diff --git a/.circleci/config.yml b/.circleci/config.yml index 2cb2e147..ce2922ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -162,7 +162,7 @@ jobs: openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks - run: name: Publish release - command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex + command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex workflows: version: 2 diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 7c537735..00000000 --- a/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -[*] -charset=utf-8 -end_of_line=lf -insert_final_newline=Advanced -indent_style=space -indent_size=4 - -[*.json] -indent_size=2 - -[*.{kt,kts}] -disabled_rules=import-ordering,no-wildcard-imports diff --git a/.gitea/FUNDING.yml b/.gitea/FUNDING.yml deleted file mode 100644 index cdce0759..00000000 --- a/.gitea/FUNDING.yml +++ /dev/null @@ -1,4 +0,0 @@ -# These are supported funding model platforms - -github: wulkanowy -custom: https://www.paypal.com/paypalme/wulkanowy diff --git a/.gitea/ISSUE_TEMPLATE/feature_request.md b/.gitea/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 6194a41e..00000000 --- a/.gitea/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Zaproponuj nowy pomysł dla Wulkanowego -title: '' -labels: '' -assignees: '' - ---- - -** Czy Twoja prośba o funkcję jest związana z problemem? Proszę opisz.** -Jasny i zwięzły opis problemu. Np. Zawsze jestem sfrustrowany, gdy [...] - -** Opisz żądane rozwiązanie ** -Jasny i zwięzły opis tego, co chcesz, aby się wydarzyło. - -** Opisz alternatywy, które rozważałeś ** -Jasny i zwięzły opis wszelkich rozważanych alternatywnych rozwiązań lub funkcji. - -** Dodatkowy kontekst ** -Dodaj inny kontekst lub zrzuty ekranu dotyczące żądania funkcji tutaj. diff --git a/.gitea/dependabot.yml b/.gitea/dependabot.yml deleted file mode 100644 index 5cb45fc8..00000000 --- a/.gitea/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: 2 -updates: -- package-ecosystem: gradle - directory: "/" - schedule: - interval: weekly - open-pull-requests-limit: 10 - target-branch: develop - ignore: - - dependency-name: io.github.wulkanowy:sdk - reviewers: - - Faierbel \ No newline at end of file diff --git a/.gitea/release.yml b/.gitea/release.yml deleted file mode 100644 index 8557fcea..00000000 --- a/.gitea/release.yml +++ /dev/null @@ -1,18 +0,0 @@ -changelog: - exclude: - labels: - - "release ignore" - categories: - - title: breaking changes - labels: - - major - - title: new features - labels: - - minor - - fr:approved - - title: translation updates - labels: - - translation - - title: features - labels: - - "*" diff --git a/.gitea/workflows/build_android.yml b/.gitea/workflows/build_android.yml deleted file mode 100644 index f9d83d38..00000000 --- a/.gitea/workflows/build_android.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Generate APK - -env: - main_project_module: app - -on: - pull_request: - types: - - closed - -jobs: - build: - - runs-on: ubuntu-latest - - env: - RUNNER_TOOL_CACHE: /toolcache - - steps: - - name: Checkout the repository - uses: actions/checkout@v3 - - - name: Set current date as env variable - run: echo "date_today=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - - - name: Set repository name as env variable - run: echo "repository_name=$(echo '${{ gitea.repository }}' | awk -F '/' '{print $2}')" >> $GITHUB_ENV - - - name: Set up JDK - uses: actions/setup-java@v3 - with: - distribution: 'zulu' # See 'Supported distributions' for available options - java-version: '17' - cache: 'gradle' - - - name: Set up Go environment - uses: actions/setup-go@v3 - with: - go-version: '1.22' - - - name: Get hash of Gradle files - uses: https://gitea.com/actions/go-hashfiles@v0.0.1 - id: get-hash - with: - patterns: |- - **/*.gradle* - - - name: Cache Gradle - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ runner.os }}-${{ steps.get-hash.outputs.hash }} - - - name: Get app version - id: get_version - run: echo "VERSION_NAME=$(grep -m1 "versionName" app/build.gradle | awk '{print $2}' | tr -d \''"\')" >> $GITHUB_ENV - - - name: Change wrapper permissions - run: chmod +x ./gradlew - - - name: Setup Android SDK - uses: android-actions/setup-android@v3 - - - name: Build debug APK - run: ./gradlew assembleDebug - - - name: Upload artifacts - uses: actions/upload-artifact@v3 # not v4 because of GHES - with: - name: wulkanowy_mod_debug_builds - path: | - app/build/outputs/**/*-debug.apk - - - name: Create release - uses: akkuman/gitea-release-action@v1 - env: - NODE_OPTIONS: '--experimental-fetch' - with: - files: | - app/build/outputs/**/*-debug.apk - - name: Release ${{ env.VERSION_NAME }} (${{ env.date_today }}) - tag_name: v${{ env.VERSION_NAME }} \ No newline at end of file diff --git a/.gitea/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE.md similarity index 61% rename from .gitea/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE.md index 237721cb..27d57f59 100644 --- a/.gitea/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,12 +1,3 @@ ---- -name: Bug report -about: Utwórz raport błędu, aby pomóc nam ulepszyć Wulkanowego -title: '' -labels: '' -assignees: '' - ---- - ## Co powinno się dziać diff --git a/.gitignore b/.gitignore index 12c6f241..5daeb6b9 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ out/ # Gradle files .gradle/ build/ -.build-cache # Local configuration file (sdk path, etc) local.properties @@ -65,12 +64,6 @@ captures/ .idea/uiDesigner.xml .idea/runConfigurations.xml .idea/discord.xml -.idea/migrations.xml -.idea/androidTestResultsUserPreferences.xml -.idea/copilot -.idea/deploymentTargetDropDown.xml -.idea/deploymentTargetSelector.xml -.idea/kotlinc.xml # Keystore files *.jks @@ -117,14 +110,9 @@ Thumbs.db *.ear ### AndroidStudio Patch ### + !/gradle/wrapper/gradle-wrapper.jar .idea/jarRepositories.xml -### Services config files -agconnect-services.json -agconnect-credentials.json -google-services.json -!app/google-services.json - -.idea/appInsightsSettings.xml +app/src/release/agconnect-services.json diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 1f93faef..cb2f4119 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -2,8 +2,34 @@ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index e0b0be97..238fefdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ cache: branches: only: - develop - - 0.24.0 + - 0.23.1 android: licenses: @@ -61,7 +61,7 @@ script: gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg; gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg; gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg; - ./gradlew publishPlayRelease --stacktrace; + ./gradlew publishPlayRelease -PenableFirebase --stacktrace; fi after_success: diff --git a/LICENSE b/LICENSE index a1fc3705..5dd9cacf 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2023 Wulkanowy + Copyright 2019 Wulkanowy Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.cs.md b/README.cs.md deleted file mode 100644 index 2d3d2a77..00000000 --- a/README.cs.md +++ /dev/null @@ -1,33 +0,0 @@ -Česká verze / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md) - -# Wulkanowy MOD - -## Funkce: -* skrýt známky -* Skrýt jednotlivé záznamy o docházce. -* Skrýt komentáře. -* falešná docházka % - -Chcete-li se dostat na skrytý panel: -1. Přejděte na kartu „Další“. -2. Přejděte na panel „Nastavení“. -3. Přejděte na panel „O aplikaci“. -4. Klikněte 5x na logo aplikace -5. Přejděte na domovskou obrazovku -6. Přejděte do nastavení -7. Zadejte „tajná nastavení“ - -# Instalace - -| Název souboru | Přizpůsobeno | -| ---------------- | ----------------- | -| `*-fdroid-*.apk` | F-Droid | -| `*-hms-*.apk` | Huawei AppGallery | -| `*-play-*.apk` | Play Store | - -Stáhněte si vybranou verzi z [releases](https://git.sador.me/sadorowo/wulkanowy-mod/releases). -Doporučujeme stáhnout nejnovější dostupnou verzi. - -# O projektu Wulkanowy - -Chcete si přečíst více o projektu Wulkanowy? [Klikněte sem](https://github.com/wulkanowy/wulkanowy) \ No newline at end of file diff --git a/README.de.md b/README.de.md deleted file mode 100644 index da16a997..00000000 --- a/README.de.md +++ /dev/null @@ -1,33 +0,0 @@ -[Česká verze](README.cs.md) / Deutsche Version / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md) - -# Wulkanowy MOD - -## Funktionen: -* Noten ausblenden -* Individuelle Anwesenheitslisten ausblenden. -* Kommentare ausblenden. -* Anwesenheit fälschen % - -So gelangen Sie zum ausgeblendeten Bereich: -1. Gehen Sie zur Registerkarte „Mehr“. -2. Gehen Sie zum Bereich „Einstellungen“. -3. Gehen Sie zum Bereich „Über die Anwendung“. -4. Klicken Sie fünfmal auf das Anwendungslogo -5. Gehen Sie zum Startbildschirm -6. Gehen Sie zu den Einstellungen -7. Geben Sie „Geheime Einstellungen“ ein - -# Installation - -| Dateiname | Angepasst an | -| ---------------- | ----------------- | -| `*-fdroid-*.apk` | F-Droid | -| `*-hms-*.apk` | Huawei AppGallery | -| `*-play-*.apk` | Play Store | - -Laden Sie die ausgewählte Version von [hier](https://git.sador.me/sadorowo/wulkanowy-mod/releases) herunter. -Wir empfehlen, die neueste verfügbare Version herunterzuladen. - -# Über das Wulkanowy-Projekt - -Möchten Sie mehr über das Wulkanowy-Projekt lesen? [Hier klicken](https://github.com/wulkanowy/wulkanowy) \ No newline at end of file diff --git a/README.en.md b/README.en.md index 9365c9b4..4c5e53da 100644 --- a/README.en.md +++ b/README.en.md @@ -1,33 +1,63 @@ -[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / English version / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md) +[Polska wersja README](README.md) -# Wulkanowy MOD +# Wulkanowy +[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy) +[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy) +[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr) +[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/) +[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases) -## Functions: -* hide grades -* hide individual attendance entries -* hide comments -* fake attendance %. +Unofficial android VULCAN UONET+ register client for both students and their parents -To get to the hidden panel: -1. Go to the "More" tab -2. Go to the "Settings" panel -3. Go to the "About application" panel -4. Click on the application logo 5 times -5. Go to the home screen -6. Go to settings -7. Enter "secret settings" - -# Installation +## Features -| File name | Adapted to | -| ---------------- | ----------------- | -| `*-fdroid-*.apk` | F-Droid | -| `*-hms-*.apk` | Huawei AppGallery | -| `*-play-*.apk` | Play Store | +* logging in using the email and password OR using token and pin +* functions from the register website: + * grades + * grade statistics + * attendance + * percentage of attendance + * exams + * timetable + * completed lessons + * messages + * homework + * notes + * lucky number +* calculation of the average independently of school's preferences +* notifications, e.g. about a new grade +* dark and black (AMOLED) theme +* offline mode +* no ads -Download application from [releases](https://git.sador.me/sadorowo/wulkanowy-mod/releases). -We recommend downloading the latest available version. +## Download -# About the Wulkanowy project +You can download the current beta version from the Google Play, F-Droid or Huawei AppGallery store -Want to read more about the Wulkanowy project? [Click here](https://github.com/wulkanowy/wulkanowy) \ No newline at end of file +[Get it on Google Play](https://play.google.com/store/apps/details?id=io.github.wulkanowy) +[Get it on F-Droid](https://f-droid.org/packages/io.github.wulkanowy/) +[Explore it on AppGallery](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=) + +You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features being prepared for the next release + +## Built With + + +* [Wulkanowy SDK](https://github.com/wulkanowy/sdk) +* [Dagger 2](https://github.com/google/dagger) +* [Room](https://developer.android.com/topic/libraries/architecture/room) +* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager) + +## Contributing + +Please contribute to the project either by creating a PR or submitting an issue on GitHub. + +## License + +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details diff --git a/README.md b/README.md index 7a265ff1..9e29cdb6 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,64 @@ -[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / Polska wersja / [Slovenská verzia](README.sk.md) +[English version of README](README.en.md) -# Wulkanowy MOD +# Wulkanowy +[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy) +[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy) +[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr) +[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/) +[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases) -## Funkcje: -* ukryj oceny -* ukryj poszczególne wpisy frekwencji -* ukryj uwagi -* sfałszuj % frekwencji +Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica -Aby dostać się do ukrytego panelu: -1. Przejdź do karty "Więcej" -2. Przejdź do panelu "Ustawienia" -3. Przejdź do panelu "O aplikacji" -4. Kliknij 5 razy w logo aplikacji -5. Przejdź na ekran główny -6. Wejdź w ustawienia -7. Wejdź w "sekretne ustawienia" - -# Instalacja +## Funkcje -| Nazwa pliku | Przystosowana do | -| ---------------- | ----------------- | -| `*-fdroid-*.apk` | F-Droid | -| `*-hms-*.apk` | Huawei AppGallery | -| `*-play-*.apk` | Sklep Play | +* logowanie za pomocą e-maila i hasła LUB tokena i pinu +* funkcje ze strony internetowej dziennika: + * oceny + * statystyki ocen + * frekwencja + * procent frekwencji + * sprawdziany + * plan lekcji + * lekcje zrealizowane + * wiadomości + * zadania domowe + * uwagi + * szczęśliwy numerek +* obliczanie średniej niezależnie od preferencji szkoły +* powiadomienia np. o nowej ocenie +* ciemny i czarny (AMOLED) motyw +* tryb offilne +* brak reklam -Pobierz wybraną wersję z [wydań](https://git.sador.me/sadorowo/wulkanowy-mod/releases). -Zalecamy pobranie najnowszej dostępnej wersji. +## Pobierz -# O projekcie Wulkanowy +Aktualną wersję beta możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery -Chcesz poczytać więcej o projekcie Wulkanowy? [Kliknij tutaj](https://github.com/wulkanowy/wulkanowy) \ No newline at end of file +[Pobierz z Google Play](https://play.google.com/store/apps/details?id=io.github.wulkanowy) +[Pobierz z F-Droid](https://f-droid.org/packages/io.github.wulkanowy/) +[Odkrywaj w AppGallery](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=) + + +Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania + + +## Zbudowana za pomocą + +* [Wulkanowy SDK](https://github.com/wulkanowy/SDK) +* [Dagger 2](https://github.com/google/dagger) +* [Room](https://developer.android.com/topic/libraries/architecture/room) +* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager) + +## Współpraca + +Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub. + +## Licencja + +Ten projekt udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE) diff --git a/README.sk.md b/README.sk.md deleted file mode 100644 index 570ac6d6..00000000 --- a/README.sk.md +++ /dev/null @@ -1,33 +0,0 @@ -[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / Slovenská verzia - -# Wulkanowy MOD - -## Funkcie: -* skryť známky -* Skryť individuálne záznamy o dochádzke. -* Skryť komentáre. -* falošná dochádzka % - -Ak chcete prejsť na skrytý panel: -1. Prejdite na kartu „Viac“. -2. Prejdite na panel „Nastavenia“. -3. Prejdite na panel „O aplikácii“. -4. Kliknite 5-krát na logo aplikácie -5. Prejdite na domovskú obrazovku -6. Prejdite do nastavení -7. Zadajte „tajné nastavenia“ - -# Inštalácia - -| Názov súboru | Prispôsobené | -| ---------------- | ----------------- | -| `*-fdroid-*.apk` | F-Droid | -| `*-hms-*.apk` | Huawei AppGallery | -| `*-play-*.apk` | Play Store | - -Stiahnite si vybranú verziu z [releases](https://git.sador.me/sadorowo/wulkanowy-mod/releases). -Odporúčame stiahnuť najnovšiu dostupnú verziu. - -# O projekte Wulkanowy - -Chcete si prečítať viac o projekte Wulkanowy? [Kliknite sem](https://github.com/wulkanowy/wulkanowy) \ No newline at end of file diff --git a/app/bitrise.jks.gpg b/app/bitrise.jks.gpg deleted file mode 100644 index 1dee91bd..00000000 Binary files a/app/bitrise.jks.gpg and /dev/null differ diff --git a/app/build.gradle b/app/build.gradle index 9e444b2a..89b5346a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,52 +1,44 @@ -import com.github.triplet.gradle.androidpublisher.ReleaseStatus -import ru.cian.huawei.publish.ReleaseNote - apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlinx-serialization' -apply plugin: 'kotlin-parcelize' -apply plugin: 'com.google.devtools.ksp' +apply plugin: 'kotlin-kapt' apply plugin: 'dagger.hilt.android.plugin' -apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.github.triplet.play' -apply plugin: 'ru.cian.huawei-publish' apply plugin: 'com.mikepenz.aboutlibraries.plugin' -apply plugin: 'com.huawei.agconnect' -apply plugin: 'kotlin-kapt' apply from: 'jacoco.gradle' apply from: 'sonarqube.gradle' apply from: 'hooks.gradle' android { - namespace 'io.github.wulkanowy' - compileSdk 34 + compileSdkVersion 30 + buildToolsVersion '30.0.2' defaultConfig { applicationId "io.github.wulkanowy" testApplicationId "io.github.tests.wulkanowy" - minSdkVersion 21 - targetSdkVersion 34 - versionCode 168 - versionName "2.6.8" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - + minSdkVersion 17 + targetSdkVersion 30 + versionCode 77 + versionName "0.23.1" + multiDexEnabled true resValue "string", "app_name", "Wulkanowy" - manifestPlaceholders = [admob_project_id: ""] - - buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null" - buildConfigField "String", "DASHBOARD_TILE_AD_ID", "null" - - if (System.env.SET_BUILD_TIMESTAMP) { - buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis()) - } else { - buildConfigField "long", "BUILD_TIMESTAMP", "1486235849000" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables.useSupportLibrary = true + manifestPlaceholders = [ + firebase_enabled: project.hasProperty("enableFirebase") + ] + javaCompileOptions { + annotationProcessorOptions { + arguments += [ + "room.schemaLocation": "$projectDir/schemas".toString(), + "room.incremental" : "true" + ] + } } } sourceSets { - // https://github.com/robolectric/robolectric/issues/3928#issuecomment-395309991 - debug.assets.srcDirs += files("$projectDir/schemas".toString()) + androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) } signingConfigs { @@ -62,86 +54,66 @@ android { release { minifyEnabled true shrinkResources true - // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - // signingConfig signingConfigs.release - buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\"" - buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"' + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release } debug { - minifyEnabled false - shrinkResources false - resValue "string", "app_name", "Wulkanowy DEV" + resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode applicationIdSuffix ".dev" versionNameSuffix "-dev" - buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\"" - buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"' + testCoverageEnabled = project.hasProperty('coverage') + ext.enableCrashlytics = project.hasProperty("enableFirebase") } } - flavorDimensions += "platform" + flavorDimensions "platform" productFlavors { hms { dimension "platform" - manifestPlaceholders = [install_channel: "AppGallery"] + minSdkVersion 19 + manifestPlaceholders = [ + install_channel: "AppGallery" + ] } play { dimension "platform" manifestPlaceholders = [ - install_channel : "Google Play", - admob_project_id: System.getenv("ADMOB_PROJECT_ID") ?: "ca-app-pub-3940256099942544~3347511713" + install_channel: "Google Play" ] - buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "\"${System.getenv("SINGLE_SUPPORT_AD_ID") ?: "ca-app-pub-3940256099942544/5354046379"}\"" - buildConfigField "String", "DASHBOARD_TILE_AD_ID", "\"${System.getenv("DASHBOARD_TILE_AD_ID") ?: "ca-app-pub-3940256099942544/6300978111"}\"" - } fdroid { dimension "platform" - manifestPlaceholders = [install_channel: "F-Droid"] + manifestPlaceholders = [ + install_channel: "F-Droid" + ] } } - playConfigs { - play { enabled.set(true) } - } - buildFeatures { - viewBinding true - buildConfig true + viewBinding = true } - bundle { - language { - enableSplit = false - } - } - - testOptions { - unitTests.includeAndroidResources = true - // workaround HMS test errors https://github.com/robolectric/robolectric/issues/2750 - unitTests.all { jvmArgs '-noverify' } + lintOptions { + disable 'HardwareIds' } compileOptions { coreLibraryDesugaringEnabled true - sourceCompatibility JavaVersion.VERSION_17 - targetCompatibility JavaVersion.VERSION_17 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = "17" - freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"] + jvmTarget = "1.8" + freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"] } packagingOptions { - resources { - excludes += ['META-INF/library_release.kotlin_module', - 'META-INF/library-core_release.kotlin_module', - 'META-INF/LICENSE.md', - 'META-INF/LICENSE-notice.md'] - } + exclude 'META-INF/library_release.kotlin_module' + exclude 'META-INF/library-core_release.kotlin_module' } aboutLibraries { @@ -149,144 +121,110 @@ android { } } -kapt { - correctErrorTypes true -} -ksp { - arg("room.schemaLocation", "$projectDir/schemas".toString()) -} - play { + serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf" + serviceAccountCredentials = file('key.p12') defaultToAppBundles = false - track = 'production' - releaseStatus = ReleaseStatus.IN_PROGRESS - userFraction = 0.99d - updatePriority = 2 - enabled.set(false) -} - -huaweiPublish { - instances { - hmsRelease { - credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json" - buildFormat = "aab" - deployType = "publish" - releaseNotes = [ - new ReleaseNote( - "pl-PL", - "$projectDir/src/main/play/release-notes/pl-PL/default.txt" - ) - ] - } - } + track = 'alpha' + updatePriority = 3 } ext { - work_manager = "2.9.0" - android_hilt = "1.2.0" - room = "2.6.1" - chucker = "4.0.0" - mockk = "1.13.10" - coroutines = "1.8.0" + work_manager = "2.4.0" + room = "2.2.5" + chucker = "3.4.0" + mockk = "1.10.3-jdk8" + moshi = "1.11.0" +} + +configurations.all { + resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3" } dependencies { - implementation 'io.github.wulkanowy:sdk:2.6.7' + implementation "io.github.wulkanowy:sdk:0.23.1" - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-guava:$coroutines" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2' - implementation 'androidx.core:core-ktx:1.13.1' - implementation 'androidx.core:core-splashscreen:1.0.1' - implementation "androidx.activity:activity-ktx:1.9.0" - implementation "androidx.appcompat:appcompat:1.6.1" - implementation "androidx.fragment:fragment-ktx:1.7.0" - implementation "androidx.annotation:annotation:1.7.1" - implementation "androidx.javascriptengine:javascriptengine:1.0.0-beta01" + implementation "androidx.core:core-ktx:1.3.2" + implementation "androidx.activity:activity-ktx:1.1.0" + implementation "androidx.appcompat:appcompat:1.2.0" + implementation "androidx.appcompat:appcompat-resources:1.2.0" + implementation "androidx.fragment:fragment-ktx:1.2.5" + implementation "androidx.annotation:annotation:1.1.0" + implementation "androidx.multidex:multidex:2.0.1" - implementation "androidx.preference:preference-ktx:1.2.1" - implementation "androidx.recyclerview:recyclerview:1.3.2" - implementation "androidx.viewpager2:viewpager2:1.1.0-rc01" + implementation "androidx.preference:preference-ktx:1.1.1" + implementation "androidx.recyclerview:recyclerview:1.1.0" + implementation "androidx.viewpager:viewpager:1.0.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - implementation "androidx.constraintlayout:constraintlayout:2.1.4" - implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" - implementation "com.google.android.material:material:1.10.0" - implementation "com.github.wulkanowy:material-chips-input:2.3.1" + implementation "androidx.constraintlayout:constraintlayout:2.0.1" + implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0" + implementation "com.google.android.material:material:1.2.1" + implementation "com.github.wulkanowy:material-chips-input:2.1.1" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" - implementation 'com.github.lopspower:CircularImageView:4.3.0' + implementation "me.zhanghai.android.materialprogressbar:library:1.6.1" - implementation "androidx.work:work-runtime:$work_manager" - playImplementation "androidx.work:work-gcm:$work_manager" + implementation "androidx.work:work-runtime-ktx:$work_manager" + implementation "androidx.work:work-gcm:$work_manager" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" implementation "androidx.room:room-runtime:$room" implementation "androidx.room:room-ktx:$room" - ksp "androidx.room:room-compiler:$room" + kapt "androidx.room:room-compiler:$room" implementation "com.google.dagger:hilt-android:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version" - kapt "androidx.hilt:hilt-compiler:$android_hilt" - implementation "androidx.hilt:hilt-work:$android_hilt" + implementation 'androidx.hilt:hilt-work:1.0.0-alpha02' + kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02' - implementation 'com.github.ncapdevi:FragNav:3.3.0' - implementation "com.github.YarikSOffice:lingver:1.3.0" + implementation "com.aurelhubert:ahbottomnavigation:2.3.4" + implementation "com.ncapdevi:frag-nav:3.3.0" + implementation "com.github.YarikSOffice:lingver:1.2.2" - implementation 'com.squareup.retrofit2:retrofit:2.11.0' - implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0" - implementation "com.squareup.okhttp3:logging-interceptor:4.12.0" - implementation "com.squareup.okhttp3:okhttp-urlconnection:4.12.0" - - implementation "com.jakewharton.timber:timber:5.0.1" - implementation 'com.github.Faierbel:slf4j-timber:2.0' - implementation 'com.github.bastienpaulfr:Treessence:1.1.2' + implementation "com.squareup.moshi:moshi:$moshi" + implementation "com.squareup.moshi:moshi-adapters:$moshi" + kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi" + implementation "com.jakewharton.timber:timber:4.7.1" + implementation "at.favre.lib:slf4j-timber:1.0.1" + implementation "fr.bipi.treessence:treessence:0.3.2" implementation "com.mikepenz:aboutlibraries-core:$about_libraries" - implementation 'io.coil-kt:coil:2.6.0' - implementation "io.github.wulkanowy:AppKillerManager:3.0.1" - implementation 'me.xdrop:fuzzywuzzy:1.4.0' - implementation 'com.fredporciuncula:flow-preferences:1.9.1' - implementation 'org.apache.commons:commons-text:1.12.0' + implementation 'com.wdullaer:materialdatetimepicker:4.2.3' + implementation "io.coil-kt:coil:1.1.0" + implementation "io.github.wulkanowy:AppKillerManager:3.0.0" + implementation 'me.xdrop:fuzzywuzzy:1.3.1' - playImplementation platform('com.google.firebase:firebase-bom:33.0.0') - playImplementation 'com.google.firebase:firebase-analytics' - playImplementation 'com.google.firebase:firebase-messaging' - playImplementation 'com.google.firebase:firebase-crashlytics:' - playImplementation 'com.google.firebase:firebase-config' + playImplementation 'com.google.firebase:firebase-analytics:18.0.0' + playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.1.2' + playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.1.2" + playImplementation 'com.google.firebase:firebase-messaging:21.0.0' + playImplementation 'com.google.firebase:firebase-crashlytics:17.3.0' + playImplementation 'com.google.android.play:core-ktx:1.8.1' + playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' - playImplementation 'com.google.android.gms:play-services-ads:22.6.0' - playImplementation "com.google.android.play:integrity:1.3.0" - playImplementation 'com.google.android.play:app-update-ktx:2.1.0' - playImplementation 'com.google.android.play:review-ktx:2.0.1' - playImplementation "com.google.android.ump:user-messaging-platform:2.1.0" + hmsImplementation 'com.huawei.hms:hianalytics:5.0.5.301' + hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.4.2.301' - hmsImplementation 'com.huawei.hms:hianalytics:6.12.0.301' - hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.9.1.303' + releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker" - releaseImplementation "com.github.chuckerteam.chucker:library-no-op:$chucker" + debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker" + debugImplementation "com.amitshekhar.android:debug-db:1.0.6" - debugImplementation "com.github.chuckerteam.chucker:library:$chucker" - debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6' - debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04' - - testImplementation "junit:junit:4.13.2" + testImplementation "junit:junit:4.13.1" testImplementation "io.mockk:mockk:$mockk" - testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines" - testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2' - testImplementation 'org.robolectric:robolectric:4.12.1' - testImplementation "androidx.test:runner:1.5.2" - testImplementation "androidx.test.ext:junit:1.1.5" - testImplementation "androidx.test:core:1.5.0" - testImplementation "androidx.room:room-testing:$room" - testImplementation "com.google.dagger:hilt-android-testing:$hilt_version" - kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version" - - androidTestImplementation "androidx.test:core:1.5.0" - androidTestImplementation "androidx.test:runner:1.5.2" - androidTestImplementation "androidx.test.ext:junit:1.1.5" + androidTestImplementation "androidx.test:core:1.3.0" + androidTestImplementation "androidx.test:runner:1.3.0" + androidTestImplementation "androidx.test.ext:junit:1.1.2" androidTestImplementation "io.mockk:mockk-android:$mockk" + androidTestImplementation "androidx.room:room-testing:$room" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" } + +apply plugin: 'com.google.gms.google-services' +apply plugin: 'com.huawei.agconnect' diff --git a/app/jacoco.gradle b/app/jacoco.gradle index 67ffdb13..a5cf84e6 100644 --- a/app/jacoco.gradle +++ b/app/jacoco.gradle @@ -1,23 +1,22 @@ apply plugin: "jacoco" jacoco { - toolVersion "0.8.11" - reportsDirectory.set(file("$buildDir/reports")) + toolVersion "0.8.5" + reportsDir = file("$buildDir/reports") } -tasks.withType(Test).configureEach { +tasks.withType(Test) { jacoco.includeNoLocationClasses = true - jacoco.excludes = ['jdk.internal.*'] } -tasks.register('jacocoTestReport', JacocoReport) { +task jacocoTestReport(type: JacocoReport) { group = "Reporting" description = "Generate Jacoco coverage reports" reports { - xml.required.set(true) - html.required.set(true) + xml.enabled = true + html.enabled = true } def excludes = ['**/R.class', @@ -33,19 +32,19 @@ tasks.register('jacocoTestReport', JacocoReport) { '**/*_Factory.*'] classDirectories.setFrom(fileTree( - dir: "$buildDir/intermediates/classes/debug", - excludes: excludes + dir: "$buildDir/intermediates/classes/debug", + excludes: excludes ) + fileTree( - dir: "$buildDir/tmp/kotlin-classes/fdroidDebug", - excludes: excludes + dir: "$buildDir/tmp/kotlin-classes/fdroidDebug", + excludes: excludes )) sourceDirectories.setFrom(files([ - "src/main/java", - "src/fdroid/java" + "src/main/java", + "src/fdroid/java" ])) executionData.setFrom(fileTree( - dir: project.projectDir, - includes: ["**/*.exec", "**/*.ec"] + dir: project.projectDir, + includes: ["**/*.exec", "**/*.ec"] )) } diff --git a/app/key.p12.gpg b/app/key.p12.gpg new file mode 100644 index 00000000..e9b6d06e Binary files /dev/null and b/app/key.p12.gpg differ diff --git a/app/play-publish-lint.sh b/app/play-publish-lint.sh index 5f0391de..d3354b1a 100755 --- a/app/play-publish-lint.sh +++ b/app/play-publish-lint.sh @@ -1,8 +1,7 @@ #!/bin/bash - content=$(cat < "app/src/main/play/release-notes/pl-PL/default.txt") || exit -content2=echo "$content" | dos2unix -if [[ "${#content2}" -gt 500 ]]; then +if [[ "${#content}" -gt 500 ]]; then echo >&2 "Release notes content has reached the limit of 500 characters" exit 1 fi diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 0fd49f6a..7c796257 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,22 +1,33 @@ -# General +# Optimizations +-optimizationpasses 5 +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontskipnonpubliclibraryclassmembers +-dontpreverify -dontobfuscate --ignorewarnings +-allowaccessmodification +-repackageclasses '' +-verbose -#Config for wulkanowy +#Keep all wulkanowy files -keep class io.github.wulkanowy.** {*;} -#Config for firebase crashlitycs +#Config for anallitycs +-keepattributes *Annotation* -keepattributes SourceFile,LineNumberTable +-keep class com.crashlytics.** {*;} -keep public class * extends java.lang.Exception +-dontwarn com.crashlytics.** -#Config for Okio and OkHttp --dontwarn javax.annotation.** +#Config for OkHttp -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase -dontwarn org.codehaus.mojo.animal_sniffer.* -dontwarn okhttp3.internal.platform.ConscryptPlatform +-dontwarn javax.annotation.** #Config for MPAndroidChart @@ -27,16 +38,8 @@ -keep class com.google.android.material.tabs.** { *; } -#Config for HMS SDK --keepattributes *Annotation* --keepattributes Exceptions --keepattributes InnerClasses --keepattributes Signature --keep class com.huawei.agconnect.**{*;} --keep class com.huawei.hianalytics.**{*;} --keep class com.huawei.updatesdk.**{*;} --keep class com.huawei.hms.**{*;} - - -#Config for Wulkanowy SDK --keep,allowobfuscation,allowshrinking class retrofit2.Response +#Config for About Libraries +-keep class .R +-keep class **.R$* { + ; +} diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/30.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/30.json deleted file mode 100644 index 309f4ac0..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/30.json +++ /dev/null @@ -1,1954 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 30, - "identityHash": "891980e378373d0a17bd341f9b07cc74", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '891980e378373d0a17bd341f9b07cc74')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/31.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/31.json deleted file mode 100644 index 4935a901..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/31.json +++ /dev/null @@ -1,2136 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 31, - "identityHash": "d642512ffa5fe81ae9308c9c55612539", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT NOT NULL, `first_guardian_kinship` TEXT NOT NULL, `first_guardian_address` TEXT NOT NULL, `first_guardian_phones` TEXT NOT NULL, `first_guardian_email` TEXT NOT NULL, `second_guardian_full_name` TEXT NOT NULL, `second_guardian_kinship` TEXT NOT NULL, `second_guardian_address` TEXT NOT NULL, `second_guardian_phones` TEXT NOT NULL, `second_guardian_email` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd642512ffa5fe81ae9308c9c55612539')" - ] - } -} diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/32.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/32.json deleted file mode 100644 index 3621be48..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/32.json +++ /dev/null @@ -1,2142 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 32, - "identityHash": "9531cdc8b3f0e62db5ab6ebe66837a28", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT NOT NULL, `first_guardian_kinship` TEXT NOT NULL, `first_guardian_address` TEXT NOT NULL, `first_guardian_phones` TEXT NOT NULL, `first_guardian_email` TEXT NOT NULL, `second_guardian_full_name` TEXT NOT NULL, `second_guardian_kinship` TEXT NOT NULL, `second_guardian_address` TEXT NOT NULL, `second_guardian_phones` TEXT NOT NULL, `second_guardian_email` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9531cdc8b3f0e62db5ab6ebe66837a28')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/33.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/33.json deleted file mode 100644 index 255c196e..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/33.json +++ /dev/null @@ -1,2142 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 33, - "identityHash": "c024cc4e19e009a03303e2bfe5c34b48", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c024cc4e19e009a03303e2bfe5c34b48')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/34.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/34.json deleted file mode 100644 index 6a56ac64..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/34.json +++ /dev/null @@ -1,2142 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 34, - "identityHash": "c024cc4e19e009a03303e2bfe5c34b48", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c024cc4e19e009a03303e2bfe5c34b48')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/35.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/35.json deleted file mode 100644 index f166b2d7..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/35.json +++ /dev/null @@ -1,2148 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 35, - "identityHash": "15fb91ec180fe60bf400cfa729c3418d", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '15fb91ec180fe60bf400cfa729c3418d')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/36.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/36.json deleted file mode 100644 index 2fae5302..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/36.json +++ /dev/null @@ -1,2160 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 36, - "identityHash": "a217c2fc4e756a014f203e7499f88a90", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a217c2fc4e756a014f203e7499f88a90')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/37.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/37.json deleted file mode 100644 index 1aaf96f6..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/37.json +++ /dev/null @@ -1,2204 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 37, - "identityHash": "98169e620b79a6633f80b5bd32162ed2", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '98169e620b79a6633f80b5bd32162ed2')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/38.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/38.json deleted file mode 100644 index 1625a9f6..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/38.json +++ /dev/null @@ -1,2248 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 38, - "identityHash": "02c6cf89e47f5ee42ee04880eb91cff2", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '02c6cf89e47f5ee42ee04880eb91cff2')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json deleted file mode 100644 index d93351ac..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/39.json +++ /dev/null @@ -1,2260 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 39, - "identityHash": "73b2b5a236cacd91df734ec4141bc590", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '73b2b5a236cacd91df734ec4141bc590')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/40.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/40.json deleted file mode 100644 index 362c7f0e..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/40.json +++ /dev/null @@ -1,2316 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 40, - "identityHash": "e2fba6244951713b4e9b217adc5d1a23", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e2fba6244951713b4e9b217adc5d1a23')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/41.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/41.json deleted file mode 100644 index 9d008060..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/41.json +++ /dev/null @@ -1,2322 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 41, - "identityHash": "d9ce44a78495a358606612bd91603c0f", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd9ce44a78495a358606612bd91603c0f')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/42.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/42.json deleted file mode 100644 index a5faa57b..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/42.json +++ /dev/null @@ -1,2396 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 42, - "identityHash": "5c8b7f9409294ecdebf9f74a44f8e883", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5c8b7f9409294ecdebf9f74a44f8e883')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/43.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/43.json deleted file mode 100644 index 22c0d812..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/43.json +++ /dev/null @@ -1,2408 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 43, - "identityHash": "66946510bb620ae82686a5a1a31aba18", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '66946510bb620ae82686a5a1a31aba18')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/44.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/44.json deleted file mode 100644 index 4dc9834d..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/44.json +++ /dev/null @@ -1,2414 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 44, - "identityHash": "e3437dc0b229a325bbeb3e964a500530", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'e3437dc0b229a325bbeb3e964a500530')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/45.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/45.json deleted file mode 100644 index 57f3d431..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/45.json +++ /dev/null @@ -1,2430 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 45, - "identityHash": "f310243440ca00cbc35e62ebaca5c7d8", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f310243440ca00cbc35e62ebaca5c7d8')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json deleted file mode 100644 index 04518141..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/46.json +++ /dev/null @@ -1,2430 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 46, - "identityHash": "f310243440ca00cbc35e62ebaca5c7d8", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f310243440ca00cbc35e62ebaca5c7d8')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/47.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/47.json deleted file mode 100644 index 3f8291ea..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/47.json +++ /dev/null @@ -1,2438 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 47, - "identityHash": "ac88c80d4bb923b22f22ce4f91521306", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ac88c80d4bb923b22f22ce4f91521306')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json deleted file mode 100644 index 1c11aae9..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json +++ /dev/null @@ -1,2445 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 48, - "identityHash": "95751b933ad9f835ffc1805f4ef71bdb", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '95751b933ad9f835ffc1805f4ef71bdb')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/49.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/49.json deleted file mode 100644 index 5472fb78..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/49.json +++ /dev/null @@ -1,2445 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 49, - "identityHash": "790d4dc0e11f38349c49af85fabf9b7b", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '790d4dc0e11f38349c49af85fabf9b7b')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/50.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/50.json deleted file mode 100644 index 4361db95..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/50.json +++ /dev/null @@ -1,2445 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 50, - "identityHash": "87455aae2b15baa976386c833afa9cd9", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `content` TEXT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "recipient", - "columnName": "recipient_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "removed", - "columnName": "removed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "oneDriveId", - "columnName": "one_drive_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "ReportingUnits", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "senderId", - "columnName": "sender_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "senderName", - "columnName": "sender_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roles", - "columnName": "roles", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "realName", - "columnName": "real_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginId", - "columnName": "login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "role", - "columnName": "role", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hash", - "columnName": "hash", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '87455aae2b15baa976386c833afa9cd9')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json deleted file mode 100644 index 271b8c90..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/51.json +++ /dev/null @@ -1,2409 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 51, - "identityHash": "51f9cb1d80df003c03bb655c0162487c", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `userLoginId` INTEGER NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "userLoginId", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "globalKey" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '51f9cb1d80df003c03bb655c0162487c')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json deleted file mode 100644 index 129d1917..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json +++ /dev/null @@ -1,2421 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 52, - "identityHash": "8742176f26afcc81279d4a073dca2949", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `userLoginId` INTEGER NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "userLoginId", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "globalKey" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8742176f26afcc81279d4a073dca2949')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json deleted file mode 100644 index 98561787..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json +++ /dev/null @@ -1,2439 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 53, - "identityHash": "1dc96a366125ec9f8567da87cdc9c863", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "globalKey" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1dc96a366125ec9f8567da87cdc9c863')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json deleted file mode 100644 index 7b41672b..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json +++ /dev/null @@ -1,2439 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 54, - "identityHash": "1dc96a366125ec9f8567da87cdc9c863", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))", - "fields": [ - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "real_id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "globalKey" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1dc96a366125ec9f8567da87cdc9c863')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/55.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/55.json deleted file mode 100644 index 60c2efbe..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/55.json +++ /dev/null @@ -1,2435 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 55, - "identityHash": "cba22eea6d26cf4d6b9a388ba3329a12", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "message_global_key", - "url", - "filename" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "globalKey" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": false - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'cba22eea6d26cf4d6b9a388ba3329a12')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/56.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/56.json deleted file mode 100644 index 1a26e717..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/56.json +++ /dev/null @@ -1,2442 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 56, - "identityHash": "48f0538bd21601eb5322a7d850e04134", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '48f0538bd21601eb5322a7d850e04134')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/57.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/57.json deleted file mode 100644 index 2eff1223..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/57.json +++ /dev/null @@ -1,2443 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 57, - "identityHash": "d15dbe7d7e4d7df98ec98d9a3a4b5fcd", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isDismissible", - "columnName": "is_dismissible", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd15dbe7d7e4d7df98ec98d9a3a4b5fcd')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/58.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/58.json deleted file mode 100644 index e6e71229..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/58.json +++ /dev/null @@ -1,2451 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 58, - "identityHash": "cd1d4f8f2b6e3860fbc1de93d4f5ca42", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'cd1d4f8f2b6e3860fbc1de93d4f5ca42')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/59.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/59.json deleted file mode 100644 index a3f2e0dc..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/59.json +++ /dev/null @@ -1,2501 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 59, - "identityHash": "3bd95e40b587e8131a2a2c23aee538c1", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3bd95e40b587e8131a2a2c23aee538c1')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/60.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/60.json deleted file mode 100644 index 20eacad1..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/60.json +++ /dev/null @@ -1,2527 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 60, - "identityHash": "3672d3f4d5e6b874e5a22d2bb458dc65", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MutedMessageSenders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`author` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3672d3f4d5e6b874e5a22d2bb458dc65')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/61.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/61.json deleted file mode 100644 index e36dcc8a..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/61.json +++ /dev/null @@ -1,2533 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 61, - "identityHash": "41fbd2ff00aba10b2ef0a079e6037c87", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `author` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MutedMessageSenders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`author` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '41fbd2ff00aba10b2ef0a079e6037c87')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json deleted file mode 100644 index ab63c679..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json +++ /dev/null @@ -1,2547 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 62, - "identityHash": "ee2464d218b254ca868667c0fc756c0b", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `is_authorized` INTEGER NOT NULL DEFAULT 0, `is_edu_one` INTEGER NOT NULL DEFAULT 0, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAuthorized", - "columnName": "is_authorized", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isEduOne", - "columnName": "is_edu_one", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `author` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MutedMessageSenders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`author` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ee2464d218b254ca868667c0fc756c0b')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/63.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/63.json deleted file mode 100644 index 9c774bb4..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/63.json +++ /dev/null @@ -1,2547 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 63, - "identityHash": "8c04a56e74b1c4f55302f28ede94cac0", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `is_authorized` INTEGER NOT NULL DEFAULT 0, `is_edu_one` INTEGER DEFAULT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAuthorized", - "columnName": "is_authorized", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isEduOne", - "columnName": "is_edu_one", - "affinity": "INTEGER", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `author` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MutedMessageSenders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`author` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8c04a56e74b1c4f55302f28ede94cac0')" - ] - } -} \ No newline at end of file diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/64.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/64.json deleted file mode 100644 index 178a5eab..00000000 --- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/64.json +++ /dev/null @@ -1,2559 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 64, - "identityHash": "dd5446e82ad8d0a65c545a5dbbaeb81c", - "entities": [ - { - "tableName": "Students", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`scrapper_base_url` TEXT NOT NULL, `scrapper_domain_suffix` TEXT NOT NULL DEFAULT '', `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `user_name` TEXT NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL, `is_authorized` INTEGER NOT NULL DEFAULT 0, `is_edu_one` INTEGER DEFAULT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "scrapperBaseUrl", - "columnName": "scrapper_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "scrapperDomainSuffix", - "columnName": "scrapper_domain_suffix", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "''" - }, - { - "fieldPath": "mobileBaseUrl", - "columnName": "mobile_base_url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginType", - "columnName": "login_type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "loginMode", - "columnName": "login_mode", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "certificateKey", - "columnName": "certificate_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "privateKey", - "columnName": "private_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isParent", - "columnName": "is_parent", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "password", - "columnName": "password", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userLoginId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "user_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "student_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolSymbol", - "columnName": "school_id", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "school_short", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolName", - "columnName": "school_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "className", - "columnName": "class_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isCurrent", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "registrationDate", - "columnName": "registration_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAuthorized", - "columnName": "is_authorized", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isEduOne", - "columnName": "is_edu_one", - "affinity": "INTEGER", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "nick", - "columnName": "nick", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "avatarColor", - "columnName": "avatar_color", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Students_email_symbol_student_id_school_id_class_id", - "unique": true, - "columnNames": [ - "email", - "symbol", - "student_id", - "school_id", - "class_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Semesters", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "kindergartenDiaryId", - "columnName": "kindergarten_diary_id", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "diaryName", - "columnName": "diary_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolYear", - "columnName": "school_year", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterName", - "columnName": "semester_name", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unitId", - "columnName": "unit_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "current", - "columnName": "is_current", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [ - { - "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id", - "unique": true, - "columnNames": [ - "student_id", - "diary_id", - "kindergarten_diary_id", - "semester_id" - ], - "orders": [], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)" - } - ], - "foreignKeys": [] - }, - { - "tableName": "Exams", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Timetable", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subjectOld", - "columnName": "subjectOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "group", - "columnName": "group", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "room", - "columnName": "room", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "roomOld", - "columnName": "roomOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherOld", - "columnName": "teacherOld", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "info", - "columnName": "info", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "isStudentPlan", - "columnName": "student_plan", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "changes", - "columnName": "changes", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "canceled", - "columnName": "canceled", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Attendance", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "timeId", - "columnName": "time_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excused", - "columnName": "excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deleted", - "columnName": "deleted", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excusable", - "columnName": "excusable", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "excuseStatus", - "columnName": "excuse_status", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AttendanceSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subjectId", - "columnName": "subject_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "month", - "columnName": "month", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "presence", - "columnName": "presence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceExcused", - "columnName": "absence_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "absenceForSchoolReasons", - "columnName": "absence_for_school_reasons", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "lateness", - "columnName": "lateness", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "latenessExcused", - "columnName": "lateness_excused", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "exemption", - "columnName": "exemption", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Grades", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "entry", - "columnName": "entry", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "value", - "columnName": "value", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "modifier", - "columnName": "modifier", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "comment", - "columnName": "comment", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "color", - "columnName": "color", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gradeSymbol", - "columnName": "grade_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weight", - "columnName": "weight", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "weightValue", - "columnName": "weightValue", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesSummary", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `points_sum_all_year` TEXT, `average` REAL NOT NULL, `average_all_year` REAL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "position", - "columnName": "position", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "predictedGrade", - "columnName": "predicted_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalGrade", - "columnName": "final_grade", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "proposedPoints", - "columnName": "proposed_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "finalPoints", - "columnName": "final_points", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSum", - "columnName": "points_sum", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pointsSumAllYear", - "columnName": "points_sum_all_year", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "average", - "columnName": "average", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "averageAllYear", - "columnName": "average_all_year", - "affinity": "REAL", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPredictedGradeNotified", - "columnName": "is_predicted_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isFinalGradeNotified", - "columnName": "is_final_grade_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "predictedGradeLastChange", - "columnName": "predicted_grade_last_change", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "finalGradeLastChange", - "columnName": "final_grade_last_change", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradePartialStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAverage", - "columnName": "class_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAverage", - "columnName": "student_average", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "classAmounts", - "columnName": "class_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentAmounts", - "columnName": "student_amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesPointsStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "others", - "columnName": "others", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "student", - "columnName": "student", - "affinity": "REAL", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradeSemesterStatistics", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "amounts", - "columnName": "amounts", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentGrade", - "columnName": "student_grade", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Messages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)", - "fields": [ - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "mailboxKey", - "columnName": "mailbox_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "messageId", - "columnName": "message_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "correspondents", - "columnName": "correspondents", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "folderId", - "columnName": "folder_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "unread", - "columnName": "unread", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "readBy", - "columnName": "read_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "unreadBy", - "columnName": "unread_by", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "hasAttachments", - "columnName": "has_attachments", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "sender", - "columnName": "sender", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "recipients", - "columnName": "recipients", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MessageAttachments", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`message_global_key`, `url`, `filename`))", - "fields": [ - { - "fieldPath": "messageGlobalKey", - "columnName": "message_global_key", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "url", - "columnName": "url", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "filename", - "columnName": "filename", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "message_global_key", - "url", - "filename" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "category", - "columnName": "category", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "categoryType", - "columnName": "category_type", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isPointsShow", - "columnName": "is_points_show", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "points", - "columnName": "points", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isRead", - "columnName": "is_read", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Homework", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "entryDate", - "columnName": "entry_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "attachments", - "columnName": "attachments", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isDone", - "columnName": "is_done", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Subjects", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "realId", - "columnName": "real_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "LuckyNumbers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "luckyNumber", - "columnName": "lucky_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "CompletedLesson", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "number", - "columnName": "number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "topic", - "columnName": "topic", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacher", - "columnName": "teacher", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "teacherSymbol", - "columnName": "teacher_symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "substitution", - "columnName": "substitution", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "absence", - "columnName": "absence", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "resources", - "columnName": "resources", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Mailboxes", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))", - "fields": [ - { - "fieldPath": "globalKey", - "columnName": "globalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "symbol", - "columnName": "symbol", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolId", - "columnName": "schoolId", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentName", - "columnName": "studentName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolNameShort", - "columnName": "schoolNameShort", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "globalKey" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Recipients", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "mailboxGlobalKey", - "columnName": "mailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "studentMailboxGlobalKey", - "columnName": "studentMailboxGlobalKey", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "fullName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "userName", - "columnName": "userName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "schoolShortName", - "columnName": "schoolShortName", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MobileDevices", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "deviceId", - "columnName": "device_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Teachers", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "shortName", - "columnName": "short_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "School", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "classId", - "columnName": "class_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "name", - "columnName": "name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "contact", - "columnName": "contact", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "headmaster", - "columnName": "headmaster", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "pedagogue", - "columnName": "pedagogue", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Conferences", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "agenda", - "columnName": "agenda", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "presentOnConference", - "columnName": "present_on_conference", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "conferenceId", - "columnName": "conference_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableAdditional", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "start", - "columnName": "start", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "end", - "columnName": "end", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "repeatId", - "columnName": "repeat_id", - "affinity": "BLOB", - "notNull": false, - "defaultValue": "NULL" - }, - { - "fieldPath": "isAddedByUser", - "columnName": "is_added_by_user", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "StudentInfo", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "fullName", - "columnName": "full_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "firstName", - "columnName": "first_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "secondName", - "columnName": "second_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "surname", - "columnName": "surname", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "birthDate", - "columnName": "birth_date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "birthPlace", - "columnName": "birth_place", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "gender", - "columnName": "gender", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "hasPolishCitizenship", - "columnName": "has_polish_citizenship", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "familyName", - "columnName": "family_name", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "parentsNames", - "columnName": "parents_names", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "address", - "columnName": "address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "registeredAddress", - "columnName": "registered_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "correspondenceAddress", - "columnName": "correspondence_address", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "phoneNumber", - "columnName": "phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "cellPhoneNumber", - "columnName": "cell_phone_number", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "email", - "columnName": "email", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "firstGuardian.fullName", - "columnName": "first_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.kinship", - "columnName": "first_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.address", - "columnName": "first_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.phones", - "columnName": "first_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "firstGuardian.email", - "columnName": "first_guardian_email", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.fullName", - "columnName": "second_guardian_full_name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.kinship", - "columnName": "second_guardian_kinship", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.address", - "columnName": "second_guardian_address", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.phones", - "columnName": "second_guardian_phones", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "secondGuardian.email", - "columnName": "second_guardian_email", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "TimetableHeaders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "diaryId", - "columnName": "diary_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "SchoolAnnouncements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `author` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "user_login_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "Notifications", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "type", - "columnName": "type", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "destination", - "columnName": "destination", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'" - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "data", - "columnName": "data", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "AdminMessages", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `types` TEXT NOT NULL DEFAULT '[]', `is_ok_visible` INTEGER NOT NULL DEFAULT 0, `is_x_visible` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", - "fields": [ - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "title", - "columnName": "title", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "content", - "columnName": "content", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "versionMin", - "columnName": "version_name", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "versionMax", - "columnName": "version_max", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "targetRegisterHost", - "columnName": "target_register_host", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "targetFlavor", - "columnName": "target_flavor", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "destinationUrl", - "columnName": "destination_url", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "priority", - "columnName": "priority", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "types", - "columnName": "types", - "affinity": "TEXT", - "notNull": true, - "defaultValue": "'[]'" - }, - { - "fieldPath": "isOkVisible", - "columnName": "is_ok_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - }, - { - "fieldPath": "isXVisible", - "columnName": "is_x_visible", - "affinity": "INTEGER", - "notNull": true, - "defaultValue": "0" - } - ], - "primaryKey": { - "autoGenerate": false, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "MutedMessageSenders", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`author` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", - "fields": [ - { - "fieldPath": "author", - "columnName": "author", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "GradesDescriptive", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `description` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "semesterId", - "columnName": "semester_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "studentId", - "columnName": "student_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "subject", - "columnName": "subject", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "description", - "columnName": "description", - "affinity": "TEXT", - "notNull": true - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isNotified", - "columnName": "is_notified", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "autoGenerate": true, - "columnNames": [ - "id" - ] - }, - "indices": [], - "foreignKeys": [] - } - ], - "views": [], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'dd5446e82ad8d0a65c545a5dbbaeb81c')" - ] - } -} \ No newline at end of file diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/TestDispatchersProvider.kt b/app/src/androidTest/java/io/github/wulkanowy/data/TestDispatchersProvider.kt new file mode 100644 index 00000000..8c4354d9 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/TestDispatchersProvider.kt @@ -0,0 +1,11 @@ +package io.github.wulkanowy.data + +import io.github.wulkanowy.utils.DispatchersProvider +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +class TestDispatchersProvider : DispatchersProvider() { + + override val backgroundThread: CoroutineDispatcher + get() = Dispatchers.Unconfined +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt new file mode 100644 index 00000000..611161e5 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.data.db.migrations + +import androidx.preference.PreferenceManager +import androidx.room.Room +import androidx.room.testing.MigrationTestHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.SharedPrefProvider +import org.junit.Rule + +abstract class AbstractMigrationTest { + + val dbName = "migration-test" + + @get:Rule + val helper: MigrationTestHelper = MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + AppDatabase::class.java.canonicalName, + FrameworkSQLiteOpenHelperFactory() + ) + + fun getMigratedRoomDatabase(): AppDatabase { + val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, dbName) + .addMigrations(*AppDatabase.getMigrations(SharedPrefProvider(PreferenceManager + .getDefaultSharedPreferences(ApplicationProvider.getApplicationContext()))) + ) + .build() + // close the database and release any stream resources when the test finishes + helper.closeWhenFinished(database) + return database + } +} diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt similarity index 80% rename from app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt index 54c73e20..b312048d 100644 --- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt @@ -2,38 +2,32 @@ package io.github.wulkanowy.data.db.migrations import android.content.ContentValues import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL -import android.os.Build import androidx.sqlite.db.SupportSQLiteDatabase -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication +import androidx.test.ext.junit.runners.AndroidJUnit4 import kotlinx.coroutines.runBlocking import org.junit.Test import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import kotlin.test.assertEquals -@HiltAndroidTest -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class) +@RunWith(AndroidJUnit4::class) class Migration12Test : AbstractMigrationTest() { @Test fun twoNotRelatedStudents() { helper.createDatabase(dbName, 11).apply { // user 1 - createStudent(this, 1) + createStudent(this, 1, true) createSemester(this, 1, false, 5, 1) createSemester(this, 1, true, 5, 2) // user 2 - createStudent(this, 2) + createStudent(this, 2, true) createSemester(this, 2, false, 6, 1) createSemester(this, 2, true, 6, 2) close() } - runMigrationsAndValidate(Migration12()) + helper.runMigrationsAndValidate(dbName, 12, true, Migration12()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -49,21 +43,20 @@ class Migration12Test : AbstractMigrationTest() { assertEquals(2, studentId) assertEquals(6, classId) } - db.close() } @Test fun removeStudentsWithoutClassId() { helper.createDatabase(dbName, 11).apply { // user 1 - createStudent(this, 1) + createStudent(this, 1, true) createSemester(this, 1, false, 0, 2) - createStudent(this, 2) + createStudent(this, 2, true) createSemester(this, 2, true, 1, 2) close() } - runMigrationsAndValidate(Migration12()) + helper.runMigrationsAndValidate(dbName, 12, true, Migration12()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -74,23 +67,22 @@ class Migration12Test : AbstractMigrationTest() { assertEquals(2, studentId) assertEquals(1, classId) } - db.close() } @Test fun ensureThereIsOnlyOneCurrentStudent() { helper.createDatabase(dbName, 11).apply { // user 1 - createStudent(this, 1) + createStudent(this, 1, true) createSemester(this, 1, true, 5, 2) - createStudent(this, 2) + createStudent(this, 2, true) createSemester(this, 2, true, 6, 2) - createStudent(this, 3) + createStudent(this, 3, true) createSemester(this, 3, false, 7, 2) close() } - runMigrationsAndValidate(Migration12()) + helper.runMigrationsAndValidate(dbName, 12, true, Migration12()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -109,10 +101,9 @@ class Migration12Test : AbstractMigrationTest() { assertEquals(studentId, 3) assertEquals(true, isCurrent) } - db.close() } - private fun createStudent(db: SupportSQLiteDatabase, studentId: Int) { + private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, isCurrent: Boolean) { db.insert("Students", CONFLICT_FAIL, ContentValues().apply { put("endpoint", "https://fakelog.cf") put("loginType", "STANDARD") @@ -123,7 +114,7 @@ class Migration12Test : AbstractMigrationTest() { put("student_name", "Jan Kowalski") put("school_id", "000123") put("school_name", "") - put("is_current", true) + put("is_current", isCurrent) put("registration_date", "0") }) } diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt similarity index 74% rename from app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt index 9ba36876..15e99f5f 100644 --- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt @@ -2,26 +2,17 @@ package io.github.wulkanowy.data.db.migrations import android.content.ContentValues import android.database.sqlite.SQLiteDatabase -import android.os.Build import androidx.sqlite.db.SupportSQLiteDatabase -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication import io.github.wulkanowy.data.db.Converters import io.github.wulkanowy.data.db.entities.Semester import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import java.time.LocalDate.of import kotlin.test.assertFalse import kotlin.test.assertTrue -@HiltAndroidTest -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class) class Migration13Test : AbstractMigrationTest() { @Test @@ -57,8 +48,6 @@ class Migration13Test : AbstractMigrationTest() { assertEquals("C", className) assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName) } - - db.close() } @Test @@ -87,30 +76,28 @@ class Migration13Test : AbstractMigrationTest() { assertEquals("", className) assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName) } - - db.close() } @Test fun markAtLeastAndOnlyOneSemesterAtCurrent() { helper.createDatabase(dbName, 12).apply { createStudent(this, 1, "", 5) - createSemester(this, 1, 1, 1, false) - createSemester(this, 1, 2, 1, false) - createSemester(this, 1, 3, 2, false) - createSemester(this, 1, 4, 2, false) + createSemester(this, 1, 5, 1, 1, false) + createSemester(this, 1, 5, 2, 1, false) + createSemester(this, 1, 5, 3, 2, false) + createSemester(this, 1, 5, 4, 2, false) createStudent(this, 2, "", 5) - createSemester(this, 2, 5, 5, true) - createSemester(this, 2, 6, 5, true) - createSemester(this, 2, 7, 55, true) - createSemester(this, 2, 8, 55, true) + createSemester(this, 2, 5, 5, 5, true) + createSemester(this, 2, 5, 6, 5, true) + createSemester(this, 2, 5, 7, 55, true) + createSemester(this, 2, 5, 8, 55, true) createStudent(this, 3, "", 5) - createSemester(this, 3, 11, 99, false) - createSemester(this, 3, 12, 99, false) - createSemester(this, 3, 13, 100, false) - createSemester(this, 3, 14, 100, true) + createSemester(this, 3, 5, 11, 99, false) + createSemester(this, 3, 5, 12, 99, false) + createSemester(this, 3, 5, 13, 100, false) + createSemester(this, 3, 5, 14, 100, true) close() } @@ -152,32 +139,28 @@ class Migration13Test : AbstractMigrationTest() { assertFalse(semesters[2].second) assertTrue(semesters[3].second) } - db.close() } private fun getSemesters(db: SupportSQLiteDatabase, query: String): List> { val semesters = mutableListOf>() - db.query(query).use { - if (it.moveToFirst()) { - do { - semesters.add(Semester( - studentId = it.getInt(1), - diaryId = it.getInt(2), - kindergartenDiaryId = 0, - diaryName = it.getString(3), - semesterId = it.getInt(4), - semesterName = it.getInt(5), - classId = it.getInt(7), - unitId = it.getInt(8), - schoolYear = it.getInt(9), - start = Converters().timestampToLocalDate(it.getLong(10))!!, - end = Converters().timestampToLocalDate(it.getLong(11))!! - ) to (it.getInt(6) == 1)) - } while (it.moveToNext()) - } + val cursor = db.query(query) + if (cursor.moveToFirst()) { + do { + semesters.add(Semester( + studentId = cursor.getInt(1), + diaryId = cursor.getInt(2), + diaryName = cursor.getString(3), + semesterId = cursor.getInt(4), + semesterName = cursor.getInt(5), + classId = cursor.getInt(7), + unitId = cursor.getInt(8), + schoolYear = cursor.getInt(9), + start = Converters().timestampToDate(cursor.getLong(10))!!, + end = Converters().timestampToDate(cursor.getLong(11))!! + ) to (cursor.getInt(6) == 1)) + } while (cursor.moveToNext()) } - return semesters.toList() } @@ -198,13 +181,7 @@ class Migration13Test : AbstractMigrationTest() { }) } - private fun createSemester( - db: SupportSQLiteDatabase, - studentId: Int, - semesterId: Int, - diaryId: Int, - isCurrent: Boolean = false - ) { + private fun createSemester(db: SupportSQLiteDatabase, studentId: Int, classId: Int, semesterId: Int, diaryId: Int, isCurrent: Boolean = false) { db.insert("Semesters", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { put("student_id", studentId) put("diary_id", diaryId) @@ -212,7 +189,7 @@ class Migration13Test : AbstractMigrationTest() { put("semester_id", semesterId) put("semester_name", "1") put("is_current", isCurrent) - put("class_id", 5) + put("class_id", classId) put("unit_id", "99") }) } diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt similarity index 86% rename from app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt rename to app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt index 19eda9ba..75955258 100644 --- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt @@ -2,21 +2,12 @@ package io.github.wulkanowy.data.db.migrations import android.content.ContentValues import android.database.sqlite.SQLiteDatabase -import android.os.Build import androidx.sqlite.db.SupportSQLiteDatabase -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config import kotlin.random.Random -@HiltAndroidTest -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class) class Migration27Test : AbstractMigrationTest() { @Test @@ -27,7 +18,7 @@ class Migration27Test : AbstractMigrationTest() { close() } - runMigrationsAndValidate(Migration27()) + helper.runMigrationsAndValidate(dbName, 27, true, Migration27()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -39,8 +30,6 @@ class Migration27Test : AbstractMigrationTest() { assertEquals(123, userLoginId) assertEquals("Student Jan", userName) } - - db.close() } @Test @@ -51,7 +40,7 @@ class Migration27Test : AbstractMigrationTest() { close() } - runMigrationsAndValidate(Migration27()) + helper.runMigrationsAndValidate(dbName, 27, true, Migration27()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -63,8 +52,6 @@ class Migration27Test : AbstractMigrationTest() { assertEquals(2, userLoginId) assertEquals("Unit Jan", userName) } - - db.close() } @Test @@ -77,7 +64,7 @@ class Migration27Test : AbstractMigrationTest() { close() } - runMigrationsAndValidate(Migration27()) + helper.runMigrationsAndValidate(dbName, 27, true, Migration27()) val db = getMigratedRoomDatabase() val students = runBlocking { db.studentDao.loadAll() } @@ -94,8 +81,6 @@ class Migration27Test : AbstractMigrationTest() { assertEquals(333, userLoginId) assertEquals("Unit Tomasz", userName) } - - db.close() } private fun createStudent(db: SupportSQLiteDatabase, id: Long, userLoginId: Int, studentName: String) { diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestEntityCreator.kt new file mode 100644 index 00000000..04d13be4 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestEntityCreator.kt @@ -0,0 +1,45 @@ +package io.github.wulkanowy.data.repositories + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import java.time.LocalDate.now +import java.time.LocalDateTime + +fun getStudent(): Student { + return Student( + email = "test", + password = "test123", + schoolSymbol = "23", + scrapperBaseUrl = "fakelog.cf", + loginType = "AUTO", + isCurrent = true, + userName = "", + studentName = "", + schoolShortName = "", + schoolName = "", + studentId = 0, + classId = 1, + symbol = "", + registrationDate = LocalDateTime.now(), + className = "", + loginMode = "API", + certificateKey = "", + privateKey = "", + mobileBaseUrl = "", + userLoginId = 0, + isParent = false + ) +} + +fun getSemester() = Semester( + semesterId = 1, + studentId = 1, + classId = 1, + diaryId = 2, + diaryName = "", + end = now(), + schoolYear = 2019, + semesterName = 1, + start = now(), + unitId = 1 +) diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt new file mode 100644 index 00000000..fa128986 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt @@ -0,0 +1,83 @@ +package io.github.wulkanowy.data.repositories.attendance + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Attendance +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDate.now +import java.time.LocalDate.of +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class AttendanceLocalTest { + + private lateinit var attendanceLocal: AttendanceLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() + attendanceLocal = AttendanceLocal(testDb.attendanceDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + getAttendanceEntity( + of(2018, 9, 10), + SentExcuseStatus.ACCEPTED + ), + getAttendanceEntity( + of(2018, 9, 14), + SentExcuseStatus.WAITING + ), + getAttendanceEntity( + of(2018, 9, 17), + SentExcuseStatus.ACCEPTED + ) + ) + runBlocking { attendanceLocal.saveAttendance(list) } + + val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1) + val attendance = runBlocking { attendanceLocal.getAttendance(semester, of(2018, 9, 10), of(2018, 9, 14)).first() } + assertEquals(2, attendance.size) + assertEquals(attendance[0].date, of(2018, 9, 10)) + assertEquals(attendance[1].date, of(2018, 9, 14)) + } + + private fun getAttendanceEntity( + date: LocalDate, + excuseStatus: SentExcuseStatus + ) = Attendance( + studentId = 1, + diaryId = 2, + timeId = 3, + date = date, + number = 0, + subject = "", + name = "", + presence = false, + absence = false, + exemption = false, + lateness = false, + excused = false, + deleted = false, + excusable = false, + excuseStatus = excuseStatus.name + ) +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt new file mode 100644 index 00000000..ca7d0b1b --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt @@ -0,0 +1,59 @@ +package io.github.wulkanowy.data.repositories.completedlessons + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.CompletedLesson +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDate.now +import java.time.LocalDate.of +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class CompletedLessonsLocalTest { + + private lateinit var completedLessonsLocal: CompletedLessonsLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room + .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + completedLessonsLocal = CompletedLessonsLocal(testDb.completedLessonsDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + getCompletedLesson(of(2018, 9, 10), 1), + getCompletedLesson(of(2018, 9, 14), 2), + getCompletedLesson(of(2018, 9, 17), 3) + ) + runBlocking { completedLessonsLocal.saveCompletedLessons(list) } + + val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1) + val completed = runBlocking { completedLessonsLocal.getCompletedLessons(semester, of(2018, 9, 10), of(2018, 9, 14)).first() } + assertEquals(2, completed.size) + assertEquals(completed[0].date, of(2018, 9, 10)) + assertEquals(completed[1].date, of(2018, 9, 14)) + } + + private fun getCompletedLesson(date: LocalDate, number: Int): CompletedLesson { + return CompletedLesson(1, 2, date, number, "", "", "", "", "", "", "") + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt new file mode 100644 index 00000000..14b29c9f --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt @@ -0,0 +1,52 @@ +package io.github.wulkanowy.data.repositories.exam + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Exam +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate.now +import java.time.LocalDate.of +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class ExamLocalTest { + + private lateinit var examLocal: ExamLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java).build() + examLocal = ExamLocal(testDb.examsDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""), + Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""), + Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "") + ) + runBlocking { examLocal.saveExams(list) } + + val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1) + val exams = runBlocking { examLocal.getExams(semester, of(2018, 9, 10), of(2018, 9, 14)).first() } + assertEquals(2, exams.size) + assertEquals(exams[0].date, of(2018, 9, 10)) + assertEquals(exams[1].date, of(2018, 9, 14)) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt new file mode 100644 index 00000000..946ebf8e --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt @@ -0,0 +1,55 @@ +package io.github.wulkanowy.data.repositories.grade + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDate.now +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class GradeLocalTest { + + private lateinit var gradeLocal: GradeLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room + .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1), + createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2), + createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2) + ) + runBlocking { gradeLocal.saveGrades(list) } + + val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1) + + val grades = runBlocking { gradeLocal.getGradesDetails(semester).first() } + + assertEquals(2, grades.size) + assertEquals(grades[0].date, LocalDate.of(2019, 2, 27)) + assertEquals(grades[1].date, LocalDate.of(2019, 2, 28)) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt new file mode 100644 index 00000000..5cf9c219 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt @@ -0,0 +1,221 @@ +package io.github.wulkanowy.data.repositories.grade + +import android.os.Build.VERSION_CODES.P +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider.getApplicationContext +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.every +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate.of +import java.time.LocalDateTime +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +@SdkSuppress(minSdkVersion = P) +@RunWith(AndroidJUnit4::class) +class GradeRepositoryTest { + + @MockK + private lateinit var semesterMock: Semester + + private lateinit var studentMock: Student + + @MockK + private lateinit var gradeRemote: GradeRemote + + private lateinit var gradeLocal: GradeLocal + + private lateinit var testDb: AppDatabase + + @Before + fun initApi() { + MockKAnnotations.init(this) + testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build() + gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao) + studentMock = getStudentMock() + + every { semesterMock.studentId } returns 1 + every { semesterMock.diaryId } returns 1 + every { semesterMock.schoolYear } returns 2019 + every { semesterMock.semesterId } returns 1 + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun markOlderThanRegisterDateAsRead() { + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf( + createGradeLocal(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"), + createGradeLocal(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"), + createGradeLocal(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"), + createGradeLocal(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza") + ) to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!!.first.sortedByDescending { it.date } + } + + assertFalse { grades[0].isRead } + assertFalse { grades[1].isRead } + assertTrue { grades[2].isRead } + assertTrue { grades[3].isRead } + } + + @Test + fun mitigateOldGradesNotifications() { + val list = listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"), + createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"), + createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia") + ) + runBlocking { gradeLocal.saveGrades(list) } + + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf( + createGradeLocal(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"), + createGradeLocal(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"), + createGradeLocal(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"), + createGradeLocal(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa") + ) to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!!.first.sortedByDescending { it.date } + } + + assertFalse { grades[0].isRead } + assertFalse { grades[1].isRead } + assertTrue { grades[2].isRead } + assertTrue { grades[3].isRead } + } + + @Test + fun subtractLocaleDuplicateGrades() { + val list = listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) + runBlocking { gradeLocal.saveGrades(list) } + + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!! + } + + assertEquals(2, grades.first.size) + } + + @Test + fun subtractRemoteDuplicateGrades() { + val list = listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) + runBlocking { gradeLocal.saveGrades(list) } + + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!! + } + + assertEquals(3, grades.first.size) + } + + @Test + fun emptyLocal() { + runBlocking { gradeLocal.saveGrades(listOf()) } + + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!! + } + + assertEquals(3, grades.first.size) + } + + @Test + fun emptyRemote() { + val list = listOf( + createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), + createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") + ) + runBlocking { gradeLocal.saveGrades(list) } + + coEvery { gradeRemote.getGrades(studentMock, semesterMock) } returns (emptyList() to emptyList()) + + val grades = runBlocking { + GradeRepository(gradeLocal, gradeRemote) + .getGrades(studentMock, semesterMock, true) + .filter { it.status == Status.SUCCESS }.first().data!! + } + + assertEquals(0, grades.first.size) + } + + private fun getStudentMock() = Student( + scrapperBaseUrl = "http://fakelog.cf", + email = "jan@fakelog.cf", + certificateKey = "", + classId = 0, + className = "", + isCurrent = false, + isParent = false, + loginMode = Sdk.Mode.SCRAPPER.name, + loginType = "STANDARD", + mobileBaseUrl = "", + password = "", + privateKey = "", + registrationDate = LocalDateTime.of(2019, 2, 27, 12, 0), + schoolName = "", + schoolShortName = "test", + schoolSymbol = "", + studentId = 0, + studentName = "", + symbol = "", + userLoginId = 0, + userName = "" + ) +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/TestGradeEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/TestGradeEntityCreator.kt new file mode 100644 index 00000000..629c2432 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/TestGradeEntityCreator.kt @@ -0,0 +1,41 @@ +package io.github.wulkanowy.data.repositories.grade + +import java.time.LocalDate +import io.github.wulkanowy.sdk.pojo.Grade as GradeRemote +import io.github.wulkanowy.data.db.entities.Grade as GradeLocal + +fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal { + return GradeLocal( + semesterId = semesterId, + studentId = 1, + modifier = .0, + teacher = "", + subject = "", + date = date, + color = "", + comment = "", + description = desc, + entry = "", + gradeSymbol = "", + value = value.toDouble(), + weight = "", + weightValue = weight + ) +} + +fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote { + return GradeRemote( + subject = "", + color = "", + comment = "", + date = date, + description = desc, + entry = "", + modifier = .0, + symbol = "", + teacher = "", + value = value.toDouble(), + weight = weight.toString(), + weightValue = weight + ) +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt new file mode 100644 index 00000000..db083432 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt @@ -0,0 +1,110 @@ +package io.github.wulkanowy.data.repositories.gradestatistics + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.GradePartialStatistics +import io.github.wulkanowy.data.db.entities.GradePointsStatistics +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate.now +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class GradeStatisticsLocalTest { + + private lateinit var gradeStatisticsLocal: GradeStatisticsLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradePartialStatisticsDao, testDb.gradePointsStatisticsDao, testDb.gradeSemesterStatisticsDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndRead_subject() { + val list = listOf( + getGradeStatistics("Matematyka", 2, 1), + getGradeStatistics("Fizyka", 1, 2) + ) + runBlocking { gradeStatisticsLocal.saveGradePartialStatistics(list) } + + val stats = runBlocking { gradeStatisticsLocal.getGradePartialStatistics(getSemester()).first() } + assertEquals(1, stats.size) + assertEquals(stats[0].subject, "Matematyka") + } + + @Test + fun saveAndRead_all() { + val list = listOf( + getGradeStatistics("Matematyka", 2, 1), + getGradeStatistics("Chemia", 2, 1), + getGradeStatistics("Fizyka", 1, 2) + ) + runBlocking { gradeStatisticsLocal.saveGradePartialStatistics(list) } + + val stats = runBlocking { gradeStatisticsLocal.getGradePartialStatistics(getSemester()).first() } + assertEquals(2, stats.size) + assertEquals(stats[0].subject, "Matematyka") + assertEquals(stats[1].subject, "Chemia") + } + + @Test + fun saveAndRead_points() { + val list = listOf( + getGradePointsStatistics("Matematyka", 2, 1), + getGradePointsStatistics("Chemia", 2, 1), + getGradePointsStatistics("Fizyka", 1, 2) + ) + runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(list) } + + val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() } + with(stats[0]) { + assertEquals(subject, "Matematyka") + assertEquals(others, 5.0) + assertEquals(student, 5.0) + } + } + + @Test + fun saveAndRead_subjectEmpty() { + runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(listOf()) } + + val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() } + assertEquals(emptyList(), stats) + } + + @Test + fun saveAndRead_allEmpty() { + runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(listOf()) } + + val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() } + assertEquals(emptyList(), stats) + } + + private fun getSemester(): Semester { + return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1) + } + + private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradePartialStatistics { + return GradePartialStatistics(studentId, semesterId, subject, "", "", listOf(5), listOf(5)) + } + + private fun getGradePointsStatistics(subject: String, studentId: Int, semesterId: Int): GradePointsStatistics { + return GradePointsStatistics(studentId, semesterId, subject, 5.0, 5.0) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt new file mode 100644 index 00000000..ca38b1fe --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt @@ -0,0 +1,51 @@ +package io.github.wulkanowy.data.repositories.luckynumber + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDateTime.now +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class LuckyNumberLocalTest { + + private lateinit var luckyNumberLocal: LuckyNumberLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room + .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + luckyNumberLocal = LuckyNumberLocal(testDb.luckyNumberDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val number = LuckyNumber(1, LocalDate.of(2019, 1, 20), 14) + runBlocking { luckyNumberLocal.saveLuckyNumber(number) } + + val student = Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", "", 1, false, now()) + val luckyNumber = runBlocking { luckyNumberLocal.getLuckyNumber(student, LocalDate.of(2019, 1, 20)).first() } + + assertEquals(1, luckyNumber?.studentId) + assertEquals(LocalDate.of(2019, 1, 20), luckyNumber?.date) + assertEquals(14, luckyNumber?.luckyNumber) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt new file mode 100644 index 00000000..6bd1959b --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt @@ -0,0 +1,65 @@ +package io.github.wulkanowy.data.repositories.recipient + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDateTime +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class RecipientLocalTest { + + private lateinit var recipientLocal: RecipientLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + recipientLocal = RecipientLocal(testDb.recipientDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + Recipient(1, "2rPracownik", "Kowalski Jan", "Kowalski Jan [KJ] - Pracownik (Fake123456)", 3, 4, 2, "hash"), + Recipient(1, "3rPracownik", "Kowalska Karolina", "Kowalska Karolina [KK] - Pracownik (Fake123456)", 4, 4, 2, "hash"), + Recipient(1, "4rPracownik", "Krupa Stanisław", "Krupa Stanisław [KS] - Uczeń (Fake123456)", 5, 4, 1, "hash") + ) + runBlocking { recipientLocal.saveRecipients(list) } + + val student = Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", "", "", 1, true, LocalDateTime.now()) + val recipients = runBlocking { + recipientLocal.getRecipients( + student = student, + role = 2, + unit = ReportingUnit(1, 4, "", 0, "", emptyList()) + ) + } + + assertEquals(2, recipients.size) + assertEquals(1, recipients[0].studentId) + assertEquals("3rPracownik", recipients[1].realId) + assertEquals("Kowalski Jan", recipients[0].name) + assertEquals("Kowalska Karolina [KK] - Pracownik (Fake123456)", recipients[1].realName) + assertEquals(3, recipients[0].loginId) + assertEquals(4, recipients[1].unitId) + assertEquals(2, recipients[0].role) + assertEquals("hash", recipients[1].hash) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt new file mode 100644 index 00000000..d68f15a8 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt @@ -0,0 +1,46 @@ +package io.github.wulkanowy.data.repositories.student + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.TestDispatchersProvider +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.repositories.getStudent +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class StudentLocalTest { + + private lateinit var studentLocal: StudentLocal + + private lateinit var testDb: AppDatabase + + private val student = getStudent() + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java) + .build() + studentLocal = StudentLocal(testDb.studentDao, TestDispatchersProvider(), context) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + runBlocking { studentLocal.saveStudents(listOf(student)) } + + val student = runBlocking { studentLocal.getCurrentStudent(true) } + assertEquals("23", student?.schoolSymbol) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt new file mode 100644 index 00000000..dddf6464 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TestTimetableEntityCreator.kt @@ -0,0 +1,48 @@ +package io.github.wulkanowy.data.repositories.timetable + +import java.time.LocalDateTime +import java.time.LocalDateTime.now +import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal +import io.github.wulkanowy.sdk.pojo.Timetable as TimetableRemote + +fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal { + return TimetableLocal( + studentId = 1, + diaryId = 2, + number = number, + start = start, + end = now(), + date = start.toLocalDate(), + subject = subject, + subjectOld = "", + group = "", + room = room, + roomOld = "", + teacher = teacher, + teacherOld = "", + info = "", + isStudentPlan = true, + changes = changes, + canceled = false + ) +} + +fun createTimetableRemote(start: LocalDateTime, number: Int = 1, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote { + return TimetableRemote( + number = number, + start = start, + end = start.plusMinutes(45), + date = start.toLocalDate(), + subject = subject, + group = "", + room = room, + teacher = teacher, + info = "", + changes = changes, + canceled = false, + roomOld = "", + subjectOld = "", + teacherOld = "", + studentPlan = true + ) +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt new file mode 100644 index 00000000..e793212e --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt @@ -0,0 +1,59 @@ +package io.github.wulkanowy.data.repositories.timetable + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDateTime.of +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +class TimetableLocalTest { + + private lateinit var timetableDb: TimetableLocal + + private lateinit var testDb: AppDatabase + + @Before + fun createDb() { + testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java) + .build() + timetableDb = TimetableLocal(testDb.timetableDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun saveAndReadTest() { + val list = listOf( + createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1), + createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1), + createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1) + ) + runBlocking { timetableDb.saveTimetable(list) } + + val semester = Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1) + val exams = runBlocking { + timetableDb.getTimetable( + semester = semester, + startDate = LocalDate.of(2018, 9, 10), + endDate = LocalDate.of(2018, 9, 14) + ).first() + } + + assertEquals(2, exams.size) + assertEquals(exams[0].date, LocalDate.of(2018, 9, 10)) + assertEquals(exams[1].date, LocalDate.of(2018, 9, 14)) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt new file mode 100644 index 00000000..1bd3c467 --- /dev/null +++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt @@ -0,0 +1,155 @@ +package io.github.wulkanowy.data.repositories.timetable + +import android.os.Build.VERSION_CODES.P +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider.getApplicationContext +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SdkSuppress +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.repositories.getSemester +import io.github.wulkanowy.data.repositories.getStudent +import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.time.LocalDate +import java.time.LocalDateTime.of +import kotlin.test.assertEquals + +@SdkSuppress(minSdkVersion = P) +@RunWith(AndroidJUnit4::class) +class TimetableRepositoryTest { + + @MockK(relaxed = true) + private lateinit var timetableNotificationSchedulerHelper: TimetableNotificationSchedulerHelper + + @MockK + private lateinit var timetableRemote: TimetableRemote + + private lateinit var timetableLocal: TimetableLocal + + private lateinit var testDb: AppDatabase + + private val student = getStudent() + + private val semester = getSemester() + + @Before + fun initApi() { + MockKAnnotations.init(this) + testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build() + timetableLocal = TimetableLocal(testDb.timetableDao) + } + + @After + fun closeDb() { + testDb.close() + } + + @Test + fun copyRoomToCompletedFromPrevious() { + runBlocking { + timetableLocal.saveTimetable(listOf( + createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"), + createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"), + createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"), + createTimetableLocal(of(2019, 3, 5, 10, 30), 3, "213", "W-F", "Jan Kowalski") + )) + } + + coEvery { timetableRemote.getTimetable(student, semester, any(), any()) } returns listOf( + createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"), + createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "", "Religia"), + createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "", "W-F"), + createTimetableLocal(of(2019, 3, 5, 10, 30), 4, "", "W-F") + ) + + val lessons = runBlocking { + TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable( + student = student, + semester = semester, + start = LocalDate.of(2019, 3, 5), + end = LocalDate.of(2019, 3, 5), + forceRefresh = true + ).filter { it.status == Status.SUCCESS }.first().data.orEmpty() + } + + assertEquals(4, lessons.size) + assertEquals("123", lessons[0].room) + assertEquals("321", lessons[1].room) + assertEquals("213", lessons[2].room) + } + + @Test + fun copyTeacherToCompletedFromPrevious() { + val list = listOf( + createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false), + createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false), + createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true), + createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true), + + createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "Joanna Wtorkowska", false), + createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "Joanna Wtorkowska", false), + createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "Joanna Środowska", true), + createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "Joanna Środowska", true), + + createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "", false), + createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false), + createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true), + createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true) + ) + runBlocking { timetableLocal.saveTimetable(list) } + + coEvery { timetableRemote.getTimetable(student, semester, any(), any()) } returns listOf( + createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false), + createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true), + createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false), + createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true), + + createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "", false), + createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "", true), + createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "", false), + createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "", true), + + createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "Paweł Środowski", false), + createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true), + createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false), + createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true) + ) + + val lessons = runBlocking { + TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable( + student = student, + semester = semester, + start = LocalDate.of(2019, 12, 23), + end = LocalDate.of(2019, 12, 25), + forceRefresh = true + ).filter { it.status == Status.SUCCESS }.first().data.orEmpty() + } + + assertEquals(12, lessons.size) + + assertEquals("Paweł Poniedziałkowski", lessons[0].teacher) + assertEquals("Jakub Wtorkowski", lessons[1].teacher) + assertEquals("Joanna Poniedziałkowska", lessons[2].teacher) + assertEquals("Joanna Wtorkowska", lessons[3].teacher) + + assertEquals("Joanna Wtorkowska", lessons[4].teacher) + assertEquals("", lessons[5].teacher) + assertEquals("", lessons[6].teacher) + assertEquals("", lessons[7].teacher) + + assertEquals("Paweł Środowski", lessons[8].teacher) + assertEquals("Paweł Czwartkowski", lessons[9].teacher) + assertEquals("Paweł Środowski", lessons[10].teacher) + assertEquals("Paweł Czwartkowski", lessons[11].teacher) + } +} diff --git a/app/src/androidTest/java/io/github/wulkanowy/utils/security/ScramblerTest.kt b/app/src/androidTest/java/io/github/wulkanowy/utils/security/ScramblerTest.kt index 1b0319f6..0c47e6bb 100644 --- a/app/src/androidTest/java/io/github/wulkanowy/utils/security/ScramblerTest.kt +++ b/app/src/androidTest/java/io/github/wulkanowy/utils/security/ScramblerTest.kt @@ -14,37 +14,34 @@ import kotlin.test.assertFailsWith @RunWith(AndroidJUnit4::class) class ScramblerTest { - private val scrambler = Scrambler(ApplicationProvider.getApplicationContext()) - @Test fun encryptDecryptTest() { - assertEquals( - "TEST", scrambler.decrypt(scrambler.encrypt("TEST")) - ) + assertEquals("TEST", decrypt(encrypt("TEST", + ApplicationProvider.getApplicationContext()))) } @Test fun emptyTextEncryptTest() { assertFailsWith { - scrambler.decrypt("") + decrypt("") } assertFailsWith { - scrambler.encrypt("") + encrypt("", ApplicationProvider.getApplicationContext()) } } @Test @SdkSuppress(minSdkVersion = 18) fun emptyKeyStoreTest() { - val text = scrambler.encrypt("test") + val text = encrypt("test", ApplicationProvider.getApplicationContext()) val keyStore = KeyStore.getInstance("AndroidKeyStore") keyStore.load(null) keyStore.deleteEntry("wulkanowy_password") assertFailsWith { - scrambler.decrypt(text) + decrypt(text) } } } diff --git a/app/src/debug/agconnect-services.json b/app/src/debug/agconnect-services.json new file mode 100644 index 00000000..48192df0 --- /dev/null +++ b/app/src/debug/agconnect-services.json @@ -0,0 +1,33 @@ +{ + "agcgw":{ + "backurl":"connect-dre.dbankcloud.cn", + "url":"connect-dre.hispace.hicloud.com" + }, + "client":{ + "cp_id":"890048000024105546", + "product_id":"", + "client_id":"", + "client_secret":"", + "app_id":"101440411", + "package_name":"io.github.wulkanowy.dev", + "api_key":"" + }, + "service":{ + "analytics":{ + "collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn", + "resource_id":"p1", + "channel_id":"" + }, + "search":{ + "url":"https://search-dre.cloud.huawei.com" + }, + "cloudstorage":{ + "storage_url":"https://ops-dre.agcstorage.link" + }, + "ml":{ + "mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn" + } + }, + "region":"DE", + "configuration_version":"1.0" +} diff --git a/app/google-services.json b/app/src/debug/google-services.json similarity index 56% rename from app/google-services.json rename to app/src/debug/google-services.json index 2f71b854..e9303986 100644 --- a/app/google-services.json +++ b/app/src/debug/google-services.json @@ -36,37 +36,6 @@ "status": 2 } } - }, - { - "client_info": { - "mobilesdk_app_id": "1:1091101852179:android:b558a25f65d088b1", - "android_client_info": { - "package_name": "io.github.wulkanowy" - } - }, - "oauth_client": [ - { - "client_id": "", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 - } - } } ], "configuration_version": "1" diff --git a/app/src/debug/res/drawable/ic_stat_grade.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml similarity index 100% rename from app/src/debug/res/drawable/ic_stat_grade.xml rename to app/src/debug/res/drawable-anydpi-v24/ic_stat_grade.xml diff --git a/app/src/debug/res/drawable/ic_stat_luckynumber.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml similarity index 100% rename from app/src/debug/res/drawable/ic_stat_luckynumber.xml rename to app/src/debug/res/drawable-anydpi-v24/ic_stat_luckynumber.xml diff --git a/app/src/debug/res/drawable/ic_stat_message.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml similarity index 100% rename from app/src/debug/res/drawable/ic_stat_message.xml rename to app/src/debug/res/drawable-anydpi-v24/ic_stat_message.xml diff --git a/app/src/debug/res/drawable/ic_stat_note.xml b/app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml similarity index 100% rename from app/src/debug/res/drawable/ic_stat_note.xml rename to app/src/debug/res/drawable-anydpi-v24/ic_stat_note.xml diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_grade.png b/app/src/debug/res/drawable-hdpi/ic_stat_grade.png new file mode 100644 index 00000000..013b7ac4 Binary files /dev/null and b/app/src/debug/res/drawable-hdpi/ic_stat_grade.png differ diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_luckynumber.png b/app/src/debug/res/drawable-hdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..74a4d0c5 Binary files /dev/null and b/app/src/debug/res/drawable-hdpi/ic_stat_luckynumber.png differ diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_message.png b/app/src/debug/res/drawable-hdpi/ic_stat_message.png new file mode 100644 index 00000000..be41e343 Binary files /dev/null and b/app/src/debug/res/drawable-hdpi/ic_stat_message.png differ diff --git a/app/src/debug/res/drawable-hdpi/ic_stat_note.png b/app/src/debug/res/drawable-hdpi/ic_stat_note.png new file mode 100644 index 00000000..1992edf2 Binary files /dev/null and b/app/src/debug/res/drawable-hdpi/ic_stat_note.png differ diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_grade.png b/app/src/debug/res/drawable-mdpi/ic_stat_grade.png new file mode 100644 index 00000000..a5df2a35 Binary files /dev/null and b/app/src/debug/res/drawable-mdpi/ic_stat_grade.png differ diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png b/app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..278ed2c6 Binary files /dev/null and b/app/src/debug/res/drawable-mdpi/ic_stat_luckynumber.png differ diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_message.png b/app/src/debug/res/drawable-mdpi/ic_stat_message.png new file mode 100644 index 00000000..7327a02f Binary files /dev/null and b/app/src/debug/res/drawable-mdpi/ic_stat_message.png differ diff --git a/app/src/debug/res/drawable-mdpi/ic_stat_note.png b/app/src/debug/res/drawable-mdpi/ic_stat_note.png new file mode 100644 index 00000000..2fb02098 Binary files /dev/null and b/app/src/debug/res/drawable-mdpi/ic_stat_note.png differ diff --git a/app/src/debug/res/drawable-xhdpi/ic_stat_grade.png b/app/src/debug/res/drawable-xhdpi/ic_stat_grade.png new file mode 100644 index 00000000..c63f810f Binary files /dev/null and b/app/src/debug/res/drawable-xhdpi/ic_stat_grade.png differ diff --git a/app/src/debug/res/drawable-xhdpi/ic_stat_luckynumber.png b/app/src/debug/res/drawable-xhdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..4035ceba Binary files /dev/null and b/app/src/debug/res/drawable-xhdpi/ic_stat_luckynumber.png differ diff --git a/app/src/debug/res/drawable-xhdpi/ic_stat_message.png b/app/src/debug/res/drawable-xhdpi/ic_stat_message.png new file mode 100644 index 00000000..c4140be8 Binary files /dev/null and b/app/src/debug/res/drawable-xhdpi/ic_stat_message.png differ diff --git a/app/src/debug/res/drawable-xhdpi/ic_stat_note.png b/app/src/debug/res/drawable-xhdpi/ic_stat_note.png new file mode 100644 index 00000000..6b533c8e Binary files /dev/null and b/app/src/debug/res/drawable-xhdpi/ic_stat_note.png differ diff --git a/app/src/debug/res/drawable-xxhdpi/ic_stat_grade.png b/app/src/debug/res/drawable-xxhdpi/ic_stat_grade.png new file mode 100644 index 00000000..13c26b77 Binary files /dev/null and b/app/src/debug/res/drawable-xxhdpi/ic_stat_grade.png differ diff --git a/app/src/debug/res/drawable-xxhdpi/ic_stat_luckynumber.png b/app/src/debug/res/drawable-xxhdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..da435745 Binary files /dev/null and b/app/src/debug/res/drawable-xxhdpi/ic_stat_luckynumber.png differ diff --git a/app/src/debug/res/drawable-xxhdpi/ic_stat_message.png b/app/src/debug/res/drawable-xxhdpi/ic_stat_message.png new file mode 100644 index 00000000..9d0fa781 Binary files /dev/null and b/app/src/debug/res/drawable-xxhdpi/ic_stat_message.png differ diff --git a/app/src/debug/res/drawable-xxhdpi/ic_stat_note.png b/app/src/debug/res/drawable-xxhdpi/ic_stat_note.png new file mode 100644 index 00000000..64da443f Binary files /dev/null and b/app/src/debug/res/drawable-xxhdpi/ic_stat_note.png differ diff --git a/app/src/debug/res/drawable/ic_stat_timetable.xml b/app/src/debug/res/drawable/ic_stat_timetable.xml deleted file mode 100644 index ac99d4a8..00000000 --- a/app/src/debug/res/drawable/ic_stat_timetable.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml index 9c21d49d..7dbec2cb 100644 --- a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,6 +1,5 @@ - + - - + \ No newline at end of file diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..7dbec2cb --- /dev/null +++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000..81e723ec Binary files /dev/null and b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000..394b5707 Binary files /dev/null and b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000..365b4d66 Binary files /dev/null and b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..463c089b Binary files /dev/null and b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..53d6f5bb Binary files /dev/null and b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/AdsHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/AdsHelper.kt deleted file mode 100644 index 3a3b5948..00000000 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/AdsHelper.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Context -import android.view.View -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import kotlinx.coroutines.flow.MutableStateFlow -import javax.inject.Inject - -@Suppress("unused") -class AdsHelper @Inject constructor( - @ApplicationContext private val context: Context, - private val preferencesRepository: PreferencesRepository -) { - - val isMobileAdsSdkInitialized = MutableStateFlow(false) - val canShowAd = false - - fun initialize() { - preferencesRepository.isAdsEnabled = false - preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS - } - - @Suppress("RedundantSuspendModifier", "UNUSED_PARAMETER") - suspend fun getDashboardTileAdBanner(width: Int): AdBanner { - throw IllegalStateException("Can't get ad banner (F-droid)") - } -} - -data class AdBanner(val view: View) diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt index a3eed484..3bf7e169 100644 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt +++ b/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt @@ -8,7 +8,15 @@ import javax.inject.Singleton @Suppress("UNUSED_PARAMETER") class AnalyticsHelper @Inject constructor() { - fun logEvent(name: String, vararg params: Pair) = Unit - fun setCurrentScreen(activity: Activity, name: String?) = Unit - fun popCurrentScreen(name: String?) = Unit + fun logEvent(name: String, vararg params: Pair) { + // do nothing + } + + fun setCurrentScreen(activity: Activity, name: String?) { + // do nothing + } + + fun popCurrentScreen(name: String?) { + // do nothing + } } diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt deleted file mode 100644 index 8615d975..00000000 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/InAppReviewHelper.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.ui.modules.main.MainActivity -import javax.inject.Singleton -import javax.inject.Inject - -@Suppress("UNUSED_PARAMETER", "unused") -@Singleton -class InAppReviewHelper @Inject constructor( - @ApplicationContext private val context: Context -) { - - fun showInAppReview(activity: MainActivity) { - // do nothing - } -} \ No newline at end of file diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt deleted file mode 100644 index 51b22ec7..00000000 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.utils - -import android.view.View -import javax.inject.Inject - -class InAppUpdateHelper @Inject constructor() { - - lateinit var messageContainer: View - - fun checkAndInstallUpdates() {} - - fun onResume() {} -} diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/IntegrityHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/IntegrityHelper.kt deleted file mode 100644 index 7af68058..00000000 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/IntegrityHelper.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.utils - -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class IntegrityHelper @Inject constructor() { - - @Suppress("UNUSED_PARAMETER") - fun getIntegrityToken(requestId: String): String? = null -} diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt deleted file mode 100644 index 88f2598f..00000000 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.wulkanowy.utils - -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RemoteConfigHelper @Inject constructor() : BaseRemoteConfigHelper() diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/UpdateHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/UpdateHelper.kt new file mode 100644 index 00000000..3abab962 --- /dev/null +++ b/app/src/fdroid/java/io/github/wulkanowy/utils/UpdateHelper.kt @@ -0,0 +1,17 @@ +package io.github.wulkanowy.utils + +import android.app.Activity +import android.view.View +import javax.inject.Inject + +@Suppress("UNUSED_PARAMETER") +class UpdateHelper @Inject constructor() { + + lateinit var messageContainer: View + + fun checkAndInstallUpdates(activity: Activity) {} + + fun onActivityResult(requestCode: Int, resultCode: Int) {} + + fun onResume(activity: Activity) {} +} diff --git a/app/src/hms/java/io/github/wulkanowy/utils/AdsHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/AdsHelper.kt deleted file mode 100644 index 165a6204..00000000 --- a/app/src/hms/java/io/github/wulkanowy/utils/AdsHelper.kt +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Context -import android.view.View -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import kotlinx.coroutines.flow.MutableStateFlow -import javax.inject.Inject - -@Suppress("unused") -class AdsHelper @Inject constructor( - @ApplicationContext private val context: Context, - private val preferencesRepository: PreferencesRepository -) { - val isMobileAdsSdkInitialized = MutableStateFlow(false) - val canShowAd = false - - fun initialize() { - preferencesRepository.isAdsEnabled = false - preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS - } - - @Suppress("RedundantSuspendModifier", "UNUSED_PARAMETER") - suspend fun getDashboardTileAdBanner(width: Int): AdBanner { - throw IllegalStateException("Can't get ad banner (HMS)") - } -} - -data class AdBanner(val view: View) diff --git a/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt index 1f78931a..5d33825f 100644 --- a/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt +++ b/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt @@ -3,38 +3,26 @@ package io.github.wulkanowy.utils import android.app.Activity import android.content.Context import android.os.Bundle -import com.huawei.agconnect.crash.AGConnectCrash import com.huawei.hms.analytics.HiAnalytics import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.data.repositories.PreferencesRepository import javax.inject.Inject import javax.inject.Singleton @Singleton class AnalyticsHelper @Inject constructor( - @ApplicationContext private val context: Context, - preferencesRepository: PreferencesRepository, - appInfo: AppInfo, + @ApplicationContext private val context: Context ) { private val analytics by lazy { HiAnalytics.getInstance(context) } - private val connectCrash by lazy { AGConnectCrash.getInstance() } - - init { - if (!appInfo.isDebug) { - connectCrash.setUserId(preferencesRepository.installationId) - } - } - fun logEvent(name: String, vararg params: Pair) { Bundle().apply { - params.forEach { (key, value) -> - if (value == null) return@forEach - when (value) { - is String -> putString(key, value) - is Int -> putInt(key, value) - is Boolean -> putBoolean(key, value) + params.forEach { + if (it.second == null) return@forEach + when (it.second) { + is String, is String? -> putString(it.first, it.second as String) + is Int, is Int? -> putInt(it.first, it.second as Int) + is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean) } } analytics.onEvent(name, this) diff --git a/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt b/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt index 2b1f1d30..b5fb6ad7 100644 --- a/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt +++ b/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt @@ -2,8 +2,12 @@ package io.github.wulkanowy.utils import android.util.Log import com.huawei.agconnect.crash.AGConnectCrash -import fr.bipi.treessence.base.FormatterPriorityTree -import fr.bipi.treessence.common.StackTraceRecorder +import fr.bipi.tressence.base.FormatterPriorityTree +import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException +import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException +import java.io.InterruptedIOException +import java.net.SocketTimeoutException +import java.net.UnknownHostException class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) { @@ -16,17 +20,34 @@ class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) { } } -class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter) { +class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR) { private val connectCrash by lazy { AGConnectCrash.getInstance() } + override fun skipLog(priority: Int, tag: String?, message: String, t: Throwable?): Boolean { + return when (t) { + is FeatureDisabledException, + is FeatureNotAvailableException, + is UnknownHostException, + is SocketTimeoutException, + is InterruptedIOException -> true + else -> super.skipLog(priority, tag, message, t) + } + } + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (skipLog(priority, tag, message, t)) return + // Disabled due to a bug in the Huawei library + + /*connectCrash.setCustomKey("priority", priority) + connectCrash.setCustomKey("tag", tag.orEmpty()) + connectCrash.setCustomKey("message", message) + if (t != null) { connectCrash.recordException(t) } else { connectCrash.recordException(StackTraceRecorder(format(priority, tag, message))) - } + }*/ } } diff --git a/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt deleted file mode 100644 index adb162fd..00000000 --- a/app/src/hms/java/io/github/wulkanowy/utils/InAppReviewHelper.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.ui.modules.main.MainActivity -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -@Suppress("UNUSED_PARAMETER", "unused") -class InAppReviewHelper @Inject constructor( - @ApplicationContext private val context: Context -) { - - fun showInAppReview(activity: MainActivity) { - // do nothing - } -} diff --git a/app/src/hms/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt deleted file mode 100644 index 51b22ec7..00000000 --- a/app/src/hms/java/io/github/wulkanowy/utils/InAppUpdateHelper.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.utils - -import android.view.View -import javax.inject.Inject - -class InAppUpdateHelper @Inject constructor() { - - lateinit var messageContainer: View - - fun checkAndInstallUpdates() {} - - fun onResume() {} -} diff --git a/app/src/hms/java/io/github/wulkanowy/utils/IntegrityHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/IntegrityHelper.kt deleted file mode 100644 index 7af68058..00000000 --- a/app/src/hms/java/io/github/wulkanowy/utils/IntegrityHelper.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.utils - -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class IntegrityHelper @Inject constructor() { - - @Suppress("UNUSED_PARAMETER") - fun getIntegrityToken(requestId: String): String? = null -} diff --git a/app/src/hms/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt deleted file mode 100644 index 88f2598f..00000000 --- a/app/src/hms/java/io/github/wulkanowy/utils/RemoteConfigHelper.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.wulkanowy.utils - -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RemoteConfigHelper @Inject constructor() : BaseRemoteConfigHelper() diff --git a/app/src/hms/java/io/github/wulkanowy/utils/UpdateHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/UpdateHelper.kt new file mode 100644 index 00000000..3abab962 --- /dev/null +++ b/app/src/hms/java/io/github/wulkanowy/utils/UpdateHelper.kt @@ -0,0 +1,17 @@ +package io.github.wulkanowy.utils + +import android.app.Activity +import android.view.View +import javax.inject.Inject + +@Suppress("UNUSED_PARAMETER") +class UpdateHelper @Inject constructor() { + + lateinit var messageContainer: View + + fun checkAndInstallUpdates(activity: Activity) {} + + fun onActivityResult(requestCode: Int, resultCode: Int) {} + + fun onResume(activity: Activity) {} +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a4257893..a8d2b49e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,59 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:usesCleartextTraffic="true" + tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"> + tools:ignore="LockedOrientationActivity"> @@ -63,7 +33,7 @@ android:name=".ui.modules.login.LoginActivity" android:configChanges="orientation|screenSize" android:label="@string/login_title" - android:theme="@style/WulkanowyTheme.Login" + android:theme="@style/WulkanowyTheme.NoActionBar" android:windowSoftInputMode="adjustResize" /> @@ -90,7 +59,6 @@ @@ -101,22 +69,6 @@ - - - - - - - - - - @@ -144,9 +95,11 @@ + + android:value="${install_channel}"> + + + + + + + + + + + + + + + + + android:resource="@drawable/ic_stat_push" /> + - - diff --git a/app/src/main/assets/contributors.json b/app/src/main/assets/contributors.json index 97ac9356..54b47350 100644 --- a/app/src/main/assets/contributors.json +++ b/app/src/main/assets/contributors.json @@ -34,29 +34,5 @@ { "displayName": "Mateusz Idziejczak", "githubUsername": "Luncenok" - }, - { - "displayName": "Daniel Olczyk", - "githubUsername": "MRmlik12" - }, - { - "displayName": "Damian Czupryn", - "githubUsername": "Daxxxis" - }, - { - "displayName": "Kamil Studziński", - "githubUsername": "studzinskik" - }, - { - "displayName": "Tomasz F.", - "githubUsername": "Pengwius" - }, - { - "displayName": "Antoni Paduch", - "githubUsername": "janAte1" - }, - { - "displayName": "Kamil Wąsik", - "githubUsername": "JestemKamil" } ] diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt index 38fade0a..57d14725 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt @@ -1,71 +1,59 @@ package io.github.wulkanowy import android.app.Application +import android.content.Context import android.util.Log.DEBUG import android.util.Log.INFO import android.util.Log.VERBOSE import androidx.hilt.work.HiltWorkerFactory +import androidx.multidex.MultiDex import androidx.work.Configuration import com.yariksoffice.lingver.Lingver import dagger.hilt.android.HiltAndroidApp -import fr.bipi.treessence.file.FileLoggerTree -import io.github.wulkanowy.data.repositories.PreferencesRepository +import fr.bipi.tressence.file.FileLoggerTree import io.github.wulkanowy.ui.base.ThemeManager import io.github.wulkanowy.utils.ActivityLifecycleLogger -import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.CrashLogExceptionTree import io.github.wulkanowy.utils.CrashLogTree import io.github.wulkanowy.utils.DebugLogTree -import io.github.wulkanowy.utils.RemoteConfigHelper import timber.log.Timber import javax.inject.Inject @HiltAndroidApp class WulkanowyApp : Application(), Configuration.Provider { + @Inject + lateinit var workerFactory: HiltWorkerFactory + @Inject lateinit var themeManager: ThemeManager @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - - @Inject - lateinit var analyticsHelper: AnalyticsHelper - - @Inject - lateinit var remoteConfigHelper: RemoteConfigHelper - - @Inject - lateinit var workerFactory: HiltWorkerFactory - - override val workManagerConfiguration: Configuration - get() = Configuration.Builder() - .setWorkerFactory(workerFactory) - .setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO) - .build() + override fun attachBaseContext(base: Context?) { + super.attachBaseContext(base) + MultiDex.install(this) + } override fun onCreate() { super.onCreate() - initializeAppLanguage() + Lingver.init(this) themeManager.applyDefaultTheme() - remoteConfigHelper.initialize() + initLogging() } private fun initLogging() { if (appInfo.isDebug) { Timber.plant(DebugLogTree()) - Timber.plant( - FileLoggerTree.Builder() - .withFileName("wulkanowy.%g.log") - .withDirName(applicationContext.filesDir.absolutePath) - .withFileLimit(10) - .withMinPriority(DEBUG) - .build() + Timber.plant(FileLoggerTree.Builder() + .withFileName("wulkanowy.%g.log") + .withDirName(applicationContext.filesDir.absolutePath) + .withFileLimit(10) + .withMinPriority(DEBUG) + .build() ) } else { Timber.plant(CrashLogExceptionTree()) @@ -74,14 +62,8 @@ class WulkanowyApp : Application(), Configuration.Provider { registerActivityLifecycleCallbacks(ActivityLifecycleLogger()) } - private fun initializeAppLanguage() { - Lingver.init(this) - - if (preferencesRepository.appLanguage == "system") { - Lingver.getInstance().setFollowSystemLocale(this) - analyticsHelper.logEvent("language", "startup" to appInfo.systemLanguage) - } else { - analyticsHelper.logEvent("language", "startup" to preferencesRepository.appLanguage) - } - } + override fun getWorkManagerConfiguration() = Configuration.Builder() + .setWorkerFactory(workerFactory) + .setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO) + .build() } diff --git a/app/src/main/java/io/github/wulkanowy/data/DataModule.kt b/app/src/main/java/io/github/wulkanowy/data/DataModule.kt deleted file mode 100644 index a21d56cc..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/DataModule.kt +++ /dev/null @@ -1,246 +0,0 @@ -package io.github.wulkanowy.data - -import android.content.Context -import android.content.SharedPreferences -import androidx.preference.PreferenceManager -import com.chuckerteam.chucker.api.ChuckerCollector -import com.chuckerteam.chucker.api.ChuckerInterceptor -import com.chuckerteam.chucker.api.RetentionManager -import com.fredporciuncula.flow.preferences.FlowSharedPreferences -import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import io.github.wulkanowy.data.api.services.SchoolsService -import io.github.wulkanowy.data.api.services.WulkanowyService -import io.github.wulkanowy.data.db.AppDatabase -import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.utils.AppInfo -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import retrofit2.Retrofit -import retrofit2.create -import java.util.concurrent.TimeUnit -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal class DataModule { - - @Singleton - @Provides - fun provideChuckerCollector( - @ApplicationContext context: Context, - prefRepository: PreferencesRepository - ) = ChuckerCollector( - context = context, - showNotification = prefRepository.isDebugNotificationEnable, - retentionPeriod = RetentionManager.Period.ONE_HOUR - ) - - @Singleton - @Provides - fun provideChuckerInterceptor( - @ApplicationContext context: Context, - chuckerCollector: ChuckerCollector - ) = ChuckerInterceptor.Builder(context) - .collector(chuckerCollector) - .alwaysReadResponseBody(true) - .build() - - @Singleton - @Provides - fun provideOkHttpClient(chuckerInterceptor: ChuckerInterceptor): OkHttpClient = - OkHttpClient.Builder() - .addNetworkInterceptor(chuckerInterceptor) - .addInterceptor(HttpLoggingInterceptor().apply { - level = HttpLoggingInterceptor.Level.BASIC - }) - .connectTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .build() - - @Singleton - @Provides - fun provideAdminMessageService( - okHttpClient: OkHttpClient, - json: Json, - appInfo: AppInfo - ): WulkanowyService = Retrofit.Builder() - .baseUrl(appInfo.messagesBaseUrl) - .client(okHttpClient) - .addConverterFactory(json.asConverterFactory("application/json".toMediaType())) - .build() - .create() - - @Singleton - @Provides - fun provideSchoolsService( - okHttpClient: OkHttpClient, - json: Json, - appInfo: AppInfo, - ): SchoolsService = Retrofit.Builder() - .baseUrl(appInfo.schoolsBaseUrl) - .client(okHttpClient) - .addConverterFactory(json.asConverterFactory("application/json".toMediaType())) - .build() - .create() - - @Singleton - @Provides - fun provideDatabase( - @ApplicationContext context: Context, - sharedPrefProvider: SharedPrefProvider, - appInfo: AppInfo - ) = AppDatabase.newInstance(context, sharedPrefProvider, appInfo) - - @Singleton - @Provides - fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences = - PreferenceManager.getDefaultSharedPreferences(context) - - @Singleton - @Provides - fun provideFlowSharedPref(sharedPreferences: SharedPreferences) = - FlowSharedPreferences(sharedPreferences) - - @Singleton - @Provides - fun provideJson() = Json { - ignoreUnknownKeys = true - } - - @Singleton - @Provides - fun provideStudentDao(database: AppDatabase) = database.studentDao - - @Singleton - @Provides - fun provideSemesterDao(database: AppDatabase) = database.semesterDao - - @Singleton - @Provides - fun provideGradeDao(database: AppDatabase) = database.gradeDao - - @Singleton - @Provides - fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao - - @Singleton - @Provides - fun provideGradePartialStatisticsDao(database: AppDatabase) = database.gradePartialStatisticsDao - - @Singleton - @Provides - fun provideGradeSemesterStatisticsDao(database: AppDatabase) = - database.gradeSemesterStatisticsDao - - @Singleton - @Provides - fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatisticsDao - - @Singleton - @Provides - fun provideMessagesDao(database: AppDatabase) = database.messagesDao - - @Singleton - @Provides - fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao - - @Singleton - @Provides - fun provideExamDao(database: AppDatabase) = database.examsDao - - @Singleton - @Provides - fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao - - @Singleton - @Provides - fun provideAttendanceSummaryDao(database: AppDatabase) = database.attendanceSummaryDao - - @Singleton - @Provides - fun provideTimetableDao(database: AppDatabase) = database.timetableDao - - @Singleton - @Provides - fun provideNoteDao(database: AppDatabase) = database.noteDao - - @Singleton - @Provides - fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao - - @Singleton - @Provides - fun provideSubjectDao(database: AppDatabase) = database.subjectDao - - @Singleton - @Provides - fun provideLuckyNumberDao(database: AppDatabase) = database.luckyNumberDao - - @Singleton - @Provides - fun provideCompletedLessonsDao(database: AppDatabase) = database.completedLessonsDao - - @Singleton - @Provides - fun provideMailboxesDao(database: AppDatabase) = database.mailboxDao - - @Singleton - @Provides - fun provideRecipientDao(database: AppDatabase) = database.recipientDao - - @Singleton - @Provides - fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao - - @Singleton - @Provides - fun provideTeacherDao(database: AppDatabase) = database.teacherDao - - @Singleton - @Provides - fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao - - @Singleton - @Provides - fun provideConferenceDao(database: AppDatabase) = database.conferenceDao - - @Singleton - @Provides - fun provideTimetableAdditionalDao(database: AppDatabase) = database.timetableAdditionalDao - - @Singleton - @Provides - fun provideStudentInfoDao(database: AppDatabase) = database.studentInfoDao - - @Singleton - @Provides - fun provideTimetableHeaderDao(database: AppDatabase) = database.timetableHeaderDao - - @Singleton - @Provides - fun provideSchoolAnnouncementDao(database: AppDatabase) = database.schoolAnnouncementDao - - @Singleton - @Provides - fun provideNotificationDao(database: AppDatabase) = database.notificationDao - - @Singleton - @Provides - fun provideAdminMessageDao(database: AppDatabase) = database.adminMessagesDao - - @Singleton - @Provides - fun provideMutesDao(database: AppDatabase) = database.mutedMessageSendersDao - - @Singleton - @Provides - fun provideGradeDescriptiveDao(database: AppDatabase) = database.gradeDescriptiveDao -} diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt new file mode 100644 index 00000000..e8a3fa48 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt @@ -0,0 +1,165 @@ +package io.github.wulkanowy.data + +import android.content.Context +import android.content.SharedPreferences +import android.content.res.AssetManager +import android.content.res.Resources +import androidx.preference.PreferenceManager +import com.chuckerteam.chucker.api.ChuckerCollector +import com.chuckerteam.chucker.api.ChuckerInterceptor +import com.chuckerteam.chucker.api.RetentionManager +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import io.github.wulkanowy.data.db.AppDatabase +import io.github.wulkanowy.data.db.SharedPrefProvider +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.sdk.Sdk +import timber.log.Timber +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal class RepositoryModule { + + @Singleton + @Provides + fun provideSdk(chuckerCollector: ChuckerCollector, @ApplicationContext context: Context): Sdk { + return Sdk().apply { + androidVersion = android.os.Build.VERSION.RELEASE + buildTag = android.os.Build.MODEL + setSimpleHttpLogger { Timber.d(it) } + + // for debug only + addInterceptor(ChuckerInterceptor( + context = context, + collector = chuckerCollector, + alwaysReadResponseBody = true + ), true) + } + } + + @Singleton + @Provides + fun provideChuckerCollector(@ApplicationContext context: Context, prefRepository: PreferencesRepository): ChuckerCollector { + return ChuckerCollector( + context = context, + showNotification = prefRepository.isDebugNotificationEnable, + retentionPeriod = RetentionManager.Period.ONE_HOUR + ) + } + + @Singleton + @Provides + fun provideDatabase(@ApplicationContext context: Context, sharedPrefProvider: SharedPrefProvider) = AppDatabase.newInstance(context, sharedPrefProvider) + + @Singleton + @Provides + fun provideResources(@ApplicationContext context: Context): Resources = context.resources + + @Singleton + @Provides + fun provideAssets(@ApplicationContext context: Context): AssetManager = context.assets + + @Singleton + @Provides + fun provideSharedPref(@ApplicationContext context: Context): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + + @Singleton + @Provides + fun provideStudentDao(database: AppDatabase) = database.studentDao + + @Singleton + @Provides + fun provideSemesterDao(database: AppDatabase) = database.semesterDao + + @Singleton + @Provides + fun provideGradeDao(database: AppDatabase) = database.gradeDao + + @Singleton + @Provides + fun provideGradeSummaryDao(database: AppDatabase) = database.gradeSummaryDao + + @Singleton + @Provides + fun provideGradePartialStatisticsDao(database: AppDatabase) = database.gradePartialStatisticsDao + + @Singleton + @Provides + fun provideGradeSemesterStatisticsDao(database: AppDatabase) = database.gradeSemesterStatisticsDao + + @Singleton + @Provides + fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatisticsDao + + @Singleton + @Provides + fun provideMessagesDao(database: AppDatabase) = database.messagesDao + + @Singleton + @Provides + fun provideMessageAttachmentsDao(database: AppDatabase) = database.messageAttachmentDao + + @Singleton + @Provides + fun provideExamDao(database: AppDatabase) = database.examsDao + + @Singleton + @Provides + fun provideAttendanceDao(database: AppDatabase) = database.attendanceDao + + @Singleton + @Provides + fun provideAttendanceSummaryDao(database: AppDatabase) = database.attendanceSummaryDao + + @Singleton + @Provides + fun provideTimetableDao(database: AppDatabase) = database.timetableDao + + @Singleton + @Provides + fun provideNoteDao(database: AppDatabase) = database.noteDao + + @Singleton + @Provides + fun provideHomeworkDao(database: AppDatabase) = database.homeworkDao + + @Singleton + @Provides + fun provideSubjectDao(database: AppDatabase) = database.subjectDao + + @Singleton + @Provides + fun provideLuckyNumberDao(database: AppDatabase) = database.luckyNumberDao + + @Singleton + @Provides + fun provideCompletedLessonsDao(database: AppDatabase) = database.completedLessonsDao + + @Singleton + @Provides + fun provideReportingUnitDao(database: AppDatabase) = database.reportingUnitDao + + @Singleton + @Provides + fun provideRecipientDao(database: AppDatabase) = database.recipientDao + + @Singleton + @Provides + fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao + + @Singleton + @Provides + fun provideTeacherDao(database: AppDatabase) = database.teacherDao + + @Singleton + @Provides + fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao + + @Singleton + @Provides + fun provideConferenceDao(database: AppDatabase) = database.conferenceDao +} diff --git a/app/src/main/java/io/github/wulkanowy/data/Resource.kt b/app/src/main/java/io/github/wulkanowy/data/Resource.kt index 712a946f..406440c8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/Resource.kt +++ b/app/src/main/java/io/github/wulkanowy/data/Resource.kt @@ -1,285 +1,23 @@ package io.github.wulkanowy.data -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.filterNot -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.takeWhile -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import timber.log.Timber -import kotlin.time.Duration -import kotlin.time.Duration.Companion.seconds - -sealed interface Resource { - /** - * The initial value of a resource flow. Indicates no data that is currently available to be shown, - * however with the expectation that the state will transition to another one soon. - */ - open class Loading : Resource - - /** - * A semi-loading state with some data available to be displayed (usually cached data loaded from - * the database). Still not the target state and it's expected to transition into another one soon. - */ - data class Intermediate(val data: T) : Loading() - - /** - * The happy-path target state. Data can either be: - * - loaded from the database - while it may seem like this case is already handled by the - * Intermediate state, the difference here is semantic. Cached data is returned as Intermediate - * when there's a API request in progress (or soon expected to be), however when there is no - * intention of immediately querying the API, the cached data is returned as a Success. - * - fetched from the API. - */ - data class Success(val data: T) : Resource - - /** - * Something bad happened and we were unable to get the requested data. This can be caused by - * a database error, a network error, or really just any other error. Upon receiving this state - * the UI can either: display a full screen error, or, when it has received any data previously, - * display a snack bar informing of the problem. - */ - data class Error(val error: Throwable) : Resource -} - -val Resource.dataOrNull: T? - get() = when (this) { - is Resource.Success -> this.data - is Resource.Intermediate -> this.data - else -> null - } - -val Resource.dataOrThrow: T - get() = when (this) { - is Resource.Success -> this.data - is Resource.Intermediate -> this.data - is Resource.Loading -> throw IllegalStateException("Resource is in loading state") - is Resource.Error -> throw this.error - } - -val Resource.errorOrNull: Throwable? - get() = when (this) { - is Resource.Error -> this.error - else -> null - } - -fun resourceFlow(block: suspend () -> T) = flow { - emit(Resource.Loading()) - emit(Resource.Success(block())) -}.catch { emit(Resource.Error(it)) } - -fun flatResourceFlow(block: suspend () -> Flow>) = flow { - emit(Resource.Loading()) - emitAll(block().filter { it is Resource.Intermediate || it !is Resource.Loading }) -}.catch { emit(Resource.Error(it)) } - -fun Resource.mapData(block: (T) -> U) = when (this) { - is Resource.Success -> Resource.Success(block(this.data)) - is Resource.Intermediate -> Resource.Intermediate(block(this.data)) - is Resource.Loading -> Resource.Loading() - is Resource.Error -> Resource.Error(this.error) -} - -/** - * Injects another flow into this flow's resource data. - */ -inline fun Flow>.combineWithResourceData( - flow: Flow, - crossinline block: suspend (T1, T2) -> R -): Flow> = - combine(flow) { resource, inject -> - when (resource) { - is Resource.Success -> Resource.Success(block(resource.data, inject)) - is Resource.Intermediate -> Resource.Intermediate(block(resource.data, inject)) - is Resource.Loading -> Resource.Loading() - is Resource.Error -> Resource.Error(resource.error) - } - } - -fun Flow>.logResourceStatus(name: String, showData: Boolean = false) = onEach { - val description = when (it) { - is Resource.Intermediate -> "intermediate data received" + if (showData) " (data: `${it.data}`)" else "" - is Resource.Loading -> "started" - is Resource.Success -> "success" + if (showData) " (data: `${it.data}`)" else "" - is Resource.Error -> "exception occurred: ${it.error}" - } - Timber.i("$name: $description") -} - -inline fun Flow>.mapResourceData(crossinline block: suspend (T) -> U) = map { - when (it) { - is Resource.Success -> Resource.Success(block(it.data)) - is Resource.Intermediate -> Resource.Intermediate(block(it.data)) - is Resource.Loading -> Resource.Loading() - is Resource.Error -> Resource.Error(it.error) - } -} - -@OptIn(ExperimentalCoroutinesApi::class) -fun Flow>.flatMapResourceData( - inheritIntermediate: Boolean = true, block: suspend (T) -> Flow> -) = flatMapLatest { - when (it) { - is Resource.Success -> block(it.data) - is Resource.Intermediate -> block(it.data).map { newRes -> - if (inheritIntermediate && newRes is Resource.Success) Resource.Intermediate(newRes.data) - else newRes +data class Resource(val status: Status, val data: T?, val error: Throwable?) { + companion object { + fun success(data: T?): Resource { + return Resource(Status.SUCCESS, data, null) } - is Resource.Loading -> flowOf(Resource.Loading()) - is Resource.Error -> flowOf(Resource.Error(it.error)) - } -} - -fun Flow>.onResourceData(block: suspend (T) -> Unit) = onEach { - when (it) { - is Resource.Success -> block(it.data) - is Resource.Intermediate -> block(it.data) - is Resource.Error, - is Resource.Loading -> Unit - } -} - -fun Flow>.onResourceLoading(block: suspend () -> Unit) = onEach { - if (it is Resource.Loading) { - block() - } -} - -fun Flow>.onResourceIntermediate(block: suspend (T) -> Unit) = onEach { - if (it is Resource.Intermediate) { - block(it.data) - } -} - -fun Flow>.onResourceSuccess(block: suspend (T) -> Unit) = onEach { - if (it is Resource.Success) { - block(it.data) - } -} - -fun Flow>.onResourceError(block: suspend (Throwable) -> Unit) = onEach { - if (it is Resource.Error) { - block(it.error) - } -} - -fun Flow>.onResourceNotLoading(block: suspend () -> Unit) = onEach { - if (it !is Resource.Loading) { - block() - } -} - -suspend fun Flow>.toFirstResult() = filter { it !is Resource.Loading }.first() - -suspend fun Flow>.waitForResult() = takeWhile { it is Resource.Loading }.collect() - -// Can cause excessive amounts of `Resource.Intermediate` to be emitted. Unless that is desired, -// use `debounceIntermediates` to alleviate this behavior. -inline fun combineResourceFlows(flows: Iterable>>): Flow>> = - combine(flows) { items -> - var isIntermediate = false - val data = mutableListOf() - for (item in items) { - when (item) { - is Resource.Success -> data.add(item.data) - is Resource.Intermediate -> { - isIntermediate = true - data.add(item.data) - } - - is Resource.Loading -> return@combine Resource.Loading() - is Resource.Error -> continue - } + fun error(error: Throwable?, data: T? = null): Resource { + return Resource(Status.ERROR, data, error) } - if (data.isEmpty()) { - // All items have to be errors for this to happen, so just return the first one. - // mapData is functionally useless and exists only to satisfy the type checker - items.first().mapData { listOf(it) } - } else if (isIntermediate) { - Resource.Intermediate(data) - } else { - Resource.Success(data) + + fun loading(data: T? = null): Resource { + return Resource(Status.LOADING, data, null) } } - -@OptIn(FlowPreview::class) -fun Flow>.debounceIntermediates(timeout: Duration = 5.seconds) = flow { - var wasIntermediate = false - - emitAll(this@debounceIntermediates.debounce { - if (it is Resource.Intermediate) { - if (!wasIntermediate) { - wasIntermediate = true - Duration.ZERO - } else { - timeout - } - } else { - wasIntermediate = false - Duration.ZERO - } - }) } - -inline fun networkBoundResource( - mutex: Mutex = Mutex(), - crossinline isResultEmpty: (OutputType) -> Boolean, - crossinline query: () -> Flow, - crossinline fetch: suspend () -> ApiType, - crossinline saveFetchResult: suspend (old: OutputType, new: ApiType) -> Unit, - crossinline shouldFetch: (OutputType) -> Boolean = { true }, - crossinline filterResult: (OutputType) -> OutputType = { it } -) = networkBoundResource( - mutex = mutex, - isResultEmpty = isResultEmpty, - query = query, - fetch = fetch, - saveFetchResult = saveFetchResult, - shouldFetch = shouldFetch, - mapResult = filterResult -) - -@JvmName("networkBoundResourceWithMap") -inline fun networkBoundResource( - mutex: Mutex = Mutex(), - crossinline isResultEmpty: (OutputType) -> Boolean, - crossinline query: () -> Flow, - crossinline fetch: suspend () -> ApiType, - crossinline saveFetchResult: suspend (old: DatabaseType, new: ApiType) -> Unit, - crossinline shouldFetch: (DatabaseType) -> Boolean = { true }, - crossinline mapResult: (DatabaseType) -> OutputType, -) = flow { - emit(Resource.Loading()) - - val data = query().first() - if (shouldFetch(data)) { - emit(Resource.Intermediate(data)) - - try { - val newData = fetch() - mutex.withLock { saveFetchResult(query().first(), newData) } - } catch (throwable: Throwable) { - emit(Resource.Error(throwable)) - return@flow - } - } - - emitAll(query().map { Resource.Success(it) }) +enum class Status { + LOADING, + SUCCESS, + ERROR } - .mapResourceData { mapResult(it) } - .filterNot { it is Resource.Intermediate && isResultEmpty(it.data) } diff --git a/app/src/main/java/io/github/wulkanowy/data/WulkanowySdkFactory.kt b/app/src/main/java/io/github/wulkanowy/data/WulkanowySdkFactory.kt deleted file mode 100644 index 2931db35..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/WulkanowySdkFactory.kt +++ /dev/null @@ -1,171 +0,0 @@ -package io.github.wulkanowy.data - -import android.content.Context -import android.os.Build -import androidx.javascriptengine.JavaScriptSandbox -import com.chuckerteam.chucker.api.ChuckerInterceptor -import com.google.common.util.concurrent.ListenableFuture -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.data.db.dao.StudentDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentIsEduOne -import io.github.wulkanowy.data.repositories.WulkanowyRepository -import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.sdk.scrapper.EvaluateHandler -import io.github.wulkanowy.utils.RemoteConfigHelper -import io.github.wulkanowy.utils.WebkitCookieManagerProxy -import kotlinx.coroutines.guava.await -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class WulkanowySdkFactory @Inject constructor( - @ApplicationContext private val context: Context, - private val chuckerInterceptor: ChuckerInterceptor, - private val remoteConfig: RemoteConfigHelper, - private val webkitCookieManagerProxy: WebkitCookieManagerProxy, - private val studentDb: StudentDao, - private val wulkanowyRepository: WulkanowyRepository, -) { - - private val eduOneMutex = Mutex() - private val migrationFailedStudentIds = mutableSetOf() - private val sandbox: ListenableFuture? = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && JavaScriptSandbox.isSupported()) - JavaScriptSandbox.createConnectedInstanceAsync(context) - else null - - private val sdk = Sdk().apply { - androidVersion = Build.VERSION.RELEASE - buildTag = Build.MODEL - userAgentTemplate = remoteConfig.userAgentTemplate - setSimpleHttpLogger { Timber.d(it) } - setAdditionalCookieManager(webkitCookieManagerProxy) - - // for debug only - addInterceptor(chuckerInterceptor, network = true) - } - - fun createBase() = sdk - - suspend fun create(): Sdk { - val mapping = wulkanowyRepository.getMapping() - - return createBase().apply { - if (mapping != null) { - endpointsMapping = mapping.endpoints - vTokenMapping = mapping.vTokens - vTokenSchemeMapping = mapping.vTokenScheme - vParamsEvaluation = createIsolate() - } - } - } - - private suspend fun createIsolate(): suspend () -> EvaluateHandler { - return { - val isolate = sandbox?.await()?.createIsolate() - object : EvaluateHandler { - override suspend fun evaluate(code: String): String? { - return isolate?.evaluateJavaScriptAsync(code)?.await() - } - - override fun close() { - isolate?.close() - } - } - } - } - - suspend fun create(student: Student, semester: Semester? = null): Sdk { - val overrideIsEduOne = checkEduOneAndMigrateIfNecessary(student) - return buildSdk(student, semester, overrideIsEduOne) - } - - private suspend fun buildSdk( - student: Student, - semester: Semester?, - isStudentEduOne: Boolean - ): Sdk { - return create().apply { - email = student.email - password = student.password - symbol = student.symbol - schoolSymbol = student.schoolSymbol - studentId = student.studentId - classId = student.classId - emptyCookieJarInterceptor = true - isEduOne = isStudentEduOne - - if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) { - mobileBaseUrl = student.mobileBaseUrl - } else { - scrapperBaseUrl = student.scrapperBaseUrl - domainSuffix = student.scrapperDomainSuffix - loginType = Sdk.ScrapperLoginType.valueOf(student.loginType) - } - - mode = Sdk.Mode.valueOf(student.loginMode) - mobileBaseUrl = student.mobileBaseUrl - keyId = student.certificateKey - privatePem = student.privateKey - - if (semester != null) { - diaryId = semester.diaryId - kindergartenDiaryId = semester.kindergartenDiaryId - schoolYear = semester.schoolYear - unitId = semester.unitId - } - } - } - - private suspend fun checkEduOneAndMigrateIfNecessary(student: Student): Boolean { - if (student.isEduOne != null) return student.isEduOne - - if (student.id in migrationFailedStudentIds) { - Timber.i("Migration eduOne: skipping because of previous failure") - return false - } - - eduOneMutex.withLock { - if (student.id in migrationFailedStudentIds) { - Timber.i("Migration eduOne: skipping because of previous failure") - return false - } - - val studentFromDatabase = studentDb.loadById(student.id) - if (studentFromDatabase?.isEduOne != null) { - Timber.i("Migration eduOne: already done") - return studentFromDatabase.isEduOne - } - - Timber.i("Migration eduOne: flag missing. Running migration...") - val initializedSdk = buildSdk( - student = student, - semester = null, - isStudentEduOne = false, // doesn't matter - ) - val newCurrentStudent = runCatching { initializedSdk.getCurrentStudent() } - .onFailure { Timber.e(it, "Migration eduOne: can't get current student") } - .getOrNull() - - if (newCurrentStudent == null) { - Timber.i("Migration eduOne: failed, so skipping") - migrationFailedStudentIds.add(student.id) - return false - } - - Timber.i("Migration eduOne: success. New isEduOne flag: ${newCurrentStudent.isEduOne}") - - val studentIsEduOne = StudentIsEduOne( - id = student.id, - isEduOne = newCurrentStudent.isEduOne - ) - studentDb.update(studentIsEduOne) - return newCurrentStudent.isEduOne - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt b/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt deleted file mode 100644 index c4667a47..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/api/models/Mapping.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.wulkanowy.data.api.models - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class Mapping( - - @SerialName("endpoints") - val endpoints: Map>>, - - @SerialName("vTokens") - val vTokens: Map>>, - - @SerialName("vTokenScheme") - val vTokenScheme: Map> = emptyMap(), -) diff --git a/app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt b/app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt deleted file mode 100644 index 07fbeb89..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/api/services/SchoolsService.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.wulkanowy.data.api.services - -import io.github.wulkanowy.data.pojos.IntegrityRequest -import io.github.wulkanowy.data.pojos.LoginEvent -import retrofit2.http.Body -import retrofit2.http.POST -import javax.inject.Singleton - -@Singleton -interface SchoolsService { - - @POST("/log/loginEvent") - suspend fun logLoginEvent(@Body request: IntegrityRequest) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt b/app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt deleted file mode 100644 index 161e93d6..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/api/services/WulkanowyService.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.wulkanowy.data.api.services - -import io.github.wulkanowy.data.api.models.Mapping -import io.github.wulkanowy.data.db.entities.AdminMessage -import retrofit2.http.GET -import javax.inject.Singleton - -@Singleton -interface WulkanowyService { - - @GET("/v1.json") - suspend fun getAdminMessages(): List - - @GET("/mapping2.json") - suspend fun getMapping(): Mapping -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt index f23c79de..57160a2b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt @@ -1,76 +1,60 @@ package io.github.wulkanowy.data.db import android.content.Context -import androidx.room.AutoMigration import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.RoomDatabase.JournalMode.TRUNCATE import androidx.room.TypeConverters -import io.github.wulkanowy.data.db.dao.AdminMessageDao +import androidx.room.migration.Migration import io.github.wulkanowy.data.db.dao.AttendanceDao import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao import io.github.wulkanowy.data.db.dao.CompletedLessonsDao import io.github.wulkanowy.data.db.dao.ConferenceDao import io.github.wulkanowy.data.db.dao.ExamDao import io.github.wulkanowy.data.db.dao.GradeDao -import io.github.wulkanowy.data.db.dao.GradeDescriptiveDao import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao import io.github.wulkanowy.data.db.dao.GradeSummaryDao import io.github.wulkanowy.data.db.dao.HomeworkDao import io.github.wulkanowy.data.db.dao.LuckyNumberDao -import io.github.wulkanowy.data.db.dao.MailboxDao import io.github.wulkanowy.data.db.dao.MessageAttachmentDao import io.github.wulkanowy.data.db.dao.MessagesDao import io.github.wulkanowy.data.db.dao.MobileDeviceDao -import io.github.wulkanowy.data.db.dao.MutedMessageSendersDao import io.github.wulkanowy.data.db.dao.NoteDao -import io.github.wulkanowy.data.db.dao.NotificationDao import io.github.wulkanowy.data.db.dao.RecipientDao -import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao +import io.github.wulkanowy.data.db.dao.ReportingUnitDao import io.github.wulkanowy.data.db.dao.SchoolDao import io.github.wulkanowy.data.db.dao.SemesterDao import io.github.wulkanowy.data.db.dao.StudentDao -import io.github.wulkanowy.data.db.dao.StudentInfoDao import io.github.wulkanowy.data.db.dao.SubjectDao import io.github.wulkanowy.data.db.dao.TeacherDao -import io.github.wulkanowy.data.db.dao.TimetableAdditionalDao import io.github.wulkanowy.data.db.dao.TimetableDao -import io.github.wulkanowy.data.db.dao.TimetableHeaderDao -import io.github.wulkanowy.data.db.entities.AdminMessage import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.AttendanceSummary import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.data.db.entities.Conference import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive import io.github.wulkanowy.data.db.entities.GradePartialStatistics import io.github.wulkanowy.data.db.entities.GradePointsStatistics import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.data.db.entities.Mailbox import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.MessageAttachment import io.github.wulkanowy.data.db.entities.MobileDevice -import io.github.wulkanowy.data.db.entities.MutedMessageSender import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.data.db.entities.Notification import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.School -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentInfo import io.github.wulkanowy.data.db.entities.Subject import io.github.wulkanowy.data.db.entities.Teacher import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.db.entities.TimetableHeader import io.github.wulkanowy.data.db.migrations.Migration10 import io.github.wulkanowy.data.db.migrations.Migration11 import io.github.wulkanowy.data.db.migrations.Migration12 @@ -93,38 +77,12 @@ import io.github.wulkanowy.data.db.migrations.Migration27 import io.github.wulkanowy.data.db.migrations.Migration28 import io.github.wulkanowy.data.db.migrations.Migration29 import io.github.wulkanowy.data.db.migrations.Migration3 -import io.github.wulkanowy.data.db.migrations.Migration30 -import io.github.wulkanowy.data.db.migrations.Migration31 -import io.github.wulkanowy.data.db.migrations.Migration32 -import io.github.wulkanowy.data.db.migrations.Migration33 -import io.github.wulkanowy.data.db.migrations.Migration34 -import io.github.wulkanowy.data.db.migrations.Migration35 -import io.github.wulkanowy.data.db.migrations.Migration36 -import io.github.wulkanowy.data.db.migrations.Migration37 -import io.github.wulkanowy.data.db.migrations.Migration38 -import io.github.wulkanowy.data.db.migrations.Migration39 import io.github.wulkanowy.data.db.migrations.Migration4 -import io.github.wulkanowy.data.db.migrations.Migration40 -import io.github.wulkanowy.data.db.migrations.Migration41 -import io.github.wulkanowy.data.db.migrations.Migration42 -import io.github.wulkanowy.data.db.migrations.Migration43 -import io.github.wulkanowy.data.db.migrations.Migration44 -import io.github.wulkanowy.data.db.migrations.Migration46 -import io.github.wulkanowy.data.db.migrations.Migration49 import io.github.wulkanowy.data.db.migrations.Migration5 -import io.github.wulkanowy.data.db.migrations.Migration50 -import io.github.wulkanowy.data.db.migrations.Migration51 -import io.github.wulkanowy.data.db.migrations.Migration53 -import io.github.wulkanowy.data.db.migrations.Migration54 -import io.github.wulkanowy.data.db.migrations.Migration55 -import io.github.wulkanowy.data.db.migrations.Migration57 -import io.github.wulkanowy.data.db.migrations.Migration58 import io.github.wulkanowy.data.db.migrations.Migration6 -import io.github.wulkanowy.data.db.migrations.Migration63 import io.github.wulkanowy.data.db.migrations.Migration7 import io.github.wulkanowy.data.db.migrations.Migration8 import io.github.wulkanowy.data.db.migrations.Migration9 -import io.github.wulkanowy.utils.AppInfo import javax.inject.Singleton @Singleton @@ -148,36 +106,12 @@ import javax.inject.Singleton Subject::class, LuckyNumber::class, CompletedLesson::class, - Mailbox::class, + ReportingUnit::class, Recipient::class, MobileDevice::class, Teacher::class, School::class, Conference::class, - TimetableAdditional::class, - StudentInfo::class, - TimetableHeader::class, - SchoolAnnouncement::class, - Notification::class, - AdminMessage::class, - MutedMessageSender::class, - GradeDescriptive::class, - ], - autoMigrations = [ - AutoMigration(from = 44, to = 45), - AutoMigration(from = 46, to = 47), - AutoMigration(from = 47, to = 48), - AutoMigration(from = 51, to = 52), - AutoMigration(from = 54, to = 55, spec = Migration55::class), - AutoMigration(from = 55, to = 56), - AutoMigration(from = 56, to = 57, spec = Migration57::class), - AutoMigration(from = 57, to = 58, spec = Migration58::class), - AutoMigration(from = 58, to = 59), - AutoMigration(from = 59, to = 60), - AutoMigration(from = 60, to = 61), - AutoMigration(from = 61, to = 62), - AutoMigration(from = 62, to = 63, spec = Migration63::class), - AutoMigration(from = 63, to = 64), ], version = AppDatabase.VERSION_SCHEMA, exportSchema = true @@ -186,70 +120,49 @@ import javax.inject.Singleton abstract class AppDatabase : RoomDatabase() { companion object { - const val VERSION_SCHEMA = 64 + const val VERSION_SCHEMA = 29 - fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf( - Migration2(), - Migration3(), - Migration4(), - Migration5(), - Migration6(), - Migration7(), - Migration8(), - Migration9(), - Migration10(), - Migration11(), - Migration12(), - Migration13(), - Migration14(), - Migration15(), - Migration16(), - Migration17(), - Migration18(), - Migration19(sharedPrefProvider), - Migration20(), - Migration21(), - Migration22(), - Migration23(), - Migration24(), - Migration25(), - Migration26(), - Migration27(), - Migration28(), - Migration29(), - Migration30(), - Migration31(), - Migration32(), - Migration33(), - Migration34(), - Migration35(appInfo), - Migration36(), - Migration37(), - Migration38(), - Migration39(), - Migration40(), - Migration41(sharedPrefProvider), - Migration42(), - Migration43(), - Migration44(), - Migration46(), - Migration49(), - Migration50(), - Migration51(), - Migration53(), - Migration54(), - ) + fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array { + return arrayOf( + Migration2(), + Migration3(), + Migration4(), + Migration5(), + Migration6(), + Migration7(), + Migration8(), + Migration9(), + Migration10(), + Migration11(), + Migration12(), + Migration13(), + Migration14(), + Migration15(), + Migration16(), + Migration17(), + Migration18(), + Migration19(sharedPrefProvider), + Migration20(), + Migration21(), + Migration22(), + Migration23(), + Migration24(), + Migration25(), + Migration26(), + Migration27(), + Migration28(), + Migration29() + ) + } - fun newInstance( - context: Context, - sharedPrefProvider: SharedPrefProvider, - appInfo: AppInfo - ) = Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") - .setJournalMode(TRUNCATE) - .fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1) - .fallbackToDestructiveMigrationOnDowngrade() - .addMigrations(*getMigrations(sharedPrefProvider, appInfo)) - .build() + fun newInstance(context: Context, sharedPrefProvider: SharedPrefProvider): AppDatabase { + return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") + .setJournalMode(TRUNCATE) + .fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1) + .fallbackToDestructiveMigrationOnDowngrade() + .addMigrations(*getMigrations(sharedPrefProvider)) + .build() + } } abstract val studentDao: StudentDao @@ -288,7 +201,7 @@ abstract class AppDatabase : RoomDatabase() { abstract val completedLessonsDao: CompletedLessonsDao - abstract val mailboxDao: MailboxDao + abstract val reportingUnitDao: ReportingUnitDao abstract val recipientDao: RecipientDao @@ -299,20 +212,4 @@ abstract class AppDatabase : RoomDatabase() { abstract val schoolDao: SchoolDao abstract val conferenceDao: ConferenceDao - - abstract val timetableAdditionalDao: TimetableAdditionalDao - - abstract val studentInfoDao: StudentInfoDao - - abstract val timetableHeaderDao: TimetableHeaderDao - - abstract val schoolAnnouncementDao: SchoolAnnouncementDao - - abstract val notificationDao: NotificationDao - - abstract val adminMessagesDao: AdminMessageDao - - abstract val mutedMessageSendersDao: MutedMessageSendersDao - - abstract val gradeDescriptiveDao: GradeDescriptiveDao } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt b/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt index 7bc8d12a..def0b371 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/Converters.kt @@ -1,37 +1,47 @@ package io.github.wulkanowy.data.db import androidx.room.TypeConverter -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.utils.toTimestamp -import kotlinx.serialization.SerializationException -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import java.time.* -import java.util.* +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import io.github.wulkanowy.data.db.adapters.PairAdapterFactory import java.time.Instant import java.time.LocalDate +import java.time.LocalDateTime import java.time.Month import java.time.ZoneOffset -import java.util.* +import java.util.Date class Converters { - private val json = Json + private val moshi by lazy { Moshi.Builder().add(PairAdapterFactory).build() } + + private val integerListAdapter by lazy { + moshi.adapter>(Types.newParameterizedType(List::class.java, Integer::class.java)) + } + + private val stringListPairAdapter by lazy { + moshi.adapter>>(Types.newParameterizedType(List::class.java, Pair::class.java, String::class.java, String::class.java)) + } @TypeConverter - fun timestampToLocalDate(value: Long?): LocalDate? = - value?.let(::Date)?.toInstant()?.atZone(ZoneOffset.UTC)?.toLocalDate() + fun timestampToDate(value: Long?): LocalDate? = value?.run { + Date(value).toInstant().atZone(ZoneOffset.UTC).toLocalDate() + } @TypeConverter - fun dateToTimestamp(date: LocalDate?): Long? = date?.toTimestamp() + fun dateToTimestamp(date: LocalDate?): Long? { + return date?.atStartOfDay()?.toInstant(ZoneOffset.UTC)?.toEpochMilli() + } @TypeConverter - fun instantToTimestamp(instant: Instant?): Long? = instant?.toEpochMilli() + fun timestampToTime(value: Long?): LocalDateTime? = value?.let { + LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC) + } @TypeConverter - fun timestampToInstant(timestamp: Long?): Instant? = timestamp?.let(Instant::ofEpochMilli) + fun timeToTimestamp(date: LocalDateTime?): Long? { + return date?.atZone(ZoneOffset.UTC)?.toInstant()?.toEpochMilli() + } @TypeConverter fun monthToInt(month: Month?) = month?.value @@ -41,37 +51,21 @@ class Converters { @TypeConverter fun intListToJson(list: List): String { - return json.encodeToString(list) + return integerListAdapter.toJson(list) } @TypeConverter fun jsonToIntList(value: String): List { - return json.decodeFromString(value) + return integerListAdapter.fromJson(value).orEmpty() } @TypeConverter fun stringPairListToJson(list: List>): String { - return json.encodeToString(list) + return stringListPairAdapter.toJson(list) } @TypeConverter fun jsonToStringPairList(value: String): List> { - return try { - json.decodeFromString(value) - } catch (e: SerializationException) { - emptyList() // handle errors from old gson Pair serialized data - } + return stringListPairAdapter.fromJson(value).orEmpty() } - - @TypeConverter - fun destinationToString(destination: Destination) = json.encodeToString(destination) - - @TypeConverter - fun stringToDestination(destination: String): Destination = json.decodeFromString(destination) - - @TypeConverter - fun messageTypesToString(types: List): String = json.encodeToString(types) - - @TypeConverter - fun stringToMessageTypes(text: String): List = json.decodeFromString(text) } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefProvider.kt b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefProvider.kt index 4929f046..4a4aaf74 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefProvider.kt @@ -6,9 +6,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class SharedPrefProvider @Inject constructor( - private val sharedPref: SharedPreferences -) { +class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) { companion object { const val APP_VERSION_CODE_KEY = "app_version_code" @@ -20,18 +18,9 @@ class SharedPrefProvider @Inject constructor( fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue) - fun getString(key: String) = sharedPref.getString(key, null) + fun getString(key: String, defaultValue: String): String = sharedPref.getString(key, defaultValue) ?: defaultValue - fun getString(key: String, defaultValue: String): String = - sharedPref.getString(key, defaultValue) ?: defaultValue - - fun getBoolean(key: String, defaultValue: Boolean): Boolean = - sharedPref.getBoolean(key, defaultValue) - - fun putBoolean(key: String, value: Boolean, sync: Boolean = false) = - sharedPref.edit(sync) { putBoolean(key, value) } - - fun putString(key: String, value: String?, sync: Boolean = false) { + fun putString(key: String, value: String, sync: Boolean = false) { sharedPref.edit(sync) { putString(key, value) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/adapters/PairAdapterFactory.kt b/app/src/main/java/io/github/wulkanowy/data/db/adapters/PairAdapterFactory.kt new file mode 100644 index 00000000..4a9b168d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/adapters/PairAdapterFactory.kt @@ -0,0 +1,68 @@ +package io.github.wulkanowy.data.db.adapters + +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type + +object PairAdapterFactory : JsonAdapter.Factory { + + override fun create(type: Type, annotations: MutableSet, moshi: Moshi): JsonAdapter<*>? { + if (type !is ParameterizedType || List::class.java != type.rawType) return null + if (type.actualTypeArguments[0] != Pair::class.java) return null + + val listType = Types.newParameterizedType(List::class.java, Map::class.java, String::class.java) + val listAdapter = moshi.adapter>>(listType) + + val mapType = Types.newParameterizedType(MutableMap::class.java, String::class.java, String::class.java) + val mapAdapter = moshi.adapter>(mapType) + + return PairAdapter(listAdapter, mapAdapter) + } + + private class PairAdapter( + private val listAdapter: JsonAdapter>>, + private val mapAdapter: JsonAdapter>, + ) : JsonAdapter>>() { + + override fun toJson(writer: JsonWriter, value: List>?) { + writer.beginArray() + value?.forEach { + writer.beginObject() + writer.name("first").value(it.first) + writer.name("second").value(it.second) + writer.endObject() + } + writer.endArray() + } + + override fun fromJson(reader: JsonReader): List>? { + return if (reader.peek() == JsonReader.Token.BEGIN_OBJECT) deserializeMoshiMap(reader) + else deserializeGsonPair(reader) + } + + // for compatibility with 0.21.0 + private fun deserializeMoshiMap(reader: JsonReader): List>? { + val map = mapAdapter.fromJson(reader) ?: return null + + return map.entries.map { + it.key to it.value + } + } + + private fun deserializeGsonPair(reader: JsonReader): List>? { + val list = listAdapter.fromJson(reader) ?: return null + + return list.map { + require(it.size == 2) { + "pair with more or less than two elements: $list" + } + + it["first"].orEmpty() to it["second"].orEmpty() + } + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/AdminMessageDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/AdminMessageDao.kt deleted file mode 100644 index 6c8d7e47..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/AdminMessageDao.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.AdminMessage -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Singleton -@Dao -interface AdminMessageDao : BaseDao { - - @Query("SELECT * FROM AdminMessages") - fun loadAll(): Flow> -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt index 7d20c9a7..8ef3fd44 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt @@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao import androidx.room.Query import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import kotlinx.coroutines.flow.Flow import java.time.LocalDate import javax.inject.Singleton @@ -12,11 +11,6 @@ import javax.inject.Singleton @Dao interface AttendanceDao : BaseDao { - @Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :start AND date <= :end") - fun loadAll( - diaryId: Int, - studentId: Int, - start: LocalDate, - end: LocalDate - ): Flow> + @Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") + fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt index 937e9824..048e9e3c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt @@ -2,13 +2,11 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Delete import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Transaction import androidx.room.Update interface BaseDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) + @Insert suspend fun insertAll(items: List): List @Update @@ -16,10 +14,4 @@ interface BaseDao { @Delete suspend fun deleteAll(items: List) - - @Transaction - suspend fun removeOldAndSaveNew(oldItems: List, newItems: List) { - deleteAll(oldItems) - insertAll(newItems) - } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt index 097ad7c8..8c03609d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt @@ -12,5 +12,5 @@ import javax.inject.Singleton interface CompletedLessonsDao : BaseDao { @Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun loadAll(studentId: Int, diaryId: Int, from: LocalDate, end: LocalDate): Flow> + fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt index ca9da9ea..4ed9aecf 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ConferenceDao.kt @@ -4,13 +4,12 @@ import androidx.room.Dao import androidx.room.Query import io.github.wulkanowy.data.db.entities.Conference import kotlinx.coroutines.flow.Flow -import java.time.Instant import javax.inject.Singleton @Dao @Singleton interface ConferenceDao : BaseDao { - @Query("SELECT * FROM Conferences WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :startDate") - fun loadAll(diaryId: Int, studentId: Int, startDate: Instant): Flow> + @Query("SELECT * FROM Conferences WHERE diary_id = :diaryId AND student_id = :studentId") + fun loadAll(diaryId: Int, studentId: Int): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt index ff332618..12e70bde 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt @@ -12,8 +12,4 @@ interface GradeDao : BaseDao { @Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId") fun loadAll(semesterId: Int, studentId: Int): Flow> - - @Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId " + - "AND entry NOT IN(:censoredEntries)") - fun loadAllCensored(semesterId: Int, studentId: Int, censoredEntries: Array): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDescriptiveDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDescriptiveDao.kt deleted file mode 100644 index 6282c080..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDescriptiveDao.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.GradeDescriptive -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Singleton -@Dao -interface GradeDescriptiveDao : BaseDao { - - @Query("SELECT * FROM GradesDescriptive WHERE semester_id = :semesterId AND student_id = :studentId") - fun loadAll(semesterId: Int, studentId: Int): Flow> -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt index d9aa2436..57f3005a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt @@ -13,7 +13,4 @@ interface LuckyNumberDao : BaseDao { @Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date") fun load(studentId: Int, date: LocalDate): Flow - - @Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date >= :start AND date <= :end") - fun getAll(studentId: Int, start: LocalDate, end: LocalDate): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt deleted file mode 100644 index 084192a0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.Mailbox -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Singleton -@Dao -interface MailboxDao : BaseDao { - - @Query("SELECT * FROM Mailboxes WHERE email = :email") - suspend fun loadAll(email: String): List - - @Query("SELECT * FROM Mailboxes WHERE email = :email AND symbol = :symbol AND schoolId = :schoolId") - fun loadAll(email: String, symbol: String, schoolId: String): Flow> -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt index 11e6da1e..729ba6a6 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt @@ -5,26 +5,15 @@ import androidx.room.Query import androidx.room.Transaction import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.MessageWithAttachment -import io.github.wulkanowy.data.db.entities.MessageWithMutedAuthor import kotlinx.coroutines.flow.Flow @Dao interface MessagesDao : BaseDao { - @Transaction - @Query("SELECT * FROM Messages WHERE message_global_key = :messageGlobalKey") - fun loadMessageWithAttachment(messageGlobalKey: String): Flow @Transaction - @Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC") - fun loadMessagesWithMutedAuthor(mailboxKey: String, folder: Int): Flow> + @Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId") + fun loadMessageWithAttachment(studentId: Int, messageId: Int): Flow - @Transaction - @Query("SELECT * FROM Messages WHERE email = :email AND folder_id = :folder ORDER BY date DESC") - fun loadMessagesWithMutedAuthor(folder: Int, email: String): Flow> - - @Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC") - fun loadAll(mailboxKey: String, folder: Int): Flow> - - @Query("SELECT * FROM Messages WHERE email = :email AND folder_id = :folder ORDER BY date DESC") - fun loadAll(folder: Int, email: String): Flow> + @Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder ORDER BY date DESC") + fun loadAll(studentId: Int, folder: Int): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt index 5ddb4dd0..8baba2c3 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt @@ -8,6 +8,6 @@ import kotlinx.coroutines.flow.Flow @Dao interface MobileDeviceDao : BaseDao { - @Query("SELECT * FROM MobileDevices WHERE user_login_id = :studentId ORDER BY date DESC") + @Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC") fun loadAll(studentId: Int): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MutedMessageSendersDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MutedMessageSendersDao.kt deleted file mode 100644 index 0a866401..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MutedMessageSendersDao.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.MutedMessageSender - -@Dao -interface MutedMessageSendersDao : BaseDao { - - @Query("SELECT COUNT(*) FROM MutedMessageSenders WHERE author = :author") - suspend fun checkMute(author: String): Boolean - - @Insert(onConflict = OnConflictStrategy.IGNORE) - suspend fun insertMute(mute: MutedMessageSender): Long - - @Query("DELETE FROM MutedMessageSenders WHERE author = :author") - suspend fun deleteMute(author: String) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt index 98de5ba3..e89a4135 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt @@ -9,6 +9,7 @@ import javax.inject.Singleton @Singleton @Dao interface NoteDao : BaseDao { + @Query("SELECT * FROM Notes WHERE student_id = :studentId") fun loadAll(studentId: Int): Flow> } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/NotificationDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/NotificationDao.kt deleted file mode 100644 index c5ae21bc..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/NotificationDao.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.Notification -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Singleton -@Dao -interface NotificationDao : BaseDao { - - @Query("SELECT * FROM Notifications WHERE student_id = :studentId OR student_id = -1") - fun loadAll(studentId: Long): Flow> -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt index 1956261e..419efde0 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt @@ -2,7 +2,6 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao import androidx.room.Query -import io.github.wulkanowy.data.db.entities.MailboxType import io.github.wulkanowy.data.db.entities.Recipient import javax.inject.Singleton @@ -10,6 +9,6 @@ import javax.inject.Singleton @Dao interface RecipientDao : BaseDao { - @Query("SELECT * FROM Recipients WHERE type = :type AND studentMailboxGlobalKey = :studentMailboxGlobalKey") - suspend fun loadAll(type: MailboxType, studentMailboxGlobalKey: String): List + @Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId") + suspend fun load(studentId: Int, role: Int, unitId: Int): List } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt new file mode 100644 index 00000000..ca697eda --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt @@ -0,0 +1,17 @@ +package io.github.wulkanowy.data.db.dao + +import androidx.room.Dao +import androidx.room.Query +import io.github.wulkanowy.data.db.entities.ReportingUnit +import javax.inject.Singleton + +@Singleton +@Dao +interface ReportingUnitDao : BaseDao { + + @Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId") + suspend fun load(studentId: Int): List + + @Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId AND real_id = :unitId") + suspend fun loadOne(studentId: Int, unitId: Int): ReportingUnit? +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolAnnouncementDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolAnnouncementDao.kt deleted file mode 100644 index 64d49bce..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolAnnouncementDao.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Dao -@Singleton -interface SchoolAnnouncementDao : BaseDao { - - @Query("SELECT * FROM SchoolAnnouncements WHERE user_login_id = :studentId ORDER BY date DESC") - fun loadAll(studentId: Int): Flow> -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt index bf9a34d0..4d171907 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt @@ -14,6 +14,6 @@ interface SemesterDao : BaseDao { @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun insertSemesters(items: List): List - @Query("SELECT * FROM Semesters WHERE (student_id = :studentId AND class_id = :classId) OR (student_id = :studentId AND class_id = 0)") + @Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId") suspend fun loadAll(studentId: Int, classId: Int): List } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt index 5302b320..d7237ea8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt @@ -3,69 +3,39 @@ package io.github.wulkanowy.data.db.dao import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert -import androidx.room.OnConflictStrategy +import androidx.room.OnConflictStrategy.ABORT import androidx.room.Query import androidx.room.Transaction -import androidx.room.Update -import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentIsAuthorized -import io.github.wulkanowy.data.db.entities.StudentIsEduOne -import io.github.wulkanowy.data.db.entities.StudentName -import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import javax.inject.Singleton @Singleton @Dao -abstract class StudentDao { +interface StudentDao { - @Insert(onConflict = OnConflictStrategy.ABORT) - abstract suspend fun insertAll(student: List): List + @Insert(onConflict = ABORT) + suspend fun insertAll(student: List): List @Delete - abstract suspend fun delete(student: Student) - - @Update(entity = Student::class) - abstract suspend fun update(studentIsAuthorized: StudentIsAuthorized) - - @Update(entity = Student::class) - abstract suspend fun update(studentIsEduOne: StudentIsEduOne) - - @Update(entity = Student::class) - abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar) - - @Update(entity = Student::class) - abstract suspend fun update(studentName: StudentName) + suspend fun delete(student: Student) @Query("SELECT * FROM Students WHERE is_current = 1") - abstract suspend fun loadCurrent(): Student? + suspend fun loadCurrent(): Student? @Query("SELECT * FROM Students WHERE id = :id") - abstract suspend fun loadById(id: Long): Student? + suspend fun loadById(id: Int): Student? @Query("SELECT * FROM Students") - abstract suspend fun loadAll(): List + suspend fun loadAll(): List @Transaction - @Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0)") - abstract suspend fun loadStudentsWithSemesters(): Map> - - @Transaction - @Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0) WHERE Students.id = :id") - abstract suspend fun loadStudentWithSemestersById(id: Long): Map> + @Query("SELECT * FROM Students") + suspend fun loadStudentsWithSemesters(): List @Query("UPDATE Students SET is_current = 1 WHERE id = :id") - abstract suspend fun updateCurrent(id: Long) + suspend fun updateCurrent(id: Long) @Query("UPDATE Students SET is_current = 0") - abstract suspend fun resetCurrent() - - @Query("DELETE FROM Students WHERE email = :email AND user_name = :userName") - abstract suspend fun deleteByEmailAndUserName(email: String, userName: String) - - @Transaction - open suspend fun switchCurrent(id: Long) { - resetCurrent() - updateCurrent(id) - } + suspend fun resetCurrent() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentInfoDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentInfoDao.kt deleted file mode 100644 index 5ec86af1..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentInfoDao.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.StudentInfo -import kotlinx.coroutines.flow.Flow -import javax.inject.Singleton - -@Singleton -@Dao -interface StudentInfoDao : BaseDao { - - @Query("SELECT * FROM StudentInfo WHERE student_id = :studentId") - fun loadStudentInfo(studentId: Int): Flow -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableAdditionalDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableAdditionalDao.kt deleted file mode 100644 index 914ce340..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableAdditionalDao.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import kotlinx.coroutines.flow.Flow -import java.time.LocalDate -import java.util.UUID -import javax.inject.Singleton - -@Dao -@Singleton -interface TimetableAdditionalDao : BaseDao { - - @Query("SELECT * FROM TimetableAdditional WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun loadAll( - diaryId: Int, - studentId: Int, - from: LocalDate, - end: LocalDate - ): Flow> - - @Query("DELETE FROM TimetableAdditional WHERE repeat_id = :repeatId") - suspend fun deleteAllByRepeatId(repeatId: UUID) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt index 40d97ea9..5e6eec66 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt @@ -13,7 +13,4 @@ interface TimetableDao : BaseDao { @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow> - - @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - suspend fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableHeaderDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableHeaderDao.kt deleted file mode 100644 index 916d1901..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableHeaderDao.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.wulkanowy.data.db.dao - -import androidx.room.Dao -import androidx.room.Query -import io.github.wulkanowy.data.db.entities.TimetableHeader -import kotlinx.coroutines.flow.Flow -import java.time.LocalDate -import javax.inject.Singleton - -@Dao -@Singleton -interface TimetableHeaderDao : BaseDao { - - @Query("SELECT * FROM TimetableHeaders WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") - fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Flow> -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/AdminMessage.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/AdminMessage.kt deleted file mode 100644 index a8604c5c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/AdminMessage.kt +++ /dev/null @@ -1,49 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.serializers.SafeMessageTypeEnumListSerializer -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -@Entity(tableName = "AdminMessages") -data class AdminMessage( - - @PrimaryKey - val id: Int, - - val title: String, - - val content: String, - - @ColumnInfo(name = "version_name") - val versionMin: Int? = null, - - @ColumnInfo(name = "version_max") - val versionMax: Int? = null, - - @ColumnInfo(name = "target_register_host") - val targetRegisterHost: String? = null, - - @ColumnInfo(name = "target_flavor") - val targetFlavor: String? = null, - - @ColumnInfo(name = "destination_url") - val destinationUrl: String? = null, - - val priority: String, - - @SerialName("messageTypes") - @Serializable(with = SafeMessageTypeEnumListSerializer::class) - @ColumnInfo(name = "types", defaultValue = "[]") - val types: List = emptyList(), - - @ColumnInfo(name = "is_ok_visible", defaultValue = "0") - val isOkVisible: Boolean = false, - - @ColumnInfo(name = "is_x_visible", defaultValue = "0") - val isXVisible: Boolean = false -) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt index b40dd52e..f141d5d5 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Attendance.kt @@ -47,7 +47,4 @@ data class Attendance( @PrimaryKey(autoGenerate = true) var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt index ba3958db..8ddcbbb0 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Conference.kt @@ -4,7 +4,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.Instant +import java.time.LocalDateTime @Entity(tableName = "Conferences") data class Conference( @@ -27,12 +27,9 @@ data class Conference( @ColumnInfo(name = "conference_id") val conferenceId: Int, - val date: Instant, + val date: LocalDateTime ) : Serializable { @PrimaryKey(autoGenerate = true) var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt index 2292c3e6..50ed343a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Exam.kt @@ -22,7 +22,6 @@ data class Exam( val subject: String, - @Deprecated("not available anymore") val group: String, val type: String, @@ -37,7 +36,4 @@ data class Exam( @PrimaryKey(autoGenerate = true) var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeDescriptive.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeDescriptive.kt deleted file mode 100644 index 9aec9599..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeDescriptive.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable - -@Entity(tableName = "GradesDescriptive") -data class GradeDescriptive( - - @ColumnInfo(name = "semester_id") - val semesterId: Int, - - @ColumnInfo(name = "student_id") - val studentId: Int, - - val subject: String, - - val description: String, -) : Serializable { - - @PrimaryKey(autoGenerate = true) - var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSemesterStatistics.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSemesterStatistics.kt index 9e08b86b..e747271c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSemesterStatistics.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSemesterStatistics.kt @@ -24,8 +24,5 @@ data class GradeSemesterStatistics( var id: Long = 0 @Transient - var classAverage: String = "" - - @Transient - var studentAverage: String = "" + var average: String = "" } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt index f8a357a3..fb7b60bb 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt @@ -3,7 +3,7 @@ package io.github.wulkanowy.data.db.entities import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey -import java.time.Instant +import java.time.LocalDateTime @Entity(tableName = "GradesSummary") data class GradeSummary( @@ -33,13 +33,7 @@ data class GradeSummary( @ColumnInfo(name = "points_sum") val pointsSum: String, - @ColumnInfo(name = "points_sum_all_year") - val pointsSumAllYear: String?, - - val average: Double, - - @ColumnInfo(name = "average_all_year") - val averageAllYear: Double? = null, + val average: Double ) { @PrimaryKey(autoGenerate = true) var id: Long = 0 @@ -51,8 +45,8 @@ data class GradeSummary( var isFinalGradeNotified: Boolean = true @ColumnInfo(name = "predicted_grade_last_change") - var predictedGradeLastChange: Instant = Instant.now() + var predictedGradeLastChange: LocalDateTime = LocalDateTime.now() @ColumnInfo(name = "final_grade_last_change") - var finalGradeLastChange: Instant = Instant.now() + var finalGradeLastChange: LocalDateTime = LocalDateTime.now() } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Homework.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Homework.kt index 4538cf31..5b21445b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Homework.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Homework.kt @@ -37,10 +37,4 @@ data class Homework( @ColumnInfo(name = "is_done") var isDone: Boolean = false - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true - - @ColumnInfo(name = "is_added_by_user") - var isAddedByUser: Boolean = false } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt deleted file mode 100644 index e65e213d..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import android.os.Parcelable -import androidx.room.Entity -import androidx.room.PrimaryKey -import kotlinx.parcelize.Parcelize - -@Parcelize -@Entity(tableName = "Mailboxes") -data class Mailbox( - - @PrimaryKey - val globalKey: String, - - val email: String, - val symbol: String, - val schoolId: String, - - val fullName: String, - val userName: String, - val studentName: String, - val schoolNameShort: String, - val type: MailboxType, -) : java.io.Serializable, Parcelable - -enum class MailboxType { - STUDENT, - PARENT, - GUARDIAN, - EMPLOYEE, - UNKNOWN, -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt index d1356b33..1f10a164 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt @@ -4,39 +4,39 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.Instant +import java.time.LocalDateTime @Entity(tableName = "Messages") data class Message( - @ColumnInfo(name = "email") - val email: String, + @ColumnInfo(name = "student_id") + val studentId: Int, - @ColumnInfo(name = "message_global_key") - val messageGlobalKey: String, - - @ColumnInfo(name = "mailbox_key") - val mailboxKey: String, + @ColumnInfo(name = "real_id") + val realId: Int, @ColumnInfo(name = "message_id") val messageId: Int, - val correspondents: String, + @ColumnInfo(name = "sender_name") + val sender: String, + + @ColumnInfo(name = "sender_id") + val senderId: Int, + + @ColumnInfo(name = "recipient_name") + val recipient: String, val subject: String, - val date: Instant, + val date: LocalDateTime, @ColumnInfo(name = "folder_id") val folderId: Int, var unread: Boolean, - @ColumnInfo(name = "read_by") - val readBy: Int?, - - @ColumnInfo(name = "unread_by") - val unreadBy: Int?, + val removed: Boolean, @ColumnInfo(name = "has_attachments") val hasAttachments: Boolean @@ -48,7 +48,11 @@ data class Message( @ColumnInfo(name = "is_notified") var isNotified: Boolean = true + @ColumnInfo(name = "unread_by") + var unreadBy: Int = 0 + + @ColumnInfo(name = "read_by") + var readBy: Int = 0 + var content: String = "" - var sender: String? = null - var recipients: String? = null } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageAttachment.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageAttachment.kt index 6f0c84ad..d1886e91 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageAttachment.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageAttachment.kt @@ -2,16 +2,21 @@ package io.github.wulkanowy.data.db.entities import androidx.room.ColumnInfo import androidx.room.Entity +import androidx.room.PrimaryKey import java.io.Serializable -@Entity( - tableName = "MessageAttachments", - primaryKeys = ["message_global_key", "url", "filename"], -) +@Entity(tableName = "MessageAttachments") data class MessageAttachment( - @ColumnInfo(name = "message_global_key") - val messageGlobalKey: String, + @PrimaryKey + @ColumnInfo(name = "real_id") + val realId: Int, + + @ColumnInfo(name = "message_id") + val messageId: Int, + + @ColumnInfo(name = "one_drive_id") + val oneDriveId: String, @ColumnInfo(name = "url") val url: String, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithAttachment.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithAttachment.kt index fc890e76..2e7af0f4 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithAttachment.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithAttachment.kt @@ -2,15 +2,11 @@ package io.github.wulkanowy.data.db.entities import androidx.room.Embedded import androidx.room.Relation -import java.io.Serializable data class MessageWithAttachment( @Embedded val message: Message, - @Relation(parentColumn = "message_global_key", entityColumn = "message_global_key") - val attachments: List, - - @Relation(parentColumn = "correspondents", entityColumn = "author") - val mutedMessageSender: MutedMessageSender?, -) : Serializable + @Relation(parentColumn = "message_id", entityColumn = "message_id") + val attachments: List +) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithMutedAuthor.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithMutedAuthor.kt deleted file mode 100644 index e3cd1ca7..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MessageWithMutedAuthor.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.Embedded -import androidx.room.Relation - -data class MessageWithMutedAuthor( - @Embedded - val message: Message, - - @Relation(parentColumn = "correspondents", entityColumn = "author") - val mutedMessageSender: MutedMessageSender?, -) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt index 44e90064..9d8f1162 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/MobileDevice.kt @@ -4,12 +4,12 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.Instant +import java.time.LocalDateTime @Entity(tableName = "MobileDevices") data class MobileDevice( - @ColumnInfo(name = "user_login_id") // todo: change column name + @ColumnInfo(name = "student_id") val studentId: Int, @ColumnInfo(name = "device_id") @@ -17,7 +17,7 @@ data class MobileDevice( val name: String, - val date: Instant, + val date: LocalDateTime ) : Serializable { @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/MutedMessageSender.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/MutedMessageSender.kt deleted file mode 100644 index f1770e64..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/MutedMessageSender.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable - -@Entity(tableName = "MutedMessageSenders") -data class MutedMessageSender( - @ColumnInfo(name = "author") - val author: String, -) : Serializable { - @PrimaryKey(autoGenerate = true) - var id: Long = 0 -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt deleted file mode 100644 index c3267f24..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Notification.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import io.github.wulkanowy.services.sync.notifications.NotificationType -import io.github.wulkanowy.ui.modules.Destination -import java.time.Instant - -@Entity(tableName = "Notifications") -data class Notification( - - @ColumnInfo(name = "student_id") - val studentId: Long, - - val title: String, - - val content: String, - - val type: NotificationType, - - @ColumnInfo(defaultValue = "{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}") - val destination: Destination, - - val date: Instant, - - val data: String? = null -) { - @PrimaryKey(autoGenerate = true) - var id: Long = 0 -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Recipient.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Recipient.kt index d09742cd..3021da72 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Recipient.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Recipient.kt @@ -1,22 +1,38 @@ package io.github.wulkanowy.data.db.entities +import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -@kotlinx.serialization.Serializable @Entity(tableName = "Recipients") data class Recipient( - val mailboxGlobalKey: String, - val studentMailboxGlobalKey: String, - val fullName: String, - val userName: String, - val schoolShortName: String, - val type: MailboxType, + + @ColumnInfo(name = "student_id") + val studentId: Int, + + @ColumnInfo(name = "real_id") + val realId: String, + + val name: String, + + @ColumnInfo(name = "real_name") + val realName: String, + + @ColumnInfo(name = "login_id") + val loginId: Int, + + @ColumnInfo(name = "unit_id") + val unitId: Int, + + val role: Int, + + val hash: String + ) : Serializable { @PrimaryKey(autoGenerate = true) var id: Long = 0 - override fun toString() = userName + override fun toString() = name } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/ReportingUnit.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/ReportingUnit.kt new file mode 100644 index 00000000..601d8aac --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/ReportingUnit.kt @@ -0,0 +1,32 @@ +package io.github.wulkanowy.data.db.entities + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import java.io.Serializable + +@Entity(tableName = "ReportingUnits") +data class ReportingUnit( + + @ColumnInfo(name = "student_id") + val studentId: Int, + + @ColumnInfo(name = "real_id") + val realId: Int, + + @ColumnInfo(name = "short") + val shortName: String, + + @ColumnInfo(name = "sender_id") + val senderId: Int, + + @ColumnInfo(name = "sender_name") + val senderName: String, + + val roles: List + +) : Serializable { + + @PrimaryKey(autoGenerate = true) + var id: Long = 0 +} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/SchoolAnnouncement.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/SchoolAnnouncement.kt deleted file mode 100644 index 814a3c8d..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/SchoolAnnouncement.kt +++ /dev/null @@ -1,29 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable -import java.time.LocalDate - -@Entity(tableName = "SchoolAnnouncements") -data class SchoolAnnouncement( - - @ColumnInfo(name = "user_login_id") // todo: change column name - val studentId: Int, - - val date: LocalDate, - - val subject: String, - - val content: String, - - val author: String? = null, -) : Serializable { - - @PrimaryKey(autoGenerate = true) - var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt index 187890c9..3b1f0add 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Semester.kt @@ -7,12 +7,7 @@ import androidx.room.PrimaryKey import java.io.Serializable import java.time.LocalDate -@Entity( - tableName = "Semesters", indices = [Index( - value = ["student_id", "diary_id", "kindergarten_diary_id", "semester_id"], - unique = true - )] -) +@Entity(tableName = "Semesters", indices = [Index(value = ["student_id", "diary_id", "semester_id"], unique = true)]) data class Semester( @ColumnInfo(name = "student_id") @@ -21,9 +16,6 @@ data class Semester( @ColumnInfo(name = "diary_id") val diaryId: Int, - @ColumnInfo(name = "kindergarten_diary_id", defaultValue = "0") - val kindergartenDiaryId: Int, - @ColumnInfo(name = "diary_name") val diaryName: String, @@ -45,11 +37,12 @@ data class Semester( @ColumnInfo(name = "unit_id") val unitId: Int -) : Serializable { +): Serializable { @PrimaryKey(autoGenerate = true) var id: Long = 0 + @ColumnInfo(name = "is_current") var current: Boolean = false } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt index 0300506a..b6c75ff8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Student.kt @@ -5,23 +5,14 @@ import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey import java.io.Serializable -import java.time.Instant +import java.time.LocalDateTime -@Entity( - tableName = "Students", - indices = [Index( - value = ["email", "symbol", "student_id", "school_id", "class_id"], - unique = true - )] -) +@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id", "class_id"], unique = true)]) data class Student( @ColumnInfo(name = "scrapper_base_url") val scrapperBaseUrl: String, - @ColumnInfo(name = "scrapper_domain_suffix", defaultValue = "") - val scrapperDomainSuffix: String, - @ColumnInfo(name = "mobile_base_url") val mobileBaseUrl: String, @@ -49,7 +40,6 @@ data class Student( @ColumnInfo(name = "student_id") val studentId: Int, - @Deprecated("not available in VULCAN anymore") @ColumnInfo(name = "user_login_id") val userLoginId: Int, @@ -62,7 +52,7 @@ data class Student( @ColumnInfo(name = "school_id") val schoolSymbol: String, - @ColumnInfo(name = "school_short") + @ColumnInfo(name ="school_short") val schoolShortName: String, @ColumnInfo(name = "school_name") @@ -78,40 +68,9 @@ data class Student( val isCurrent: Boolean, @ColumnInfo(name = "registration_date") - val registrationDate: Instant, - - @ColumnInfo(name = "is_authorized", defaultValue = "0") - val isAuthorized: Boolean, - - @ColumnInfo(name = "is_edu_one", defaultValue = "NULL") - val isEduOne: Boolean?, - + val registrationDate: LocalDateTime ) : Serializable { @PrimaryKey(autoGenerate = true) var id: Long = 0 - - var nick = "" - - @ColumnInfo(name = "avatar_color") - var avatarColor = 0L } - -@Entity -data class StudentIsAuthorized( - - @PrimaryKey - var id: Long, - - @ColumnInfo(name = "is_authorized", defaultValue = "NULL") - val isAuthorized: Boolean?, -) : Serializable - -@Entity -data class StudentIsEduOne( - @PrimaryKey - var id: Long, - - @ColumnInfo(name = "is_edu_one", defaultValue = "NULL") - val isEduOne: Boolean?, -) : Serializable diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentInfo.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentInfo.kt deleted file mode 100644 index 7366e547..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentInfo.kt +++ /dev/null @@ -1,85 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Embedded -import androidx.room.Entity -import androidx.room.PrimaryKey -import io.github.wulkanowy.data.enums.Gender -import java.io.Serializable -import java.time.LocalDate - -@Entity(tableName = "StudentInfo") -data class StudentInfo( - - @ColumnInfo(name = "student_id") - val studentId: Int, - - @ColumnInfo(name = "full_name") - val fullName: String, - - @ColumnInfo(name = "first_name") - val firstName: String, - - @ColumnInfo(name = "second_name") - val secondName: String, - - val surname: String, - - @ColumnInfo(name = "birth_date") - val birthDate: LocalDate, - - @ColumnInfo(name = "birth_place") - val birthPlace: String, - - val gender: Gender, - - @ColumnInfo(name = "has_polish_citizenship") - val hasPolishCitizenship: Boolean, - - @ColumnInfo(name = "family_name") - val familyName: String, - - @ColumnInfo(name = "parents_names") - val parentsNames: String, - - val address: String, - - @ColumnInfo(name = "registered_address") - val registeredAddress: String, - - @ColumnInfo(name = "correspondence_address") - val correspondenceAddress: String, - - @ColumnInfo(name = "phone_number") - val phoneNumber: String, - - @ColumnInfo(name = "cell_phone_number") - val cellPhoneNumber: String, - - val email: String, - - @Embedded(prefix = "first_guardian_") - val firstGuardian: StudentGuardian?, - - @Embedded(prefix = "second_guardian_") - val secondGuardian: StudentGuardian? - -) : Serializable { - - @PrimaryKey(autoGenerate = true) - var id: Long = 0 -} - -data class StudentGuardian( - - @ColumnInfo(name = "full_name") - val fullName: String, - - val kinship: String, - - val address: String, - - val phones: String, - - val email: String -) : Serializable diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentName.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentName.kt deleted file mode 100644 index 46f754b5..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentName.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable - -@Entity -data class StudentName( - - @ColumnInfo(name = "student_name") - val studentName: String - -) : Serializable { - - @PrimaryKey - var id: Long = 0 -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentNickAndAvatar.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentNickAndAvatar.kt deleted file mode 100644 index 546059ee..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentNickAndAvatar.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable - -@Entity -data class StudentNickAndAvatar( - - val nick: String, - - @ColumnInfo(name = "avatar_color") - var avatarColor: Long - -) : Serializable { - - @PrimaryKey - var id: Long = 0 -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentWithSemesters.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentWithSemesters.kt index f9869d4e..9362a954 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentWithSemesters.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/StudentWithSemesters.kt @@ -1,8 +1,13 @@ package io.github.wulkanowy.data.db.entities +import androidx.room.Embedded +import androidx.room.Relation import java.io.Serializable data class StudentWithSemesters( + @Embedded val student: Student, + + @Relation(parentColumn = "student_id", entityColumn = "student_id") val semesters: List ) : Serializable diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt index d23d388f..1bf159ef 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Timetable.kt @@ -4,8 +4,8 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import java.io.Serializable -import java.time.Instant import java.time.LocalDate +import java.time.LocalDateTime @Entity(tableName = "Timetable") data class Timetable( @@ -18,9 +18,9 @@ data class Timetable( val number: Int, - val start: Instant, + val start: LocalDateTime, - val end: Instant, + val end: LocalDateTime, val date: LocalDate, @@ -50,7 +50,4 @@ data class Timetable( @PrimaryKey(autoGenerate = true) var id: Long = 0 - - @ColumnInfo(name = "is_notified") - var isNotified: Boolean = true } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt deleted file mode 100644 index 47802610..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableAdditional.kt +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable -import java.time.Instant -import java.time.LocalDate -import java.util.* - -@Entity(tableName = "TimetableAdditional") -data class TimetableAdditional( - - @ColumnInfo(name = "student_id") - val studentId: Int, - - @ColumnInfo(name = "diary_id") - val diaryId: Int, - - val start: Instant, - - val end: Instant, - - val date: LocalDate, - - val subject: String, -) : Serializable { - - @PrimaryKey(autoGenerate = true) - var id: Long = 0 - - @ColumnInfo(name = "repeat_id", defaultValue = "NULL") - var repeatId: UUID? = null - - @ColumnInfo(name = "is_added_by_user", defaultValue = "0") - var isAddedByUser: Boolean = false -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableHeader.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableHeader.kt deleted file mode 100644 index 7f21bf54..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/entities/TimetableHeader.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.wulkanowy.data.db.entities - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey -import java.io.Serializable -import java.time.LocalDate - -@Entity(tableName = "TimetableHeaders") -data class TimetableHeader( - - @ColumnInfo(name = "student_id") - val studentId: Int, - - @ColumnInfo(name = "diary_id") - val diaryId: Int, - - val date: LocalDate, - - val content: String, -) : Serializable { - - @PrimaryKey(autoGenerate = true) - var id: Long = 0 -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt index 0e7e1409..c26a02d1 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration10.kt @@ -5,7 +5,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration10 : Migration(9, 10) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Grades_Summary RENAME TO GradesSummary") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Grades_Summary RENAME TO GradesSummary") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration11.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration11.kt index 342e2e2e..6d129bca 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration11.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration11.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration11 : Migration(10, 11) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS Grades_temp ( id INTEGER PRIMARY KEY NOT NULL, is_read INTEGER NOT NULL, @@ -27,10 +26,9 @@ class Migration11 : Migration(10, 11) { date INTEGER NOT NULL, teacher TEXT NOT NULL ) - """ - ) - db.execSQL("INSERT INTO Grades_temp SELECT * FROM Grades") - db.execSQL("DROP TABLE Grades") - db.execSQL("ALTER TABLE Grades_temp RENAME TO Grades") + """) + database.execSQL("INSERT INTO Grades_temp SELECT * FROM Grades") + database.execSQL("DROP TABLE Grades") + database.execSQL("ALTER TABLE Grades_temp RENAME TO Grades") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt index 6cc72695..1dc38e14 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration12.kt @@ -5,17 +5,16 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration12 : Migration(11, 12) { - override fun migrate(db: SupportSQLiteDatabase) { - createTempStudentsTable(db) - replaceStudentTable(db) - updateStudentsWithClassId(db, getStudentsIds(db)) - removeStudentsWithNoClassId(db) - ensureThereIsOnlyOneCurrentStudent(db) + override fun migrate(database: SupportSQLiteDatabase) { + createTempStudentsTable(database) + replaceStudentTable(database) + updateStudentsWithClassId(database, getStudentsIds(database)) + removeStudentsWithNoClassId(database) + ensureThereIsOnlyOneCurrentStudent(database) } - private fun createTempStudentsTable(db: SupportSQLiteDatabase) { - db.execSQL( - """ + private fun createTempStudentsTable(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS Students_tmp ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, endpoint TEXT NOT NULL, @@ -31,43 +30,40 @@ class Migration12 : Migration(11, 12) { registration_date INTEGER NOT NULL, class_id INTEGER NOT NULL ) - """ - ) - db.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students_tmp (email, symbol, student_id, school_id, class_id)") + """) + database.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students_tmp (email, symbol, student_id, school_id, class_id)") } - private fun replaceStudentTable(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") - db.execSQL("INSERT INTO Students_tmp SELECT * FROM Students") - db.execSQL("DROP TABLE Students") - db.execSQL("ALTER TABLE Students_tmp RENAME TO Students") + private fun replaceStudentTable(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Students ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") + database.execSQL("INSERT INTO Students_tmp SELECT * FROM Students") + database.execSQL("DROP TABLE Students") + database.execSQL("ALTER TABLE Students_tmp RENAME TO Students") } private fun getStudentsIds(database: SupportSQLiteDatabase): List { val students = mutableListOf() - database.query("SELECT student_id FROM Students").use { - if (it.moveToFirst()) { - do { - students.add(it.getInt(0)) - } while (it.moveToNext()) - } + val studentsCursor = database.query("SELECT student_id FROM Students") + if (studentsCursor.moveToFirst()) { + do { + students.add(studentsCursor.getInt(0)) + } while (studentsCursor.moveToNext()) } - return students } - private fun updateStudentsWithClassId(db: SupportSQLiteDatabase, students: List) { + private fun updateStudentsWithClassId(database: SupportSQLiteDatabase, students: List) { students.forEach { - db.execSQL("UPDATE Students SET class_id = IFNULL((SELECT class_id FROM Semesters WHERE student_id = $it), 0) WHERE student_id = $it") + database.execSQL("UPDATE Students SET class_id = IFNULL((SELECT class_id FROM Semesters WHERE student_id = $it), 0) WHERE student_id = $it") } } - private fun removeStudentsWithNoClassId(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Students WHERE class_id = 0") + private fun removeStudentsWithNoClassId(database: SupportSQLiteDatabase) { + database.execSQL("DELETE FROM Students WHERE class_id = 0") } - private fun ensureThereIsOnlyOneCurrentStudent(db: SupportSQLiteDatabase) { - db.execSQL("UPDATE Students SET is_current = 0") - db.execSQL("UPDATE Students SET is_current = 1 WHERE id = (SELECT MAX(id) FROM Students)") + private fun ensureThereIsOnlyOneCurrentStudent(database: SupportSQLiteDatabase) { + database.execSQL("UPDATE Students SET is_current = 0") + database.execSQL("UPDATE Students SET is_current = 1 WHERE id = (SELECT MAX(id) FROM Students)") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt index c5030232..0cf8cd9b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration13.kt @@ -5,70 +5,60 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration13 : Migration(12, 13) { - override fun migrate(db: SupportSQLiteDatabase) { - addClassNameToStudents(db, getStudentsIds(db)) - updateSemestersTable(db) - markAtLeastAndOnlyOneSemesterAtCurrent(db, getStudentsAndClassIds(db)) - clearMessagesTable(db) + override fun migrate(database: SupportSQLiteDatabase) { + addClassNameToStudents(database, getStudentsIds(database)) + updateSemestersTable(database) + markAtLeastAndOnlyOneSemesterAtCurrent(database, getStudentsAndClassIds(database)) + clearMessagesTable(database) } - private fun addClassNameToStudents( - db: SupportSQLiteDatabase, - students: List> - ) { - db.execSQL("ALTER TABLE Students ADD COLUMN class_name TEXT DEFAULT \"\" NOT NULL") + private fun addClassNameToStudents(database: SupportSQLiteDatabase, students: List>) { + database.execSQL("ALTER TABLE Students ADD COLUMN class_name TEXT DEFAULT \"\" NOT NULL") students.forEach { (id, name) -> val schoolName = name.substringAfter(" - ") val className = name.substringBefore(" - ", "").replace("Klasa ", "") - db.execSQL("UPDATE Students SET class_name = '$className' WHERE id = '$id'") - db.execSQL("UPDATE Students SET school_name = '$schoolName' WHERE id = '$id'") + database.execSQL("UPDATE Students SET class_name = '$className' WHERE id = '$id'") + database.execSQL("UPDATE Students SET school_name = '$schoolName' WHERE id = '$id'") } } - private fun getStudentsIds(db: SupportSQLiteDatabase): MutableList> { + private fun getStudentsIds(database: SupportSQLiteDatabase): MutableList> { val students = mutableListOf>() - db.query("SELECT id, school_name FROM Students").use { - if (it.moveToFirst()) { - do { - students.add(it.getInt(0) to it.getString(1)) - } while (it.moveToNext()) - } + val studentsCursor = database.query("SELECT id, school_name FROM Students") + if (studentsCursor.moveToFirst()) { + do { + students.add(studentsCursor.getInt(0) to studentsCursor.getString(1)) + } while (studentsCursor.moveToNext()) } - return students } - private fun updateSemestersTable(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Semesters ADD COLUMN school_year INTEGER DEFAULT 1970 NOT NULL") - db.execSQL("ALTER TABLE Semesters ADD COLUMN start INTEGER DEFAULT 0 NOT NULL") - db.execSQL("ALTER TABLE Semesters ADD COLUMN `end` INTEGER DEFAULT 0 NOT NULL") + private fun updateSemestersTable(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Semesters ADD COLUMN school_year INTEGER DEFAULT 1970 NOT NULL") + database.execSQL("ALTER TABLE Semesters ADD COLUMN start INTEGER DEFAULT 0 NOT NULL") + database.execSQL("ALTER TABLE Semesters ADD COLUMN `end` INTEGER DEFAULT 0 NOT NULL") } - private fun getStudentsAndClassIds(db: SupportSQLiteDatabase): List> { + private fun getStudentsAndClassIds(database: SupportSQLiteDatabase): List> { val students = mutableListOf>() - db.query("SELECT student_id, class_id FROM Students").use { - if (it.moveToFirst()) { - do { - students.add(it.getInt(0) to it.getInt(1)) - } while (it.moveToNext()) - } + val studentsCursor = database.query("SELECT student_id, class_id FROM Students") + if (studentsCursor.moveToFirst()) { + do { + students.add(studentsCursor.getInt(0) to studentsCursor.getInt(1)) + } while (studentsCursor.moveToNext()) } - return students } - private fun markAtLeastAndOnlyOneSemesterAtCurrent( - db: SupportSQLiteDatabase, - students: List> - ) { + private fun markAtLeastAndOnlyOneSemesterAtCurrent(database: SupportSQLiteDatabase, students: List>) { students.forEach { (studentId, classId) -> - db.execSQL("UPDATE Semesters SET is_current = 0 WHERE student_id = '$studentId' AND class_id = '$classId'") - db.execSQL("UPDATE Semesters SET is_current = 1 WHERE id = (SELECT id FROM Semesters WHERE student_id = '$studentId' AND class_id = '$classId' ORDER BY semester_id DESC)") + database.execSQL("UPDATE Semesters SET is_current = 0 WHERE student_id = '$studentId' AND class_id = '$classId'") + database.execSQL("UPDATE Semesters SET is_current = 1 WHERE id = (SELECT id FROM Semesters WHERE student_id = '$studentId' AND class_id = '$classId' ORDER BY semester_id DESC)") } } - private fun clearMessagesTable(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Messages") + private fun clearMessagesTable(database: SupportSQLiteDatabase) { + database.execSQL("DELETE FROM Messages") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration14.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration14.kt index 793b4a9d..4dac0d30 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration14.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration14.kt @@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration14 : Migration(13, 14) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS GradesSummary") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE IF EXISTS GradesSummary") + database.execSQL(""" CREATE TABLE IF NOT EXISTS GradesSummary ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, semester_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration15.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration15.kt index 5ff44e9c..5be49a95 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration15.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration15.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration15 : Migration(14, 15) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS MobileDevices ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, @@ -15,7 +14,6 @@ class Migration15 : Migration(14, 15) { name TEXT NOT NULL, date INTEGER NOT NULL ) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration16.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration16.kt index 8a8f5b8f..7f40c0f8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration16.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration16.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration16 : Migration(15, 16) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS Teachers ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, @@ -16,7 +15,6 @@ class Migration16 : Migration(15, 16) { name TEXT NOT NULL, short_name TEXT NOT NULL ) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration17.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration17.kt index cf3318ad..e2a2574d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration17.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration17.kt @@ -5,14 +5,13 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration17 : Migration(16, 17) { - override fun migrate(db: SupportSQLiteDatabase) { - createGradesPointsStatisticsTable(db) - truncateSemestersTable(db) + override fun migrate(database: SupportSQLiteDatabase) { + createGradesPointsStatisticsTable(database) + truncateSemestersTable(database) } - private fun createGradesPointsStatisticsTable(db: SupportSQLiteDatabase) { - db.execSQL( - """ + private fun createGradesPointsStatisticsTable(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS GradesPointsStatistics( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, @@ -21,11 +20,10 @@ class Migration17 : Migration(16, 17) { others REAL NOT NULL, student REAL NOT NULL ) - """ - ) + """) } - private fun truncateSemestersTable(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Semesters") + private fun truncateSemestersTable(database: SupportSQLiteDatabase) { + database.execSQL("DELETE FROM Semesters") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt index 713f8e72..6c5e56c6 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration18.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration18 : Migration(17, 18) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS School ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration19.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration19.kt index 021cdbb3..d38f1245 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration19.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration19.kt @@ -6,17 +6,16 @@ import io.github.wulkanowy.data.db.SharedPrefProvider class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migration(18, 19) { - override fun migrate(db: SupportSQLiteDatabase) { - migrateMessages(db) - migrateGrades(db) - migrateStudents(db) + override fun migrate(database: SupportSQLiteDatabase) { + migrateMessages(database) + migrateGrades(database) + migrateStudents(database) migrateSharedPreferences() } - private fun migrateMessages(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE Messages") - db.execSQL( - """ + private fun migrateMessages(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE Messages") + database.execSQL(""" CREATE TABLE IF NOT EXISTS Messages ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, is_notified INTEGER NOT NULL, @@ -35,14 +34,12 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio read_by INTEGER NOT NULL, removed INTEGER NOT NULL ) - """ - ) + """) } - private fun migrateGrades(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE Grades") - db.execSQL( - """ + private fun migrateGrades(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE Grades") + database.execSQL(""" CREATE TABLE IF NOT EXISTS Grades ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, is_read INTEGER NOT NULL, @@ -62,13 +59,11 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio date INTEGER NOT NULL, teacher TEXT NOT NULL ) - """ - ) + """) } - private fun migrateStudents(db: SupportSQLiteDatabase) { - db.execSQL( - """ + private fun migrateStudents(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS Students_tmp ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, scrapper_base_url TEXT NOT NULL, @@ -91,29 +86,26 @@ class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migratio is_current INTEGER NOT NULL, registration_date INTEGER NOT NULL ) - """ - ) + """) - db.execSQL("ALTER TABLE Students ADD COLUMN scrapperBaseUrl TEXT NOT NULL DEFAULT \"\";") - db.execSQL("ALTER TABLE Students ADD COLUMN apiBaseUrl TEXT NOT NULL DEFAULT \"\";") - db.execSQL("ALTER TABLE Students ADD COLUMN is_parent INT NOT NULL DEFAULT 0;") - db.execSQL("ALTER TABLE Students ADD COLUMN loginMode TEXT NOT NULL DEFAULT \"\";") - db.execSQL("ALTER TABLE Students ADD COLUMN certificateKey TEXT NOT NULL DEFAULT \"\";") - db.execSQL("ALTER TABLE Students ADD COLUMN privateKey TEXT NOT NULL DEFAULT \"\";") - db.execSQL("ALTER TABLE Students ADD COLUMN user_login_id INTEGER NOT NULL DEFAULT 0;") + database.execSQL("ALTER TABLE Students ADD COLUMN scrapperBaseUrl TEXT NOT NULL DEFAULT \"\";") + database.execSQL("ALTER TABLE Students ADD COLUMN apiBaseUrl TEXT NOT NULL DEFAULT \"\";") + database.execSQL("ALTER TABLE Students ADD COLUMN is_parent INT NOT NULL DEFAULT 0;") + database.execSQL("ALTER TABLE Students ADD COLUMN loginMode TEXT NOT NULL DEFAULT \"\";") + database.execSQL("ALTER TABLE Students ADD COLUMN certificateKey TEXT NOT NULL DEFAULT \"\";") + database.execSQL("ALTER TABLE Students ADD COLUMN privateKey TEXT NOT NULL DEFAULT \"\";") + database.execSQL("ALTER TABLE Students ADD COLUMN user_login_id INTEGER NOT NULL DEFAULT 0;") - db.execSQL( - """ + database.execSQL(""" INSERT INTO Students_tmp( id, scrapper_base_url, mobile_base_url, is_parent, login_type, login_mode, certificate_key, private_key, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date) SELECT id, endpoint, apiBaseUrl, is_parent, loginType, "SCRAPPER", certificateKey, privateKey, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date FROM Students - """ - ) - db.execSQL("DROP TABLE Students") - db.execSQL("ALTER TABLE Students_tmp RENAME TO Students") - db.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students (email, symbol, student_id, school_id, class_id)") + """) + database.execSQL("DROP TABLE Students") + database.execSQL("ALTER TABLE Students_tmp RENAME TO Students") + database.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students (email, symbol, student_id, school_id, class_id)") } private fun migrateSharedPreferences() { diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt index be867509..c5a30991 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration2.kt @@ -5,16 +5,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration2 : Migration(1, 2) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS LuckyNumbers ( id INTEGER PRIMARY KEY NOT NULL, is_notified INTEGER NOT NULL, student_id INTEGER NOT NULL, date INTEGER NOT NULL, lucky_number INTEGER NOT NULL) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt index 7ad43230..2fcfc183 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration20.kt @@ -5,15 +5,14 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration20 : Migration(19, 20) { - override fun migrate(db: SupportSQLiteDatabase) { - migrateTimetable(db) - truncateSubjects(db) + override fun migrate(database: SupportSQLiteDatabase) { + migrateTimetable(database) + truncateSubjects(database) } - private fun migrateTimetable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE Timetable") - db.execSQL( - """ + private fun migrateTimetable(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE Timetable") + database.execSQL(""" CREATE TABLE IF NOT EXISTS `Timetable` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, @@ -34,11 +33,10 @@ class Migration20 : Migration(19, 20) { `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL ) - """ - ) + """) } - private fun truncateSubjects(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Subjects") + private fun truncateSubjects(database: SupportSQLiteDatabase) { + database.execSQL("DELETE FROM Subjects") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt index 60e044cd..bc0ff900 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration21.kt @@ -5,11 +5,11 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration21 : Migration(20, 21) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Attendance ADD COLUMN excusable INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE Attendance ADD COLUMN time_id INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE Attendance ADD COLUMN excuse_status TEXT DEFAULT NULL") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Attendance ADD COLUMN excusable INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Attendance ADD COLUMN time_id INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Attendance ADD COLUMN excuse_status TEXT DEFAULT NULL") - db.execSQL("DELETE FROM Semesters") + database.execSQL("DELETE FROM Semesters") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration22.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration22.kt index ef525a49..cf50a6c3 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration22.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration22.kt @@ -5,7 +5,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration22 : Migration(21, 22) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN school_short TEXT NOT NULL DEFAULT ''") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Students ADD COLUMN school_short TEXT NOT NULL DEFAULT ''") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration23.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration23.kt index 3650307a..22de94c3 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration23.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration23.kt @@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration23 : Migration(22, 23) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Notes ADD COLUMN teacher_symbol TEXT NOT NULL DEFAULT ''") - db.execSQL("ALTER TABLE Notes ADD COLUMN category_type INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE Notes ADD COLUMN is_points_show INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE Notes ADD COLUMN points INTEGER NOT NULL DEFAULT 0") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Notes ADD COLUMN teacher_symbol TEXT NOT NULL DEFAULT ''") + database.execSQL("ALTER TABLE Notes ADD COLUMN category_type INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Notes ADD COLUMN is_points_show INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Notes ADD COLUMN points INTEGER NOT NULL DEFAULT 0") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration24.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration24.kt index a3cd9819..604ed487 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration24.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration24.kt @@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration24 : Migration(23, 24) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Messages ADD COLUMN has_attachments INTEGER NOT NULL DEFAULT 0") + database.execSQL(""" CREATE TABLE IF NOT EXISTS MessageAttachments ( real_id INTEGER NOT NULL, message_id INTEGER NOT NULL, @@ -17,7 +16,6 @@ class Migration24 : Migration(23, 24) { filename TEXT NOT NULL, PRIMARY KEY(real_id) ) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration25.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration25.kt index cb395d7e..4749bac7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration25.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration25.kt @@ -5,8 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration25 : Migration(24, 25) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Homework ADD COLUMN is_done INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE Homework ADD COLUMN attachments TEXT NOT NULL DEFAULT \"[]\"") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Homework ADD COLUMN is_done INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE Homework ADD COLUMN attachments TEXT NOT NULL DEFAULT \"[]\"") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt index 94746b45..7130d86d 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt @@ -5,10 +5,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration26 : Migration(25, 26) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1") - db.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1") - db.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0") - db.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1") + database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1") + database.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0") + database.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt index a7ba763d..6592228a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration27.kt @@ -5,46 +5,41 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration27 : Migration(26, 27) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN user_name TEXT NOT NULL DEFAULT \"\"") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Students ADD COLUMN user_name TEXT NOT NULL DEFAULT \"\"") - val students = getStudentsIdsAndNames(db) - val units = getReportingUnits(db) + val students = getStudentsIdsAndNames(database) + val units = getReportingUnits(database) students.forEach { (id, userLoginId, studentName) -> - val userNameFromUnits = - units.singleOrNull { (senderId, _) -> senderId == userLoginId }?.second + val userNameFromUnits = units.singleOrNull { (senderId, _) -> senderId == userLoginId }?.second val normalizedStudentName = studentName.split(" ").asReversed().joinToString(" ") val userName = userNameFromUnits ?: normalizedStudentName - db.execSQL("UPDATE Students SET user_name = '$userName' WHERE id = '$id'") + database.execSQL("UPDATE Students SET user_name = '$userName' WHERE id = '$id'") } } - private fun getStudentsIdsAndNames(db: SupportSQLiteDatabase): MutableList> { + private fun getStudentsIdsAndNames(database: SupportSQLiteDatabase): MutableList> { val students = mutableListOf>() - db.query("SELECT id, user_login_id, student_name FROM Students").use { - if (it.moveToFirst()) { - do { - students.add(Triple(it.getLong(0), it.getInt(1), it.getString(2))) - } while (it.moveToNext()) - } + val studentsCursor = database.query("SELECT id, user_login_id, student_name FROM Students") + if (studentsCursor.moveToFirst()) { + do { + students.add(Triple(studentsCursor.getLong(0), studentsCursor.getInt(1), studentsCursor.getString(2))) + } while (studentsCursor.moveToNext()) } - return students } - private fun getReportingUnits(db: SupportSQLiteDatabase): MutableList> { + private fun getReportingUnits(database: SupportSQLiteDatabase): MutableList> { val units = mutableListOf>() - db.query("SELECT sender_id, sender_name FROM ReportingUnits").use { - if (it.moveToFirst()) { - do { - units.add(it.getInt(0) to it.getString(1)) - } while (it.moveToNext()) - } + val unitsCursor = database.query("SELECT sender_id, sender_name FROM ReportingUnits") + if (unitsCursor.moveToFirst()) { + do { + units.add(unitsCursor.getInt(0) to unitsCursor.getString(1)) + } while (unitsCursor.moveToNext()) } - return units } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration28.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration28.kt index e8a5a4a8..51e7628b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration28.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration28.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration28 : Migration(27, 28) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS Conferences ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration29.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration29.kt index dac303d2..327552d7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration29.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration29.kt @@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration29 : Migration(28, 29) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS GradesStatistics") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE IF EXISTS GradesStatistics") + database.execSQL(""" CREATE TABLE IF NOT EXISTS GradeSemesterStatistics ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, @@ -17,10 +16,8 @@ class Migration29 : Migration(28, 29) { amounts TEXT NOT NULL, student_grade INTEGER NOT NULL ) - """ - ) - db.execSQL( - """ + """) + database.execSQL(""" CREATE TABLE IF NOT EXISTS GradePartialStatistics ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, student_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt index 44d42164..d9699c0f 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration3.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration3 : Migration(2, 3) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS CompletedLesson ( id INTEGER PRIMARY KEY NOT NULL, student_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration30.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration30.kt deleted file mode 100644 index 3fea8ec0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration30.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration30 : Migration(29, 30) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ - CREATE TABLE TimetableAdditional ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - student_id INTEGER NOT NULL, - diary_id INTEGER NOT NULL, - start INTEGER NOT NULL, - `end` INTEGER NOT NULL, - date INTEGER NOT NULL, - subject TEXT NOT NULL - ) - """ - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration31.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration31.kt deleted file mode 100644 index 28fb1056..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration31.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration31 : Migration(30, 31) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """CREATE TABLE IF NOT EXISTS StudentInfo ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - student_id INTEGER NOT NULL, - full_name TEXT NOT NULL, - first_name TEXT NOT NULL, - second_name TEXT NOT NULL, - surname TEXT NOT NULL, - birth_date INTEGER NOT NULL, - birth_place TEXT NOT NULL, - gender TEXT NOT NULL, - has_polish_citizenship INTEGER NOT NULL, - family_name TEXT NOT NULL, - parents_names TEXT NOT NULL, - address TEXT NOT NULL, - registered_address TEXT NOT NULL, - correspondence_address TEXT NOT NULL, - phone_number TEXT NOT NULL, - cell_phone_number TEXT NOT NULL, - email TEXT NOT NULL, - first_guardian_full_name TEXT NOT NULL, - first_guardian_kinship TEXT NOT NULL, - first_guardian_address TEXT NOT NULL, - first_guardian_phones TEXT NOT NULL, - first_guardian_email TEXT NOT NULL, - second_guardian_full_name TEXT NOT NULL, - second_guardian_kinship TEXT NOT NULL, - second_guardian_address TEXT NOT NULL, - second_guardian_phones TEXT NOT NULL, - second_guardian_email TEXT NOT NULL) - """ - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration32.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration32.kt deleted file mode 100644 index 34787393..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration32.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration32 : Migration(31, 32) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN nick TEXT NOT NULL DEFAULT \"\"") - } -} - diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration33.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration33.kt deleted file mode 100644 index 9778d279..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration33.kt +++ /dev/null @@ -1,45 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration33 : Migration(32, 33) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS StudentInfo") - - db.execSQL( - """CREATE TABLE IF NOT EXISTS StudentInfo ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - student_id INTEGER NOT NULL, - full_name TEXT NOT NULL, - first_name TEXT NOT NULL, - second_name TEXT NOT NULL, - surname TEXT NOT NULL, - birth_date INTEGER NOT NULL, - birth_place TEXT NOT NULL, - gender TEXT NOT NULL, - has_polish_citizenship INTEGER NOT NULL, - family_name TEXT NOT NULL, - parents_names TEXT NOT NULL, - address TEXT NOT NULL, - registered_address TEXT NOT NULL, - correspondence_address TEXT NOT NULL, - phone_number TEXT NOT NULL, - cell_phone_number TEXT NOT NULL, - email TEXT NOT NULL, - first_guardian_full_name TEXT, - first_guardian_kinship TEXT, - first_guardian_address TEXT, - first_guardian_phones TEXT, - first_guardian_email TEXT, - second_guardian_full_name TEXT, - second_guardian_kinship TEXT, - second_guardian_address TEXT, - second_guardian_phones TEXT, - second_guardian_email TEXT) - """ - ) - } -} - diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration34.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration34.kt deleted file mode 100644 index e9eec58c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration34.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration34 : Migration(33, 34) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM ReportingUnits") - db.execSQL("DELETE FROM Recipients") - } -} - diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt deleted file mode 100644 index b238ce8b..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration35.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.core.database.getLongOrNull -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase -import io.github.wulkanowy.utils.AppInfo - -class Migration35(private val appInfo: AppInfo) : Migration(34, 35) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN `avatar_color` INTEGER NOT NULL DEFAULT 0") - - db.query("SELECT * FROM Students").use { - while (it.moveToNext()) { - val studentId = it.getLongOrNull(0) - db.execSQL( - """ - UPDATE Students - SET avatar_color = ${appInfo.defaultColorsForAvatar.random()} - WHERE id = $studentId - """ - ) - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration36.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration36.kt deleted file mode 100644 index 62ce346c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration36.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration36 : Migration(35, 36) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Exams ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - db.execSQL("ALTER TABLE Homework ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration37.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration37.kt deleted file mode 100644 index 9ab35514..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration37.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration37 : Migration(36, 37) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS TimetableHeaders ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - student_id INTEGER NOT NULL, - diary_id INTEGER NOT NULL, - date INTEGER NOT NULL, - content TEXT NOT NULL - ) - """ - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration38.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration38.kt deleted file mode 100644 index bb9b32bf..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration38.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration38 : Migration(37, 38) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` ( - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - `student_id` INTEGER NOT NULL, - `date` INTEGER NOT NULL, - `subject` TEXT NOT NULL, - `content` TEXT NOT NULL - ) - """ - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration39.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration39.kt deleted file mode 100644 index 2e5315bf..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration39.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration39 : Migration(38, 39) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Conferences ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - db.execSQL("ALTER TABLE SchoolAnnouncements ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt index b6089aa6..0ae89bdd 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration4.kt @@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration4 : Migration(3, 4) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Messages") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE IF EXISTS Messages") + database.execSQL(""" CREATE TABLE IF NOT EXISTS Messages ( id INTEGER PRIMARY KEY NOT NULL, is_notified INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration40.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration40.kt deleted file mode 100644 index 8e38b0c8..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration40.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration40 : Migration(39, 40) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Notifications` ( - `student_id` INTEGER NOT NULL, - `title` TEXT NOT NULL, - `content` TEXT NOT NULL, - `type` TEXT NOT NULL, - `date` INTEGER NOT NULL, - `data` TEXT, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL - ) - """ - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration41.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration41.kt deleted file mode 100644 index bfc28334..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration41.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase -import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.enums.GradeExpandMode - -class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) { - - override fun migrate(db: SupportSQLiteDatabase) { - migrateSharedPreferences() - db.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0") - } - - private fun migrateSharedPreferences() { - if (sharedPrefProvider.getBoolean("pref_key_expand_grade", false)) { - sharedPrefProvider.putString("pref_key_expand_grade_mode", GradeExpandMode.ALWAYS_EXPANDED.value) - } - sharedPrefProvider.delete("pref_key_expand_grade") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration42.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration42.kt deleted file mode 100644 index 14356e27..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration42.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration42 : Migration(41, 42) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """CREATE TABLE IF NOT EXISTS `AdminMessages` ( - `id` INTEGER NOT NULL, - `title` TEXT NOT NULL, - `content` TEXT NOT NULL, - `version_name` INTEGER, - `version_max` INTEGER, - `target_register_host` TEXT, - `target_flavor` TEXT, - `destination_url` TEXT, - `priority` TEXT NOT NULL, - `type` TEXT NOT NULL, - PRIMARY KEY(`id`))""" - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration43.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration43.kt deleted file mode 100644 index ef810816..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration43.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration43 : Migration(42, 43) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Timetable ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - db.execSQL("ALTER TABLE Attendance ADD COLUMN is_notified INTEGER NOT NULL DEFAULT 1") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration44.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration44.kt deleted file mode 100644 index 0a4e5f96..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration44.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration44 : Migration(43, 44) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE AdminMessages ADD COLUMN is_dismissible INTEGER NOT NULL DEFAULT 0") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt deleted file mode 100644 index 0bacbaa0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration46.kt +++ /dev/null @@ -1,102 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase -import java.time.Instant -import java.time.ZoneId -import java.time.ZoneOffset - -class Migration46 : Migration(45, 46) { - - override fun migrate(db: SupportSQLiteDatabase) { - migrateConferences(db) - migrateMessages(db) - migrateMobileDevices(db) - migrateNotifications(db) - migrateTimetable(db) - migrateTimetableAdditional(db) - } - - private fun migrateConferences(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM Conferences").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) - val timestampUtc = timestampLocal.timestampLocalToUTC() - - db.execSQL("UPDATE Conferences SET date = $timestampUtc WHERE id = $id") - } - } - } - - private fun migrateMessages(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM Messages").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) - val timestampUtc = timestampLocal.timestampLocalToUTC() - - db.execSQL("UPDATE Messages SET date = $timestampUtc WHERE id = $id") - } - } - } - - private fun migrateMobileDevices(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM MobileDevices").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) - val timestampUtc = timestampLocal.timestampLocalToUTC() - - db.execSQL("UPDATE MobileDevices SET date = $timestampUtc WHERE id = $id") - } - } - } - - private fun migrateNotifications(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM Notifications").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocal = it.getLong(it.getColumnIndexOrThrow("date")) - val timestampUtc = timestampLocal.timestampLocalToUTC() - - db.execSQL("UPDATE Notifications SET date = $timestampUtc WHERE id = $id") - } - } - } - - private fun migrateTimetable(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM Timetable").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) - val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end")) - val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() - val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() - - db.execSQL("UPDATE Timetable SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") - } - } - } - - private fun migrateTimetableAdditional(db: SupportSQLiteDatabase) { - db.query("SELECT * FROM TimetableAdditional").use { - while (it.moveToNext()) { - val id = it.getLong(it.getColumnIndexOrThrow("id")) - val timestampLocalStart = it.getLong(it.getColumnIndexOrThrow("start")) - val timestampLocalEnd = it.getLong(it.getColumnIndexOrThrow("end")) - val timestampUtcStart = timestampLocalStart.timestampLocalToUTC() - val timestampUtcEnd = timestampLocalEnd.timestampLocalToUTC() - - db.execSQL("UPDATE TimetableAdditional SET start = $timestampUtcStart, end = $timestampUtcEnd WHERE id = $id") - } - } - } - - private fun Long.timestampLocalToUTC(): Long = Instant.ofEpochMilli(this) - .atZone(ZoneOffset.UTC) - .withZoneSameLocal(ZoneId.of("Europe/Warsaw")) - .withZoneSameInstant(ZoneId.systemDefault()) - .toInstant() - .toEpochMilli() -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration49.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration49.kt deleted file mode 100644 index 97766c01..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration49.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration49 : Migration(48, 49) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS SchoolAnnouncements") - - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `SchoolAnnouncements` ( - `user_login_id` INTEGER NOT NULL, - `date` INTEGER NOT NULL, - `subject` TEXT NOT NULL, - `content` TEXT NOT NULL, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - `is_notified` INTEGER NOT NULL) - """.trimIndent() - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt index a5b4e8e1..dbcd916b 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration5.kt @@ -7,16 +7,11 @@ import java.time.ZoneOffset class Migration5 : Migration(4, 5) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Students ADD COLUMN registration_date INTEGER DEFAULT 0 NOT NULL") - db.execSQL( - "UPDATE Students SET registration_date = '${ - now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli() - }'" - ) - db.execSQL("DROP TABLE IF EXISTS Notes") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Students ADD COLUMN registration_date INTEGER DEFAULT 0 NOT NULL") + database.execSQL("UPDATE Students SET registration_date = '${now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli()}'") + database.execSQL("DROP TABLE IF EXISTS Notes") + database.execSQL(""" CREATE TABLE IF NOT EXISTS Notes ( id INTEGER PRIMARY KEY NOT NULL, is_read INTEGER NOT NULL, @@ -26,7 +21,6 @@ class Migration5 : Migration(4, 5) { teacher TEXT NOT NULL, category TEXT NOT NULL, content TEXT NOT NULL) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration50.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration50.kt deleted file mode 100644 index 577998ca..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration50.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration50 : Migration(49, 50) { - - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS MobileDevices") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `MobileDevices` ( - `user_login_id` INTEGER NOT NULL, - `device_id` INTEGER NOT NULL, - `name` TEXT NOT NULL, - `date` INTEGER NOT NULL, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL) - """.trimIndent() - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration51.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration51.kt deleted file mode 100644 index 7023049f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration51.kt +++ /dev/null @@ -1,88 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration51 : Migration(50, 51) { - - override fun migrate(db: SupportSQLiteDatabase) { - createMailboxTable(db) - recreateMessagesTable(db) - recreateMessageAttachmentsTable(db) - recreateRecipientsTable(db) - deleteReportingUnitTable(db) - } - - private fun createMailboxTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Mailboxes") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Mailboxes` ( - `globalKey` TEXT NOT NULL, - `fullName` TEXT NOT NULL, - `userName` TEXT NOT NULL, - `userLoginId` INTEGER NOT NULL, - `studentName` TEXT NOT NULL, - `schoolNameShort` TEXT NOT NULL, - `type` TEXT NOT NULL, - PRIMARY KEY(`globalKey`) - )""".trimIndent() - ) - } - - private fun recreateMessagesTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Messages") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Messages` ( - `message_global_key` TEXT NOT NULL, - `mailbox_key` TEXT NOT NULL, - `message_id` INTEGER NOT NULL, - `correspondents` TEXT NOT NULL, - `subject` TEXT NOT NULL, - `date` INTEGER NOT NULL, - `folder_id` INTEGER NOT NULL, - `unread` INTEGER NOT NULL, - `has_attachments` INTEGER NOT NULL, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - `is_notified` INTEGER NOT NULL, - `content` TEXT NOT NULL, - `sender` TEXT, `recipients` TEXT - )""".trimIndent() - ) - } - - private fun recreateMessageAttachmentsTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS MessageAttachments") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `MessageAttachments` ( - `real_id` INTEGER NOT NULL, - `message_global_key` TEXT NOT NULL, - `url` TEXT NOT NULL, - `filename` TEXT NOT NULL, - PRIMARY KEY(`real_id`) - )""".trimIndent() - ) - } - - private fun recreateRecipientsTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Recipients") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Recipients` ( - `mailboxGlobalKey` TEXT NOT NULL, - `studentMailboxGlobalKey` TEXT NOT NULL, - `fullName` TEXT NOT NULL, - `userName` TEXT NOT NULL, - `schoolShortName` TEXT NOT NULL, - `type` TEXT NOT NULL, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL - )""".trimIndent() - ) - } - - private fun deleteReportingUnitTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS ReportingUnits") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt deleted file mode 100644 index dd9e68c9..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration53 : Migration(52, 53) { - - override fun migrate(db: SupportSQLiteDatabase) { - createMailboxTable(db) - recreateMessagesTable(db) - } - - private fun createMailboxTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Mailboxes") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Mailboxes` ( - `globalKey` TEXT NOT NULL, - `email` TEXT NOT NULL, - `symbol` TEXT NOT NULL, - `schoolId` TEXT NOT NULL, - `fullName` TEXT NOT NULL, - `userName` TEXT NOT NULL, - `studentName` TEXT NOT NULL, - `schoolNameShort` TEXT NOT NULL, - `type` TEXT NOT NULL, - PRIMARY KEY(`globalKey`) - )""".trimIndent() - ) - } - - private fun recreateMessagesTable(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Messages") - db.execSQL( - """ - CREATE TABLE IF NOT EXISTS `Messages` ( - `email` TEXT NOT NULL, - `message_global_key` TEXT NOT NULL, - `mailbox_key` TEXT NOT NULL, - `message_id` INTEGER NOT NULL, - `correspondents` TEXT NOT NULL, - `subject` TEXT NOT NULL, - `date` INTEGER NOT NULL, - `folder_id` INTEGER NOT NULL, - `unread` INTEGER NOT NULL, - `read_by` INTEGER, - `unread_by` INTEGER, - `has_attachments` INTEGER NOT NULL, - `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - `is_notified` INTEGER NOT NULL, - `content` TEXT NOT NULL, - `sender` TEXT, - `recipients` TEXT - )""".trimIndent() - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt deleted file mode 100644 index 60bd21f0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration54 : Migration(53, 54) { - - override fun migrate(db: SupportSQLiteDatabase) { - migrateResman(db) - removeTomaszowMazowieckiStudents(db) - } - - private fun migrateResman(db: SupportSQLiteDatabase) { - db.execSQL( - """ - UPDATE Students SET - scrapper_base_url = 'https://vulcan.net.pl', - login_type = 'ADFSLightScoped', - symbol = 'rzeszowprojekt' - WHERE scrapper_base_url = 'https://resman.pl' - """.trimIndent() - ) - } - - private fun removeTomaszowMazowieckiStudents(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Students WHERE symbol = 'tomaszowmazowiecki'") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration55.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration55.kt deleted file mode 100644 index 424be171..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration55.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.DeleteColumn -import androidx.room.migration.AutoMigrationSpec -import androidx.sqlite.db.SupportSQLiteDatabase - -@DeleteColumn( - tableName = "MessageAttachments", - columnName = "real_id", -) -class Migration55 : AutoMigrationSpec { - - override fun onPostMigrate(db: SupportSQLiteDatabase) { - db.execSQL("DELETE FROM Messages") - db.execSQL("DELETE FROM MessageAttachments") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration57.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration57.kt deleted file mode 100644 index 2fc8718f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration57.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.DeleteColumn -import androidx.room.migration.AutoMigrationSpec - -@DeleteColumn( - tableName = "AdminMessages", - columnName = "type", -) -class Migration57 : AutoMigrationSpec diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration58.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration58.kt deleted file mode 100644 index c440d58d..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration58.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.DeleteColumn -import androidx.room.migration.AutoMigrationSpec - -@DeleteColumn( - tableName = "AdminMessages", - columnName = "is_dismissible", -) -class Migration58 : AutoMigrationSpec diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt index 06cd5f0f..fa943618 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration6.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration6 : Migration(5, 6) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS ReportingUnits ( id INTEGER PRIMARY KEY NOT NULL, student_id INTEGER NOT NULL, @@ -16,11 +15,9 @@ class Migration6 : Migration(5, 6) { sender_id INTEGER NOT NULL, sender_name TEXT NOT NULL, roles TEXT NOT NULL) - """ - ) + """) - db.execSQL( - """ + database.execSQL(""" CREATE TABLE IF NOT EXISTS Recipients ( id INTEGER PRIMARY KEY NOT NULL, student_id INTEGER NOT NULL, @@ -31,11 +28,10 @@ class Migration6 : Migration(5, 6) { unit_id INTEGER NOT NULL, role INTEGER NOT NULL, hash TEXT NOT NULL) - """ - ) + """) - db.execSQL("DELETE FROM Semesters WHERE 1") - db.execSQL("ALTER TABLE Semesters ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") - db.execSQL("ALTER TABLE Semesters ADD COLUMN unit_id INTEGER DEFAULT 0 NOT NULL") + database.execSQL("DELETE FROM Semesters WHERE 1") + database.execSQL("ALTER TABLE Semesters ADD COLUMN class_id INTEGER DEFAULT 0 NOT NULL") + database.execSQL("ALTER TABLE Semesters ADD COLUMN unit_id INTEGER DEFAULT 0 NOT NULL") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration63.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration63.kt deleted file mode 100644 index f88d31fc..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration63.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.db.migrations - -import androidx.room.migration.AutoMigrationSpec -import androidx.sqlite.db.SupportSQLiteDatabase - -class Migration63 : AutoMigrationSpec { - - override fun onPostMigrate(db: SupportSQLiteDatabase) { - db.execSQL("UPDATE Students SET is_edu_one = NULL WHERE is_edu_one = 0") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt index 83a822f2..120716c8 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration7.kt @@ -5,9 +5,8 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration7 : Migration(6, 7) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL(""" CREATE TABLE IF NOT EXISTS GradesStatistics ( id INTEGER PRIMARY KEY NOT NULL, student_id INTEGER NOT NULL, @@ -16,7 +15,6 @@ class Migration7 : Migration(6, 7) { grade INTEGER NOT NULL, amount INTEGER NOT NULL, is_semester INTEGER NOT NULL) - """ - ) + """) } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt index 992e8c68..7009ee12 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration8.kt @@ -5,9 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration8 : Migration(7, 8) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("ALTER TABLE Timetable ADD COLUMN subjectOld TEXT DEFAULT \"\" NOT NULL") - db.execSQL("ALTER TABLE Timetable ADD COLUMN roomOld TEXT DEFAULT \"\" NOT NULL") - db.execSQL("ALTER TABLE Timetable ADD COLUMN teacherOld TEXT DEFAULT \"\" NOT NULL") + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE Timetable ADD COLUMN subjectOld TEXT DEFAULT \"\" NOT NULL") + database.execSQL("ALTER TABLE Timetable ADD COLUMN roomOld TEXT DEFAULT \"\" NOT NULL") + database.execSQL("ALTER TABLE Timetable ADD COLUMN teacherOld TEXT DEFAULT \"\" NOT NULL") } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt index b83c34c4..d79a5706 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration9.kt @@ -5,10 +5,9 @@ import androidx.sqlite.db.SupportSQLiteDatabase class Migration9 : Migration(8, 9) { - override fun migrate(db: SupportSQLiteDatabase) { - db.execSQL("DROP TABLE IF EXISTS Messages") - db.execSQL( - """ + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("DROP TABLE IF EXISTS Messages") + database.execSQL(""" CREATE TABLE IF NOT EXISTS Messages ( id INTEGER PRIMARY KEY NOT NULL, student_id INTEGER NOT NULL, diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt b/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt deleted file mode 100644 index acff9d2e..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class AppTheme(val value: String) { - SYSTEM("system"), - LIGHT("light"), - DARK("dark"), - BLACK("black"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: LIGHT - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/AttendanceCalculatorSortingMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/AttendanceCalculatorSortingMode.kt deleted file mode 100644 index 77dd5fc4..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/AttendanceCalculatorSortingMode.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class AttendanceCalculatorSortingMode(private val value: String) { - ALPHABETIC("alphabetic"), - ATTENDANCE("attendance_percentage"), - LESSON_BALANCE("lesson_balance"); - - companion object { - fun getByValue(value: String) = - AttendanceCalculatorSortingMode.values() - .find { it.value == value } ?: ALPHABETIC - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/Gender.kt b/app/src/main/java/io/github/wulkanowy/data/enums/Gender.kt deleted file mode 100644 index df93dcbe..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/Gender.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class Gender { MALE, FEMALE } diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/GradeColorTheme.kt b/app/src/main/java/io/github/wulkanowy/data/enums/GradeColorTheme.kt deleted file mode 100644 index 48b81670..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/GradeColorTheme.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.data.enums - -import java.io.Serializable - -enum class GradeColorTheme(val value: String) : Serializable { - VULCAN("vulcan"), - MATERIAL("material"), - GRADE_COLOR("grade_color"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: VULCAN - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/GradeExpandMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/GradeExpandMode.kt deleted file mode 100644 index f99fe7a8..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/GradeExpandMode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class GradeExpandMode(val value: String) { - ONE("one"), - UNLIMITED("any"), - ALWAYS_EXPANDED("always"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: ONE - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/GradeSortingMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/GradeSortingMode.kt deleted file mode 100644 index e2872728..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/GradeSortingMode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class GradeSortingMode(val value: String) { - ALPHABETIC("alphabetic"), - DATE("date"), - AVERAGE("average"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: ALPHABETIC - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/MessageFolder.kt b/app/src/main/java/io/github/wulkanowy/data/enums/MessageFolder.kt deleted file mode 100644 index 7cb4202a..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/MessageFolder.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class MessageFolder(val id: Int = 1) { - RECEIVED(1), - SENT(2), - TRASHED(3), - ; - - companion object { - fun byId(id: Int) = entries.first { it.id == id } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/MessageType.kt b/app/src/main/java/io/github/wulkanowy/data/enums/MessageType.kt deleted file mode 100644 index ecd8d916..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/MessageType.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class MessageType { - GENERAL_MESSAGE, - DASHBOARD_MESSAGE, - LOGIN_MESSAGE, - LOGIN_STUDENT_SELECT_MESSAGE, - LOGIN_SYMBOL_MESSAGE, - PASS_RESET_MESSAGE, - ERROR_OVERRIDE, -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/ShowAdditionalLessonsMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/ShowAdditionalLessonsMode.kt deleted file mode 100644 index 3e7cdef5..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/ShowAdditionalLessonsMode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class ShowAdditionalLessonsMode(val value: String) { - NONE("none"), - INLINE("inline"), - BELOW("below"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: INLINE - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/TimetableGapsMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/TimetableGapsMode.kt deleted file mode 100644 index c8310c02..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/TimetableGapsMode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class TimetableGapsMode(val value: String) { - NO_GAPS("no_gaps"), - BETWEEN_LESSONS("between"), - BETWEEN_AND_BEFORE_LESSONS("before_and_between"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: BETWEEN_LESSONS - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt deleted file mode 100644 index b2eeec38..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.enums - -enum class TimetableMode(val value: String) { - WHOLE_PLAN("yes"), - ONLY_CURRENT_GROUP("no"), - SMALL_OTHER_GROUP("small"); - - companion object { - fun getByValue(value: String) = entries.find { it.value == value } ?: ONLY_CURRENT_GROUP - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt deleted file mode 100644 index c0ed0c8c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt +++ /dev/null @@ -1,48 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.data.db.entities.AttendanceSummary -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.sdk.pojo.Attendance as SdkAttendance -import io.github.wulkanowy.sdk.pojo.AttendanceSummary as SdkAttendanceSummary - -fun List.mapToEntities(semester: Semester, lessons: List) = map { - Attendance( - studentId = semester.studentId, - diaryId = semester.diaryId, - date = it.date, - timeId = it.timeId, - number = it.number, - subject = it.subject.ifBlank { - lessons.find { lesson -> - lesson.date == it.date && lesson.number == it.number - }?.subject.orEmpty() - }, - name = it.name, - presence = it.presence, - absence = it.absence, - exemption = it.exemption, - lateness = it.lateness, - excused = it.excused, - deleted = it.deleted, - excusable = it.excusable, - excuseStatus = it.excuseStatus?.name - ) -} - -fun List.mapToEntities(semester: Semester, subjectId: Int) = map { - AttendanceSummary( - studentId = semester.studentId, - diaryId = semester.diaryId, - subjectId = subjectId, - month = it.month, - presence = it.presence, - absence = it.absence, - absenceExcused = it.absenceExcused, - absenceForSchoolReasons = it.absenceForSchoolReasons, - lateness = it.lateness, - latenessExcused = it.latenessExcused, - exemption = it.exemption - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/CompletedLessonsMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/CompletedLessonsMapper.kt deleted file mode 100644 index c42126eb..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/CompletedLessonsMapper.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.CompletedLesson -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.CompletedLesson as SdkCompletedLesson - -fun List.mapToEntities(semester: Semester) = map { - CompletedLesson( - studentId = semester.studentId, - diaryId = semester.diaryId, - date = it.date, - number = it.number, - subject = it.subject, - topic = it.topic, - teacher = it.teacher, - teacherSymbol = it.teacherSymbol, - substitution = it.substitution, - absence = it.absence, - resources = it.resources - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt deleted file mode 100644 index add6439d..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/ConferenceMapper.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.Conference as SdkConference - -fun List.mapToEntities(semester: Semester) = map { - Conference( - studentId = semester.studentId, - diaryId = semester.diaryId, - agenda = it.agenda, - conferenceId = it.id, - date = it.date.toInstant(), - presentOnConference = it.presentOnConference, - subject = it.topic, - title = it.place, - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/DirectorInformationMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/DirectorInformationMapper.kt deleted file mode 100644 index 1a84a6a5..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/DirectorInformationMapper.kt +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.sdk.pojo.DirectorInformation as SdkDirectorInformation -import io.github.wulkanowy.sdk.pojo.LastAnnouncement as SdkLastAnnouncement - -@JvmName("mapDirectorInformationToEntities") -fun List.mapToEntities(student: Student) = map { - SchoolAnnouncement( - studentId = student.studentId, - date = it.date, - subject = it.subject, - content = it.content, - author = null, - ) -} - -@JvmName("mapLastAnnouncementsToEntities") -fun List.mapToEntities(student: Student) = map { - SchoolAnnouncement( - studentId = student.studentId, - date = it.date, - subject = it.subject, - content = it.content, - author = it.author, - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt deleted file mode 100644 index 173dfebf..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/ExamMapper.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Exam -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.Exam as SdkExam - -fun List.mapToEntities(semester: Semester) = map { - Exam( - studentId = semester.studentId, - diaryId = semester.diaryId, - date = it.date, - entryDate = it.entryDate, - subject = it.subject, - group = "", - type = it.type, - description = it.description, - teacher = it.teacher, - teacherSymbol = it.teacherSymbol - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/GradeMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/GradeMapper.kt deleted file mode 100644 index 57322a7a..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/GradeMapper.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive -import io.github.wulkanowy.data.db.entities.GradeSummary -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.Grade as SdkGrade -import io.github.wulkanowy.sdk.pojo.GradeDescriptive as SdkGradeDescriptive -import io.github.wulkanowy.sdk.pojo.GradeSummary as SdkGradeSummary - -fun List.mapToEntities(semester: Semester) = map { - Grade( - studentId = semester.studentId, - semesterId = semester.semesterId, - subject = it.subject, - entry = it.entry, - value = it.value, - modifier = it.modifier, - comment = it.comment, - color = it.color, - gradeSymbol = it.symbol, - description = it.description, - weight = it.weight, - weightValue = it.weightValue, - date = it.date, - teacher = it.teacher - ) -} - -@JvmName("mapGradeSummaryToEntities") -fun List.mapToEntities(semester: Semester) = map { - GradeSummary( - semesterId = semester.semesterId, - studentId = semester.studentId, - position = 0, - subject = it.name, - predictedGrade = it.predicted, - finalGrade = it.final, - pointsSum = it.pointsSum, - pointsSumAllYear = it.pointsSumAllYear, - proposedPoints = it.proposedPoints, - finalPoints = it.finalPoints, - average = it.average, - averageAllYear = it.averageAllYear, - ) -} - -@JvmName("mapGradeDescriptiveToEntities") -fun List.mapToEntities(semester: Semester) = map { - GradeDescriptive( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.subject, - description = it.description - ) -} - - diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/GradeStatisticsMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/GradeStatisticsMapper.kt deleted file mode 100644 index b25802d2..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/GradeStatisticsMapper.kt +++ /dev/null @@ -1,79 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.GradePartialStatistics -import io.github.wulkanowy.data.db.entities.GradePointsStatistics -import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.pojos.GradeStatisticsItem -import io.github.wulkanowy.sdk.pojo.GradePointsStatistics as SdkGradePointsStatistics -import io.github.wulkanowy.sdk.pojo.GradeStatisticsSemester as SdkGradeStatisticsSemester -import io.github.wulkanowy.sdk.pojo.GradeStatisticsSubject as SdkGradeStatisticsSubject - -@JvmName("mapToEntitiesSubject") -fun List.mapToEntities(semester: Semester) = map { - GradePartialStatistics( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.subject, - classAverage = it.classAverage, - studentAverage = it.studentAverage, - classAmounts = it.classItems - .sortedBy { item -> item.grade } - .map { item -> item.amount }, - studentAmounts = it.studentItems.map { item -> item.amount } - ) -} - -@JvmName("mapToEntitiesSemester") -fun List.mapToEntities(semester: Semester) = map { - GradeSemesterStatistics( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.subject, - amounts = it.items - .sortedBy { item -> item.grade } - .map { item -> item.amount }, - studentGrade = it.items.singleOrNull { item -> item.isStudentHere }?.grade ?: 0 - ) -} - -@JvmName("mapToEntitiesPoints") -fun List.mapToEntities(semester: Semester) = map { - GradePointsStatistics( - semesterId = semester.semesterId, - studentId = semester.studentId, - subject = it.subject, - others = it.others, - student = it.student - ) -} - -fun List.mapPartialToStatisticItems() = filterNot { it.classAmounts.isEmpty() }.map { - GradeStatisticsItem( - type = GradeStatisticsItem.DataType.PARTIAL, - average = it.classAverage, - partial = it, - points = null, - semester = null - ) -} - -fun List.mapSemesterToStatisticItems() = filterNot { it.amounts.isEmpty() }.map { - GradeStatisticsItem( - type = GradeStatisticsItem.DataType.SEMESTER, - partial = null, - points = null, - average = "", - semester = it - ) -} - -fun List.mapPointsToStatisticsItems() = map { - GradeStatisticsItem( - type = GradeStatisticsItem.DataType.POINTS, - partial = null, - semester = null, - average = "", - points = it - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/HomeworkMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/HomeworkMapper.kt deleted file mode 100644 index 880a26d6..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/HomeworkMapper.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.sdk.pojo.Homework as SdkHomework -import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.db.entities.Semester - -fun List.mapToEntities(semester: Semester) = map { - Homework( - semesterId = semester.semesterId, - studentId = semester.studentId, - date = it.date, - entryDate = it.entryDate, - subject = it.subject, - content = it.content, - teacher = it.teacher, - teacherSymbol = it.teacherSymbol, - attachments = it.attachments.map { attachment -> - attachment.url to attachment.name - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/LuckyNumberMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/LuckyNumberMapper.kt deleted file mode 100644 index 78ebe1d6..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/LuckyNumberMapper.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.data.db.entities.Student -import java.time.LocalDate -import io.github.wulkanowy.sdk.pojo.LuckyNumber as SdkLuckyNumber - -fun SdkLuckyNumber.mapToEntity(student: Student) = LuckyNumber( - studentId = student.studentId, - date = LocalDate.now(), - luckyNumber = number -) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt deleted file mode 100644 index 0cf54777..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.MailboxType -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.sdk.pojo.Mailbox as SdkMailbox - -fun List.mapToEntities(student: Student) = map { - Mailbox( - globalKey = it.globalKey, - fullName = it.fullName, - userName = it.userName, - studentName = it.studentName, - schoolNameShort = it.schoolNameShort, - type = MailboxType.valueOf(it.type.name), - email = student.email, - symbol = student.symbol, - schoolId = student.schoolSymbol, - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt deleted file mode 100644 index a26d7665..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.* -import io.github.wulkanowy.sdk.pojo.MailboxType -import timber.log.Timber -import io.github.wulkanowy.sdk.pojo.Message as SdkMessage -import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment -import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient - -fun List.mapToEntities( - student: Student, - mailbox: Mailbox?, - allMailboxes: List -): List = map { - Message( - messageGlobalKey = it.globalKey, - mailboxKey = mailbox?.globalKey ?: allMailboxes.find { box -> - box.fullName == it.mailbox - }?.globalKey.let { mailboxKey -> - if (mailboxKey == null) { - Timber.e("Can't find ${it.mailbox} in $allMailboxes") - "unknown" - } else mailboxKey - }, - email = student.email, - messageId = it.id, - correspondents = it.correspondents, - subject = it.subject.trim(), - date = it.date.toInstant(), - folderId = it.folderId, - unread = it.unread, - unreadBy = it.unreadBy, - readBy = it.readBy, - hasAttachments = it.hasAttachments, - ).apply { - content = it.content.orEmpty() - } -} - -fun List.mapToEntities(messageGlobalKey: String) = map { - MessageAttachment( - messageGlobalKey = messageGlobalKey, - url = it.url, - filename = it.filename - ) -} - -fun List.mapFromEntities() = map { - SdkRecipient( - fullName = it.fullName, - userName = it.userName, - studentName = it.userName, - mailboxGlobalKey = it.mailboxGlobalKey, - schoolNameShort = it.schoolShortName, - type = MailboxType.valueOf(it.type.name), - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt deleted file mode 100644 index 3818f01a..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/MobileDeviceMapper.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.MobileDevice -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.MobileDeviceToken -import io.github.wulkanowy.sdk.pojo.Device as SdkDevice -import io.github.wulkanowy.sdk.pojo.Token as SdkToken - -fun List.mapToEntities(student: Student) = map { - MobileDevice( - studentId = student.studentId, - date = it.createDate.toInstant(), - deviceId = it.id, - name = it.name - ) -} - -fun SdkToken.mapToMobileDeviceToken() = MobileDeviceToken( - token = token, - symbol = symbol, - pin = pin, - qr = qrCodeImage -) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/NoteMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/NoteMapper.kt deleted file mode 100644 index 70941799..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/NoteMapper.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.Note as SdkNote - -fun List.mapToEntities(semester: Semester) = map { - Note( - studentId = semester.studentId, - date = it.date, - teacher = it.teacher, - teacherSymbol = it.teacherSymbol, - category = it.category, - categoryType = it.categoryType.id, - isPointsShow = it.showPoints, - points = it.points, - content = it.content - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/RecipientMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/RecipientMapper.kt deleted file mode 100644 index eb993a0f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/RecipientMapper.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.MailboxType -import io.github.wulkanowy.data.db.entities.Recipient -import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient - -fun List.mapToEntities(studentMailboxGlobalKey: String) = map { - Recipient( - mailboxGlobalKey = it.mailboxGlobalKey, - fullName = it.fullName, - userName = it.userName, - studentMailboxGlobalKey = studentMailboxGlobalKey, - schoolShortName = it.schoolNameShort, - type = MailboxType.valueOf(it.type.name), - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt deleted file mode 100644 index 7e6a8166..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt +++ /dev/null @@ -1,94 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.pojos.* -import java.time.Instant -import io.github.wulkanowy.sdk.pojo.RegisterStudent as SdkRegisterStudent -import io.github.wulkanowy.sdk.pojo.RegisterUser as SdkRegisterUser - -fun SdkRegisterUser.mapToPojo(password: String?) = RegisterUser( - email = email, - login = login, - password = password, - scrapperBaseUrl = scrapperBaseUrl, - loginMode = loginMode, - loginType = loginType, - symbols = symbols.map { registerSymbol -> - RegisterSymbol( - symbol = registerSymbol.symbol, - error = registerSymbol.error, - hebeBaseUrl = registerSymbol.hebeBaseUrl, - keyId = registerSymbol.keyId, - privatePem = registerSymbol.privatePem, - userName = registerSymbol.userName, - schools = registerSymbol.schools.map { - RegisterUnit( - userLoginId = it.userLoginId, - schoolId = it.schoolId, - schoolName = it.schoolName, - schoolShortName = it.schoolShortName, - parentIds = it.parentIds, - studentIds = it.studentIds, - employeeIds = it.employeeIds, - error = it.error, - students = it.subjects - .filterIsInstance() - .map { registerStudent -> - RegisterStudent( - studentId = registerStudent.studentId, - studentName = registerStudent.studentName, - studentSecondName = registerStudent.studentSecondName, - studentSurname = registerStudent.studentSurname, - className = registerStudent.className, - classId = registerStudent.classId, - isParent = registerStudent.isParent, - isAuthorized = registerStudent.isAuthorized, - isEduOne = registerStudent.isEduOne, - semesters = registerStudent.semesters - .mapToEntities(registerStudent.studentId), - ) - }, - ) - } - ) - }, -) - -fun RegisterStudent.mapToStudentWithSemesters( - user: RegisterUser, - scrapperDomainSuffix: String, - symbol: RegisterSymbol, - unit: RegisterUnit, - colors: List, -): StudentWithSemesters = StudentWithSemesters( - semesters = semesters, - student = Student( - email = user.login, // for compatibility - userName = symbol.userName, - userLoginId = unit.userLoginId, - isParent = isParent, - className = className, - classId = classId, - studentId = studentId, - symbol = symbol.symbol, - loginType = user.loginType?.name.orEmpty(), - schoolName = unit.schoolName, - schoolShortName = unit.schoolShortName, - schoolSymbol = unit.schoolId, - studentName = "$studentName $studentSurname", - loginMode = user.loginMode.name, - scrapperBaseUrl = user.scrapperBaseUrl.orEmpty(), - scrapperDomainSuffix = scrapperDomainSuffix, - mobileBaseUrl = symbol.hebeBaseUrl.orEmpty(), - certificateKey = symbol.keyId.orEmpty(), - privateKey = symbol.privatePem.orEmpty(), - password = user.password.orEmpty(), - isCurrent = false, - registrationDate = Instant.now(), - isAuthorized = this.isAuthorized, - isEduOne = this.isEduOne, - ).apply { - avatarColor = colors.random() - }, -) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/SchoolInfoMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/SchoolInfoMapper.kt deleted file mode 100644 index dc3a5a9e..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/SchoolInfoMapper.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.School -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.pojo.School as SdkSchool - -fun SdkSchool.mapToEntity(semester: Semester) = School( - studentId = semester.studentId, - classId = semester.classId, - name = name, - address = address, - contact = contact, - headmaster = headmaster, - pedagogue = pedagogue -) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/SemesterMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/SemesterMapper.kt index 67d68a1e..acd93a91 100644 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/SemesterMapper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/SemesterMapper.kt @@ -7,7 +7,6 @@ fun List.mapToEntities(studentId: Int) = map { Semester( studentId = studentId, diaryId = it.diaryId, - kindergartenDiaryId = it.kindergartenDiaryId, diaryName = it.diaryName, schoolYear = it.schoolYear, semesterId = it.semesterId, diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentInfoMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentInfoMapper.kt deleted file mode 100644 index 9e853390..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentInfoMapper.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.StudentGuardian -import io.github.wulkanowy.data.db.entities.StudentInfo -import io.github.wulkanowy.data.enums.Gender -import io.github.wulkanowy.sdk.pojo.StudentGuardian as SdkStudentGuardian -import io.github.wulkanowy.sdk.pojo.StudentInfo as SdkStudentInfo - -fun SdkStudentInfo.mapToEntity(semester: Semester) = StudentInfo( - studentId = semester.studentId, - fullName = fullName, - firstName = firstName, - secondName = secondName, - surname = surname, - birthDate = birthDate, - birthPlace = birthPlace, - gender = Gender.valueOf(gender.name), - hasPolishCitizenship = hasPolishCitizenship, - familyName = familyName, - parentsNames = parentsNames, - address = address, - registeredAddress = registeredAddress, - correspondenceAddress = correspondenceAddress, - phoneNumber = phoneNumber, - cellPhoneNumber = phoneNumber, - email = email, - firstGuardian = guardianFirst?.mapToEntity(), - secondGuardian = guardianSecond?.mapToEntity() -) - -fun SdkStudentGuardian.mapToEntity() = StudentGuardian( - fullName = fullName, - kinship = kinship, - address = address, - phones = phones, - email = email -) diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt new file mode 100644 index 00000000..67f56c62 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/mappers/StudentMapper.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.data.mappers + +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import java.time.LocalDateTime +import io.github.wulkanowy.sdk.pojo.Student as SdkStudent + +fun List.mapToEntities(password: String = "") = map { + StudentWithSemesters( + student = Student( + email = it.email, + password = password, + isParent = it.isParent, + symbol = it.symbol, + studentId = it.studentId, + userLoginId = it.userLoginId, + userName = it.userName, + studentName = it.studentName + " " + it.studentSurname, + schoolSymbol = it.schoolSymbol, + schoolShortName = it.schoolShortName, + schoolName = it.schoolName, + className = it.className, + classId = it.classId, + scrapperBaseUrl = it.scrapperBaseUrl, + loginType = it.loginType.name, + isCurrent = false, + registrationDate = LocalDateTime.now(), + mobileBaseUrl = it.mobileBaseUrl, + privateKey = it.privateKey, + certificateKey = it.certificateKey, + loginMode = it.loginMode.name + ), + semesters = it.semesters.mapToEntities(it.studentId) + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/SubjectMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/SubjectMapper.kt deleted file mode 100644 index 4dc95aaa..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/SubjectMapper.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Subject -import io.github.wulkanowy.sdk.pojo.Subject as SdkSubject - -fun List.mapToEntities(semester: Semester) = map { - Subject( - studentId = semester.studentId, - diaryId = semester.diaryId, - name = it.name, - realId = it.id - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/TeacherMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/TeacherMapper.kt deleted file mode 100644 index 49cb7c29..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/TeacherMapper.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Teacher -import io.github.wulkanowy.sdk.pojo.Teacher as SdkTeacher - -fun List.mapToEntities(semester: Semester) = map { - Teacher( - studentId = semester.studentId, - name = it.name, - subject = it.subject, - shortName = it.short, - classId = semester.classId - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt deleted file mode 100644 index ee525e10..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/mappers/TimetableMapper.kt +++ /dev/null @@ -1,61 +0,0 @@ -package io.github.wulkanowy.data.mappers - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.db.entities.TimetableHeader -import io.github.wulkanowy.data.pojos.TimetableFull -import io.github.wulkanowy.sdk.pojo.Timetable as SdkTimetableFull -import io.github.wulkanowy.sdk.pojo.TimetableDayHeader as SdkTimetableHeader -import io.github.wulkanowy.sdk.pojo.Lesson as SdkLesson -import io.github.wulkanowy.sdk.pojo.LessonAdditional as SdkTimetableAdditional - -fun SdkTimetableFull.mapToEntities(semester: Semester) = TimetableFull( - lessons = lessons.mapToEntities(semester), - additional = additional.mapToEntities(semester), - headers = headers.mapToEntities(semester) -) - -fun List.mapToEntities(semester: Semester) = map { - Timetable( - studentId = semester.studentId, - diaryId = semester.diaryId, - number = it.number, - start = it.start.toInstant(), - end = it.end.toInstant(), - date = it.date, - subject = it.subject, - subjectOld = it.subjectOld, - group = it.group, - room = it.room, - roomOld = it.roomOld, - teacher = it.teacher, - teacherOld = it.teacherOld, - info = it.info, - isStudentPlan = it.studentPlan, - changes = it.changes, - canceled = it.canceled - ) -} - -@JvmName("mapToEntitiesTimetableAdditional") -fun List.mapToEntities(semester: Semester) = map { - TimetableAdditional( - studentId = semester.studentId, - diaryId = semester.diaryId, - subject = it.subject, - date = it.date, - start = it.start.toInstant(), - end = it.end.toInstant(), - ) -} - -@JvmName("mapToEntitiesTimetableHeaders") -fun List.mapToEntities(semester: Semester) = map { - TimetableHeader( - studentId = semester.studentId, - diaryId = semester.diaryId, - date = it.date, - content = it.content - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/AttendanceData.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/AttendanceData.kt deleted file mode 100644 index 5810363c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/AttendanceData.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.wulkanowy.data.pojos - -data class AttendanceData( - val subjectName: String, - val lessonBalance: Int, - val presences: Int, - val absences: Int, -) { - val total: Int - get() = presences + absences - - val presencePercentage: Double - get() = if (total == 0) 0.0 else (presences.toDouble() / total) * 100 -} diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/Contributor.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/Contributor.kt index 4165b3f1..d2338c28 100644 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/Contributor.kt +++ b/app/src/main/java/io/github/wulkanowy/data/pojos/Contributor.kt @@ -1,8 +1,8 @@ package io.github.wulkanowy.data.pojos -import kotlinx.serialization.Serializable +import com.squareup.moshi.JsonClass -@Serializable +@JsonClass(generateAdapter = true) class Contributor( val displayName: String, val githubUsername: String diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/GradeStatisticsItem.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/GradeStatisticsItem.kt index bdcd049d..88257470 100644 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/GradeStatisticsItem.kt +++ b/app/src/main/java/io/github/wulkanowy/data/pojos/GradeStatisticsItem.kt @@ -3,10 +3,11 @@ package io.github.wulkanowy.data.pojos import io.github.wulkanowy.data.db.entities.GradePartialStatistics import io.github.wulkanowy.data.db.entities.GradePointsStatistics import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics +import io.github.wulkanowy.ui.modules.grade.statistics.ViewType data class GradeStatisticsItem( - val type: DataType, + val type: ViewType, val average: String, @@ -15,11 +16,4 @@ data class GradeStatisticsItem( val semester: GradeSemesterStatistics?, val points: GradePointsStatistics? - -) { - enum class DataType { - SEMESTER, - PARTIAL, - POINTS, - } -} +) diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/LoginEvent.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/LoginEvent.kt deleted file mode 100644 index c2b4d2de..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/LoginEvent.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.data.pojos - -import kotlinx.serialization.Serializable - -@Serializable -data class LoginEvent( - val uuid: String, - val schoolName: String, - val schoolShort: String, - val schoolAddress: String, - val scraperBaseUrl: String, - val symbol: String, - val schoolId: String, - val loginType: String, -) - -@Serializable -data class IntegrityRequest( - val tokenString: String, - val data: T, -) diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/MessageDraft.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/MessageDraft.kt deleted file mode 100644 index 2e568e37..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/MessageDraft.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.pojos - -import io.github.wulkanowy.ui.modules.message.send.RecipientChipItem -import kotlinx.serialization.Serializable - -@Serializable -data class MessageDraft( - val recipients: List, - val subject: String, - val content: String, -) \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/NotificationData.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/NotificationData.kt deleted file mode 100644 index f4fd0fc8..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/NotificationData.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.wulkanowy.data.pojos - -import io.github.wulkanowy.services.sync.notifications.NotificationType -import io.github.wulkanowy.ui.modules.Destination - -data class NotificationData( - val destination: Destination, - val title: String, - val content: String -) - -data class GroupNotificationData( - val notificationDataList: List, - val title: String, - val content: String, - val destination: Destination, - val type: NotificationType -) - diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt deleted file mode 100644 index dec6ebec..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.wulkanowy.data.pojos - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.sdk.scrapper.Scrapper - -data class RegisterUser( - val email: String, - val password: String?, - val login: String, // may be the same as email - val scrapperBaseUrl: String?, - val loginType: Scrapper.LoginType?, - val loginMode: Sdk.Mode, - val symbols: List, -) : java.io.Serializable - -data class RegisterSymbol( - val symbol: String, - val error: Throwable?, - val hebeBaseUrl: String?, - val keyId: String?, - val privatePem: String?, - val userName: String, - val schools: List, -) : java.io.Serializable - -data class RegisterUnit( - val userLoginId: Int, - val schoolId: String, - val schoolName: String, - val schoolShortName: String, - val parentIds: List, - val studentIds: List, - val employeeIds: List, - val error: Throwable?, - val students: List, -) : java.io.Serializable - -data class RegisterStudent( - val studentId: Int, - val studentName: String, - val studentSecondName: String, - val studentSurname: String, - val className: String, - val classId: Int, - val isParent: Boolean, - val semesters: List, - val isAuthorized: Boolean, - val isEduOne: Boolean -) : java.io.Serializable diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/TimetableFull.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/TimetableFull.kt deleted file mode 100644 index ce0f6ef5..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/pojos/TimetableFull.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.data.pojos - -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.db.entities.TimetableHeader - -data class TimetableFull( - val lessons: List, - val additional: List, - val headers: List, -) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt deleted file mode 100644 index bec2797d..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/AppCreatorRepository.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.data.pojos.Contributor -import io.github.wulkanowy.utils.DispatchersProvider -import kotlinx.coroutines.withContext -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.decodeFromStream -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class AppCreatorRepository @Inject constructor( - @ApplicationContext private val context: Context, - private val dispatchers: DispatchersProvider, - private val json: Json, -) { - - @OptIn(ExperimentalSerializationApi::class) - suspend fun getAppCreators() = withContext(dispatchers.io) { - val inputStream = context.assets.open("contributors.json").buffered() - json.decodeFromStream>(inputStream) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt deleted file mode 100644 index ebe6f5db..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt +++ /dev/null @@ -1,182 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.AttendanceDao -import io.github.wulkanowy.data.db.dao.TimetableDao -import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.sdk.pojo.Absent -import io.github.wulkanowy.sdk.pojo.Attendance as SdkAttendance -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.sunday -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.sync.Mutex -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.LocalTime -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class AttendanceRepository @Inject constructor( - private val attendanceDb: AttendanceDao, - private val timetableDb: TimetableDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, - private val preferencesRepository: PreferencesRepository -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "attendance" - - private fun filterAttendance( - hiddenAttendanceTiles: List, - attendanceItem: Attendance - ): Boolean { - return when { - attendanceItem.absence && attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.EXCUSED_ABSENCE - ) -> false - - attendanceItem.absence && !attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.UNEXCUSED_ABSENCE - ) -> false - - attendanceItem.lateness && attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.EXCUSED_LATENESS - ) -> false - - attendanceItem.lateness && !attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.UNEXCUSED_LATENESS - ) -> false - - attendanceItem.exemption && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.EXEMPTION) -> false - attendanceItem.deleted && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.DELETED) -> false - attendanceItem.presence && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.PRESENT) -> false - - else -> !hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.UNKNOWN) - } - } - - private fun filterAttendance( - hiddenAttendanceTiles: List, - attendanceItem: SdkAttendance - ): Boolean { - return when { - attendanceItem.absence && attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.EXCUSED_ABSENCE - ) -> false - - attendanceItem.absence && !attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.UNEXCUSED_ABSENCE - ) -> false - - attendanceItem.lateness && attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.EXCUSED_LATENESS - ) -> false - - attendanceItem.lateness && !attendanceItem.excused && hiddenAttendanceTiles.contains( - DashboardItem.HiddenAttendanceTile.UNEXCUSED_LATENESS - ) -> false - - attendanceItem.exemption && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.EXEMPTION) -> false - attendanceItem.deleted && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.DELETED) -> false - attendanceItem.presence && hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.PRESENT) -> false - - else -> !hiddenAttendanceTiles.contains(DashboardItem.HiddenAttendanceTile.UNKNOWN) - } - } - - fun getAttendance( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - notify: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(cacheKey, semester, start, end) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems - - attendanceDb - .loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday) - .map { - it.filter { item -> filterAttendance(hiddenAttendanceItems, item) } - } - }, - fetch = { - val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems - - val lessons = timetableDb.load( - semester.diaryId, semester.studentId, start.monday, end.sunday - ) - - wulkanowySdkFactory.create(student, semester) - .getAttendance(start.monday, end.sunday) - .filter { item -> filterAttendance(hiddenAttendanceItems, item) } - .mapToEntities(semester, lessons) - }, - saveFetchResult = { old, new -> - val attendanceToAdd = (new uniqueSubtract old).map { newAttendance -> - newAttendance.apply { if (notify) isNotified = false } - } - attendanceDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = attendanceToAdd, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end)) - }, - filterResult = { it.filter { item -> item.date in start..end } } - ) - - fun getAttendanceFromDatabase( - semester: Semester, - start: LocalDate, - end: LocalDate - ): Flow> { - val hiddenAttendanceItems = preferencesRepository.hiddenAttendanceItems - - return attendanceDb - .loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday) - .map { - it.filter { item -> filterAttendance(hiddenAttendanceItems, item) } - } - } - - suspend fun updateTimetable(timetable: List) { - return attendanceDb.updateAll(timetable) - } - - suspend fun excuseForAbsence( - student: Student, - semester: Semester, - absenceList: List, - reason: String? = null - ) { - val items = absenceList.map { attendance -> - Absent( - date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)), - timeId = attendance.timeId - ) - } - wulkanowySdkFactory.create(student, semester) - .excuseForAbsence(items, reason) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceSummaryRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceSummaryRepository.kt deleted file mode 100644 index 78c98169..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceSummaryRepository.kt +++ /dev/null @@ -1,56 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import androidx.room.withTransaction -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.AppDatabase -import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class AttendanceSummaryRepository @Inject constructor( - private val attendanceDb: AttendanceSummaryDao, - private val refreshHelper: AutoRefreshHelper, - private val appDatabase: AppDatabase, - private val wulkanowySdkFactory: WulkanowySdkFactory, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "attendance_summary" - - fun getAttendanceSummary( - student: Student, - semester: Semester, - subjectId: Int, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getAttendanceSummary(subjectId) - .mapToEntities(semester, subjectId) - }, - saveFetchResult = { old, new -> - appDatabase.withTransaction { - attendanceDb.deleteAll(old uniqueSubtract new) - attendanceDb.insertAll(new uniqueSubtract old) - } - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/CompletedLessonsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/CompletedLessonsRepository.kt deleted file mode 100644 index 45a36f55..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/CompletedLessonsRepository.kt +++ /dev/null @@ -1,67 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.CompletedLessonsDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.sunday -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import java.time.LocalDate -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class CompletedLessonsRepository @Inject constructor( - private val completedLessonsDb: CompletedLessonsDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "completed" - - fun getCompletedLessons( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(cacheKey, semester, start, end) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - completedLessonsDb.loadAll( - studentId = semester.studentId, - diaryId = semester.diaryId, - from = start.monday, - end = end.sunday - ) - }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getCompletedLessons(start.monday, end.sunday) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - completedLessonsDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end)) - }, - filterResult = { it.filter { item -> item.date in start..end } } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt deleted file mode 100644 index 58ce0091..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ConferenceRepository.kt +++ /dev/null @@ -1,71 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.ConferenceDao -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.sync.Mutex -import java.time.Instant -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class ConferenceRepository @Inject constructor( - private val conferenceDb: ConferenceDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "conference" - - fun getConferences( - student: Student, - semester: Semester, - forceRefresh: Boolean, - notify: Boolean = false, - startDate: Instant = Instant.EPOCH, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - conferenceDb.loadAll(semester.diaryId, student.studentId, startDate) - }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getConferences() - .mapToEntities(semester) - .filter { it.date >= startDate } - }, - saveFetchResult = { old, new -> - conferenceDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - if (notify) it.isNotified = false - }, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) - } - ) - - fun getConferenceFromDatabase(semester: Semester): Flow> = - conferenceDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - startDate = Instant.EPOCH, - ) - - suspend fun updateConference(conference: List) = conferenceDb.updateAll(conference) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt deleted file mode 100644 index 89dbcd5c..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/ExamRepository.kt +++ /dev/null @@ -1,85 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.ExamDao -import io.github.wulkanowy.data.db.entities.Exam -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.endExamsDay -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.startExamsDay -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.sync.Mutex -import java.time.LocalDate -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class ExamRepository @Inject constructor( - private val examDb: ExamDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "exam" - - fun getExams( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - notify: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(cacheKey, semester, start, end) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - examDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - from = start.startExamsDay, - end = start.endExamsDay - ) - }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getExams(start.startExamsDay, start.endExamsDay) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - examDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - if (notify) it.isNotified = false - }, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end)) - }, - filterResult = { it.filter { item -> item.date in start..end } } - ) - - fun getExamsFromDatabase( - semester: Semester, - start: LocalDate, - end: LocalDate - ): Flow> = examDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - from = start, - end = end, - ) - - suspend fun updateExam(exam: List) = examDb.updateAll(exam) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt deleted file mode 100644 index 7a502787..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeRepository.kt +++ /dev/null @@ -1,214 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.GradeDao -import io.github.wulkanowy.data.db.dao.GradeDescriptiveDao -import io.github.wulkanowy.data.db.dao.GradeSummaryDao -import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive -import io.github.wulkanowy.data.db.entities.GradeSummary -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.toLocalDate -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.sync.Mutex -import timber.log.Timber -import java.time.Instant -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class GradeRepository @Inject constructor( - private val gradeDb: GradeDao, - private val gradeSummaryDb: GradeSummaryDao, - private val gradeDescriptiveDb: GradeDescriptiveDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, - private val preferencesRepository: PreferencesRepository -) { - - private val saveFetchResultMutex = Mutex() - - private fun loadGrades(semesterId: Int, studentId: Int): Flow> { - val hiddenGrades = preferencesRepository.hiddenGrades - - Timber.i("Load grades for semester $semesterId student $studentId") - return gradeDb.loadAllCensored(semesterId, studentId, hiddenGrades.toTypedArray()) - } - - fun getGrades( - student: Student, - semester: Semester, - forceRefresh: Boolean, - notify: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { - //When details is empty and summary is not, app will not use summary cache - edge case - it.first.isEmpty() - }, - shouldFetch = { (details, summaries, descriptive) -> - val isExpired = - refreshHelper.shouldBeRefreshed(getRefreshKey(GRADE_CACHE_KEY, semester)) - details.isEmpty() || (summaries.isEmpty() && descriptive.isEmpty()) || forceRefresh || isExpired - }, - query = { - val detailsFlow = gradeDb.loadAll(semester.semesterId, semester.studentId) - val summaryFlow = gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) - val descriptiveFlow = - gradeDescriptiveDb.loadAll(semester.semesterId, semester.studentId) - - combine(detailsFlow, summaryFlow, descriptiveFlow) { details, summaries, descriptive -> - Triple(details, summaries, descriptive) - } - }, - fetch = { - val hiddenGrades = preferencesRepository.hiddenGrades - - val (details, summary, descriptive) = wulkanowySdkFactory.create(student, semester) - .getGrades(semester.semesterId) - - val censoredDetails = details.filterNot { it.entry in hiddenGrades } - - Triple( - censoredDetails.mapToEntities(semester), - summary.mapToEntities(semester), - descriptive.mapToEntities(semester) - ) - }, - saveFetchResult = { (oldDetails, oldSummary, oldDescriptive), (newDetails, newSummary, newDescriptive) -> - refreshGradeDetails(student, oldDetails, newDetails, notify) - refreshGradeSummaries(oldSummary, newSummary, notify) - refreshGradeDescriptions(oldDescriptive, newDescriptive, notify) - - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(GRADE_CACHE_KEY, semester)) - } - ) - - private suspend fun refreshGradeDescriptions( - old: List, - new: List, - notify: Boolean - ) { - gradeDescriptiveDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - if (notify) it.isNotified = false - }, - ) - } - - private suspend fun refreshGradeDetails( - student: Student, - oldGrades: List, - newDetails: List, - notify: Boolean - ) { - val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date - ?: student.registrationDate.toLocalDate() - - gradeDb.removeOldAndSaveNew( - oldItems = oldGrades uniqueSubtract newDetails, - newItems = (newDetails uniqueSubtract oldGrades).onEach { - if (it.date >= notifyBreakDate) it.apply { - isRead = false - if (notify) isNotified = false - } - }, - ) - } - - private suspend fun refreshGradeSummaries( - oldSummaries: List, - newSummary: List, - notify: Boolean - ) { - gradeSummaryDb.removeOldAndSaveNew( - oldItems = oldSummaries uniqueSubtract newSummary, - newItems = (newSummary uniqueSubtract oldSummaries).onEach { summary -> - getGradeSummaryWithUpdatedNotificationState( - summary = summary, - oldSummary = oldSummaries.find { it.subject == summary.subject }, - notify = notify, - ) - }, - ) - } - - private fun getGradeSummaryWithUpdatedNotificationState( - summary: GradeSummary, - oldSummary: GradeSummary?, - notify: Boolean, - ) { - summary.isPredictedGradeNotified = when { - summary.predictedGrade.isEmpty() -> true - notify && oldSummary?.predictedGrade != summary.predictedGrade -> false - else -> true - } - summary.isFinalGradeNotified = when { - summary.finalGrade.isEmpty() -> true - notify && oldSummary?.finalGrade != summary.finalGrade -> false - else -> true - } - summary.predictedGradeLastChange = when { - oldSummary == null -> Instant.now() - summary.predictedGrade != oldSummary.predictedGrade -> Instant.now() - else -> oldSummary.predictedGradeLastChange - } - summary.finalGradeLastChange = when { - oldSummary == null -> Instant.now() - summary.finalGrade != oldSummary.finalGrade -> Instant.now() - else -> oldSummary.finalGradeLastChange - } - } - - fun getUnreadGrades(semester: Semester): Flow> { - return loadGrades(semester.semesterId, semester.studentId).map { - it.filter { grade -> !grade.isRead } - } - } - - fun getGradesFromDatabase(semester: Semester): Flow> { - return loadGrades(semester.semesterId, semester.studentId) - } - - fun getGradesPredictedFromDatabase(semester: Semester): Flow> { - return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) - } - - fun getGradesFinalFromDatabase(semester: Semester): Flow> { - return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) - } - - fun getGradesDescriptiveFromDatabase(semester: Semester): Flow> { - return gradeDescriptiveDb.loadAll(semester.semesterId, semester.studentId) - } - - suspend fun updateGrade(grade: Grade) { - return gradeDb.updateAll(listOf(grade)) - } - - suspend fun updateGrades(grades: List) { - return gradeDb.updateAll(grades) - } - - suspend fun updateGradesSummary(gradesSummary: List) { - return gradeSummaryDb.updateAll(gradesSummary) - } - - suspend fun updateGradesDescriptive(gradesDescriptive: List) { - return gradeDescriptiveDb.updateAll(gradesDescriptive) - } - - private companion object { - - private const val GRADE_CACHE_KEY = "grade" - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeStatisticsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/GradeStatisticsRepository.kt deleted file mode 100644 index f120d34f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/GradeStatisticsRepository.kt +++ /dev/null @@ -1,203 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao -import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao -import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao -import io.github.wulkanowy.data.db.entities.GradePartialStatistics -import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapPartialToStatisticItems -import io.github.wulkanowy.data.mappers.mapPointsToStatisticsItems -import io.github.wulkanowy.data.mappers.mapSemesterToStatisticItems -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import java.util.Locale -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class GradeStatisticsRepository @Inject constructor( - private val gradePartialStatisticsDb: GradePartialStatisticsDao, - private val gradePointsStatisticsDb: GradePointsStatisticsDao, - private val gradeSemesterStatisticsDb: GradeSemesterStatisticsDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val partialMutex = Mutex() - private val semesterMutex = Mutex() - private val pointsMutex = Mutex() - - private val partialCacheKey = "grade_stats_partial" - private val semesterCacheKey = "grade_stats_semester" - private val pointsCacheKey = "grade_stats_points" - - fun getGradesPartialStatistics( - student: Student, - semester: Semester, - subjectName: String, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = partialMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(partialCacheKey, semester) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { gradePartialStatisticsDb.loadAll(semester.semesterId, semester.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getGradesPartialStatistics(semester.semesterId) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - gradePartialStatisticsDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(partialCacheKey, semester)) - }, - mapResult = { items -> - when (subjectName) { - "Wszystkie" -> { - val summaryItem = GradePartialStatistics( - studentId = semester.studentId, - semesterId = semester.semesterId, - subject = subjectName, - classAverage = items.map { it.classAverage }.getSummaryAverage(), - studentAverage = items.map { it.studentAverage }.getSummaryAverage(), - classAmounts = items.map { it.classAmounts }.sumGradeAmounts(), - studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts() - ) - listOf(summaryItem) + items - } - - else -> items.filter { it.subject == subjectName } - }.mapPartialToStatisticItems() - } - ) - - fun getGradesSemesterStatistics( - student: Student, - semester: Semester, - subjectName: String, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = semesterMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(semesterCacheKey, semester) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { gradeSemesterStatisticsDb.loadAll(semester.semesterId, semester.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getGradesSemesterStatistics(semester.semesterId) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - gradeSemesterStatisticsDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(semesterCacheKey, semester)) - }, - mapResult = { items -> - val itemsWithAverage = items.map { item -> - item.copy().apply { - val denominator = item.amounts.sum() - classAverage = if (denominator == 0) "" else { - (item.amounts.mapIndexed { gradeValue, amount -> - (gradeValue + 1) * amount - }.sum().toDouble() / denominator).asAverageString() - } - } - } - when (subjectName) { - "Wszystkie" -> { - val summaryItem = GradeSemesterStatistics( - studentId = semester.studentId, - semesterId = semester.semesterId, - subject = subjectName, - amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(), - studentGrade = 0, - ).apply { - classAverage = itemsWithAverage.map { it.classAverage }.getSummaryAverage() - studentAverage = items - .mapNotNull { summary -> summary.studentGrade.takeIf { it != 0 } } - .average().asAverageString() - } - listOf(summaryItem) + itemsWithAverage - } - - else -> itemsWithAverage.filter { it.subject == subjectName } - }.mapSemesterToStatisticItems() - } - ) - - fun getGradesPointsStatistics( - student: Student, - semester: Semester, - subjectName: String, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = pointsMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(pointsCacheKey, semester)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getGradesPointsStatistics(semester.semesterId) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - gradePointsStatisticsDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(pointsCacheKey, semester)) - }, - mapResult = { items -> - when (subjectName) { - "Wszystkie" -> items - else -> items.filter { it.subject == subjectName } - }.mapPointsToStatisticsItems() - } - ) - - private fun List.getSummaryAverage(): String { - val averages = mapNotNull { - it.replace(",", ".").toDoubleOrNull() - } - - return averages.average() - .asAverageString() - .takeIf { averages.isNotEmpty() } - .orEmpty() - } - - private fun Double.asAverageString(): String = "%.2f".format(Locale.FRANCE, this) - - private fun List>.sumGradeAmounts(): List { - val result = mutableListOf(0, 0, 0, 0, 0, 0) - forEach { - it.forEachIndexed { grade, amount -> - result[grade] += amount - } - } - return result - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt deleted file mode 100644 index 7893ef63..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/HomeworkRepository.kt +++ /dev/null @@ -1,87 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.HomeworkDao -import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.sunday -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import java.time.LocalDate -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class HomeworkRepository @Inject constructor( - private val homeworkDb: HomeworkDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "homework" - - fun getHomework( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - notify: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(cacheKey, semester, start, end) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - homeworkDb.loadAll( - semesterId = semester.semesterId, - studentId = semester.studentId, - from = start.monday, - end = end.sunday - ) - }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getHomework(start.monday, end.sunday) - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - val filteredOld = old.filterNot { it.isAddedByUser } - - homeworkDb.removeOldAndSaveNew( - oldItems = filteredOld uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - if (notify) it.isNotified = false - }, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end)) - } - ) - - suspend fun toggleDone(homework: Homework) { - homeworkDb.updateAll(listOf(homework.apply { - isDone = !isDone - })) - } - - fun getHomeworkFromDatabase(semester: Semester, start: LocalDate, end: LocalDate) = - homeworkDb.loadAll(semester.semesterId, semester.studentId, start.monday, end.sunday) - - suspend fun updateHomework(homework: List) = homeworkDb.updateAll(homework) - - suspend fun saveHomework(homework: Homework) = homeworkDb.insertAll(listOf(homework)) - - suspend fun deleteHomework(homework: Homework) = homeworkDb.deleteAll(listOf(homework)) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/LuckyNumberRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/LuckyNumberRepository.kt deleted file mode 100644 index dfafe6c8..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/LuckyNumberRepository.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.LuckyNumberDao -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntity -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider -import io.github.wulkanowy.utils.AppWidgetUpdater -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.sync.Mutex -import java.time.LocalDate -import java.time.LocalDate.now -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class LuckyNumberRepository @Inject constructor( - private val luckyNumberDb: LuckyNumberDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val appWidgetUpdater: AppWidgetUpdater, -) { - - private val saveFetchResultMutex = Mutex() - - fun getLuckyNumber( - student: Student, - forceRefresh: Boolean, - notify: Boolean = false, - isFromAppWidget: Boolean = false - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it == null }, - shouldFetch = { it == null || forceRefresh }, - query = { luckyNumberDb.load(student.studentId, now()) }, - fetch = { - wulkanowySdkFactory.create(student) - .getLuckyNumber(student.schoolShortName) - ?.mapToEntity(student) - }, - saveFetchResult = { oldLuckyNumber, newLuckyNumber -> - newLuckyNumber ?: return@networkBoundResource - - if (newLuckyNumber != oldLuckyNumber) { - luckyNumberDb.removeOldAndSaveNew( - oldItems = listOfNotNull(oldLuckyNumber), - newItems = listOf(newLuckyNumber.apply { if (notify) isNotified = false }), - ) - if (!isFromAppWidget) { - appWidgetUpdater.updateAllAppWidgetsByProvider(LuckyNumberWidgetProvider::class) - } - } - } - ) - - fun getLuckyNumberHistory(student: Student, start: LocalDate, end: LocalDate) = - luckyNumberDb.getAll(student.studentId, start, end) - - suspend fun getNotNotifiedLuckyNumber(student: Student) = - luckyNumberDb.load(student.studentId, now()).map { - if (it?.isNotified == false) it else null - }.first() - - suspend fun updateLuckyNumber(luckyNumber: LuckyNumber?) = - luckyNumberDb.updateAll(listOfNotNull(luckyNumber)) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt deleted file mode 100644 index f91dc63e..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt +++ /dev/null @@ -1,286 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.db.dao.MailboxDao -import io.github.wulkanowy.data.db.dao.MessageAttachmentDao -import io.github.wulkanowy.data.db.dao.MessagesDao -import io.github.wulkanowy.data.db.dao.MutedMessageSendersDao -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.db.entities.MessageWithAttachment -import io.github.wulkanowy.data.db.entities.MessageWithMutedAuthor -import io.github.wulkanowy.data.db.entities.MutedMessageSender -import io.github.wulkanowy.data.db.entities.Recipient -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.enums.MessageFolder -import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED -import io.github.wulkanowy.data.enums.MessageFolder.SENT -import io.github.wulkanowy.data.enums.MessageFolder.TRASHED -import io.github.wulkanowy.data.mappers.mapFromEntities -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.pojos.MessageDraft -import io.github.wulkanowy.data.toFirstResult -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase -import io.github.wulkanowy.sdk.pojo.Folder -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.sync.Mutex -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class MessageRepository @Inject constructor( - private val messagesDb: MessagesDao, - private val mutedMessageSendersDao: MutedMessageSendersDao, - private val messageAttachmentDao: MessageAttachmentDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - @ApplicationContext private val context: Context, - private val refreshHelper: AutoRefreshHelper, - private val sharedPrefProvider: SharedPrefProvider, - private val json: Json, - private val mailboxDao: MailboxDao, - private val getMailboxByStudentUseCase: GetMailboxByStudentUseCase, -) { - private val saveFetchResultMutex = Mutex() - - private val messagesCacheKey = "message" - private val mailboxCacheKey = "mailboxes" - - fun getMessages( - student: Student, - mailbox: Mailbox?, - folder: MessageFolder, - forceRefresh: Boolean, - notify: Boolean = false, - ): Flow>> = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(messagesCacheKey, mailbox, folder) - ) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - if (mailbox == null) { - messagesDb.loadMessagesWithMutedAuthor(folder.id, student.email) - } else messagesDb.loadMessagesWithMutedAuthor(mailbox.globalKey, folder.id) - }, - fetch = { - wulkanowySdkFactory.create(student) - .getMessages( - folder = Folder.valueOf(folder.name), - mailboxKey = mailbox?.globalKey, - ) - .mapToEntities( - student = student, - mailbox = mailbox, - allMailboxes = mailboxDao.loadAll(student.email) - ) - }, - saveFetchResult = { oldWithAuthors, new -> - val old = oldWithAuthors.map { it.message } - messagesDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - val muted = isMuted(it.correspondents) - it.isNotified = !notify || muted - }, - ) - refreshHelper.updateLastRefreshTimestamp( - getRefreshKey(messagesCacheKey, mailbox, folder) - ) - } - ) - - fun getMessage( - student: Student, - message: Message, - markAsRead: Boolean = false, - ): Flow> = networkBoundResource( - isResultEmpty = { it?.message?.content.isNullOrBlank() }, - shouldFetch = { - checkNotNull(it) { "This message no longer exist!" } - Timber.d("Message content in db empty: ${it.message.content.isBlank()}") - (it.message.unread && markAsRead) || it.message.content.isBlank() - }, - query = { messagesDb.loadMessageWithAttachment(message.messageGlobalKey) }, - fetch = { - wulkanowySdkFactory.create(student) - .getMessageDetails( - messageKey = message.messageGlobalKey, - markAsRead = message.unread && markAsRead, - ) - }, - saveFetchResult = { old, new -> - checkNotNull(old) { "Fetched message no longer exist!" } - messagesDb.updateAll( - listOf(old.message.apply { - id = message.id - unread = when { - markAsRead -> false - else -> unread - } - sender = new.sender - recipients = new.recipients.singleOrNull() ?: "Wielu adresatów" - content = content.ifBlank { new.content } - }) - ) - messageAttachmentDao.insertAttachments( - items = new.attachments.mapToEntities(message.messageGlobalKey), - ) - - Timber.d("Message ${message.messageId} with blank content: ${old.message.content.isBlank()}, marked as read: $markAsRead") - } - ) - - fun getMessagesFromDatabase(student: Student, mailbox: Mailbox?): Flow> { - return if (mailbox == null) { - messagesDb.loadAll(RECEIVED.id, student.email) - } else messagesDb.loadAll(mailbox.globalKey, RECEIVED.id) - } - - suspend fun updateMessages(messages: List) { - return messagesDb.updateAll(messages) - } - - suspend fun sendMessage( - student: Student, - subject: String, - content: String, - recipients: List, - mailbox: Mailbox, - ) { - wulkanowySdkFactory.create(student) - .sendMessage( - subject = subject, - content = content, - recipients = recipients.mapFromEntities(), - mailboxId = mailbox.globalKey, - ) - refreshFolders(student, mailbox, listOf(SENT)) - } - - suspend fun restoreMessages(student: Student, mailbox: Mailbox?, messages: List) { - wulkanowySdkFactory.create(student) - .restoreMessages(messages = messages.map { it.messageGlobalKey }) - - refreshFolders(student, mailbox) - } - - suspend fun deleteMessage(student: Student, message: Message) { - deleteMessages(student, listOf(message)) - } - - suspend fun deleteMessages(student: Student, messages: List) { - val firstMessage = messages.first() - wulkanowySdkFactory.create(student) - .deleteMessages( - messages = messages.map { it.messageGlobalKey }, - removeForever = firstMessage.folderId == TRASHED.id, - ) - - if (firstMessage.folderId != TRASHED.id) { - val deletedMessages = messages.map { - it.copy(folderId = TRASHED.id) - .apply { - id = it.id - content = it.content - sender = it.sender - recipients = it.recipients - } - } - - messagesDb.updateAll(deletedMessages) - } else { - messagesDb.deleteAll(messages) - } - } - - private suspend fun refreshFolders( - student: Student, - mailbox: Mailbox?, - folders: List = MessageFolder.entries - ) { - folders.forEach { - getMessages( - student = student, - mailbox = mailbox, - folder = it, - forceRefresh = true, - ).toFirstResult() - } - } - - suspend fun getMailboxes(student: Student, forceRefresh: Boolean) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(mailboxCacheKey, student), - ) - it.isEmpty() || isExpired || forceRefresh - }, - query = { mailboxDao.loadAll(student.email, student.symbol, student.schoolSymbol) }, - fetch = { - wulkanowySdkFactory.create(student) - .getMailboxes() - .mapToEntities(student) - }, - saveFetchResult = { old, new -> - mailboxDao.deleteAll(old uniqueSubtract new) - mailboxDao.insertAll(new uniqueSubtract old) - - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(mailboxCacheKey, student)) - } - ) - - suspend fun getMailboxByStudent(student: Student): Mailbox? { - val mailbox = getMailboxByStudentUseCase(student) - - return if (mailbox == null) { - getMailboxes(student, forceRefresh = true) - .onResourceError { throw it } - .onResourceSuccess { Timber.i("Found ${it.size} new mailboxes") } - .waitForResult() - - getMailboxByStudentUseCase(student) - } else mailbox - } - - var draftMessage: MessageDraft? - get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_draft)) - ?.let { json.decodeFromString(it) } - set(value) = sharedPrefProvider.putString( - context.getString(R.string.pref_key_message_draft), - value?.let { json.encodeToString(it) } - ) - - private suspend fun isMuted(author: String): Boolean { - return mutedMessageSendersDao.checkMute(author) - } - - suspend fun muteMessage(author: String) { - if (isMuted(author)) return - mutedMessageSendersDao.insertMute(MutedMessageSender(author)) - } - - suspend fun unmuteMessage(author: String) { - if (!isMuted(author)) return - mutedMessageSendersDao.deleteMute(author) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/MobileDeviceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/MobileDeviceRepository.kt deleted file mode 100644 index 1303d0e7..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/MobileDeviceRepository.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.MobileDeviceDao -import io.github.wulkanowy.data.db.entities.MobileDevice -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.mappers.mapToMobileDeviceToken -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.data.pojos.MobileDeviceToken -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class MobileDeviceRepository @Inject constructor( - private val mobileDb: MobileDeviceDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "devices" - - fun getDevices( - student: Student, - semester: Semester, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { mobileDb.loadAll(student.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getRegisteredDevices() - .mapToEntities(student) - }, - saveFetchResult = { old, new -> - mobileDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student)) - } - ) - - suspend fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice) { - wulkanowySdkFactory.create(student, semester) - .unregisterDevice(device.deviceId) - - mobileDb.deleteAll(listOf(device)) - } - - suspend fun getToken(student: Student, semester: Semester): MobileDeviceToken { - return wulkanowySdkFactory.create(student, semester) - .getToken() - .mapToMobileDeviceToken() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt deleted file mode 100644 index 6be0928e..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/NoteRepository.kt +++ /dev/null @@ -1,81 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.NoteDao -import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.toLocalDate -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class NoteRepository @Inject constructor( - private val noteDb: NoteDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, - private val preferencesRepository: PreferencesRepository -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "note" - - fun getNotes( - student: Student, - semester: Semester, - forceRefresh: Boolean, - notify: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - getRefreshKey(cacheKey, semester) - ) - - it.isEmpty() || forceRefresh || isExpired - }, - query = { noteDb.loadAll(student.studentId) }, - fetch = { - val showNotes = preferencesRepository.showNotes - - wulkanowySdkFactory.create(student, semester) - .getNotes() - .filter { showNotes } - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - val notesToAdd = (new uniqueSubtract old).onEach { - if (it.date >= student.registrationDate.toLocalDate()) it.apply { - isRead = false - if (notify) isNotified = false - } - } - noteDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = notesToAdd, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) - } - ) - - fun getNotesFromDatabase(student: Student): Flow> { - return noteDb.loadAll(student.studentId) - } - - suspend fun updateNote(note: Note) { - noteDb.updateAll(listOf(note)) - } - - suspend fun updateNotes(notes: List) { - noteDb.updateAll(notes) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/NotificationRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/NotificationRepository.kt deleted file mode 100644 index fca26378..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/NotificationRepository.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.db.dao.NotificationDao -import io.github.wulkanowy.data.db.entities.Notification -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class NotificationRepository @Inject constructor( - private val notificationDao: NotificationDao, -) { - - fun getNotifications(studentId: Long) = notificationDao.loadAll(studentId) - - suspend fun saveNotification(notification: Notification) = - notificationDao.insertAll(listOf(notification)) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt deleted file mode 100644 index 0cc883a0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt +++ /dev/null @@ -1,504 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import android.content.Context -import android.content.SharedPreferences -import androidx.annotation.StringRes -import androidx.core.content.edit -import com.fredporciuncula.flow.preferences.FlowSharedPreferences -import com.fredporciuncula.flow.preferences.Preference -import com.fredporciuncula.flow.preferences.Serializer -import com.fredporciuncula.flow.preferences.map -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.api.models.Mapping -import io.github.wulkanowy.data.enums.AppTheme -import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.enums.GradeExpandMode -import io.github.wulkanowy.data.enums.GradeSortingMode -import io.github.wulkanowy.data.enums.ShowAdditionalLessonsMode -import io.github.wulkanowy.data.enums.TimetableGapsMode -import io.github.wulkanowy.data.enums.TimetableMode -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import io.github.wulkanowy.ui.modules.grade.GradeAverageMode -import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import timber.log.Timber -import java.time.Instant -import java.util.UUID -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class PreferencesRepository @Inject constructor( - @ApplicationContext val context: Context, - private val sharedPref: SharedPreferences, - private val flowSharedPref: FlowSharedPreferences, - private val json: Json, -) { - private val NO_ATTENDANCE_VALUE = -1.0 - - val isShowPresent: Boolean - get() = getBoolean( - R.string.pref_key_attendance_present, - R.bool.pref_default_attendance_present - ) - - val targetAttendanceFlow: Flow - get() = flowSharedPref.getInt( - context.getString(R.string.pref_key_attendance_target), - context.resources.getInteger(R.integer.pref_default_attendance_target) - ).asFlow() - - val attendanceCalculatorSortingModeFlow: Flow - get() = flowSharedPref.getString( - context.getString(R.string.pref_key_attendance_calculator_sorting_mode), - context.resources.getString(R.string.pref_default_attendance_calculator_sorting_mode) - ).asFlow().map(AttendanceCalculatorSortingMode::getByValue) - - /** - * Subjects are empty when they don't have any attendances (total = 0, attendances = 0, absences = 0). - */ - val attendanceCalculatorShowEmptySubjects: Flow - get() = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_attendance_calculator_show_empty_subjects), - context.resources.getBoolean(R.bool.pref_default_attendance_calculator_show_empty_subjects) - ).asFlow() - - private val gradeAverageModePref: Preference - get() = getObjectFlow( - R.string.pref_key_grade_average_mode, - R.string.pref_default_grade_average_mode, - object : Serializer { - override fun serialize(value: GradeAverageMode) = value.value - override fun deserialize(serialized: String) = - GradeAverageMode.getByValue(serialized) - }, - ) - - val gradeAverageModeFlow: Flow - get() = gradeAverageModePref.asFlow() - - private val gradeAverageForceCalcPref: Preference - get() = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_grade_average_force_calc), - context.resources.getBoolean(R.bool.pref_default_grade_average_force_calc) - ) - - val gradeAverageForceCalcFlow: Flow - get() = gradeAverageForceCalcPref.asFlow() - - val gradeExpandMode: GradeExpandMode - get() = GradeExpandMode.getByValue( - getString( - R.string.pref_key_expand_grade_mode, - R.string.pref_default_expand_grade_mode - ) - ) - - val showAllSubjectsOnStatisticsList: Boolean - get() = getBoolean( - R.string.pref_key_grade_statistics_list, - R.bool.pref_default_grade_statistics_list - ) - - val appThemeKey = context.getString(R.string.pref_key_app_theme) - val appTheme: AppTheme - get() = AppTheme.getByValue(getString(appThemeKey, R.string.pref_default_app_theme)) - - val gradeColorTheme: GradeColorTheme - get() = GradeColorTheme.getByValue( - getString( - R.string.pref_key_grade_color_scheme, - R.string.pref_default_grade_color_scheme - ) - ) - - val appLanguageKey = context.getString(R.string.pref_key_app_language) - val appLanguage - get() = getString(appLanguageKey, R.string.pref_default_app_language) - - val serviceEnableKey = context.getString(R.string.pref_key_services_enable) - val isServiceEnabled: Boolean - get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable) - - val servicesIntervalKey = context.getString(R.string.pref_key_services_interval) - val servicesInterval: Long - get() = getString(servicesIntervalKey, R.string.pref_default_services_interval).toLong() - - val servicesOnlyWifiKey = context.getString(R.string.pref_key_services_wifi_only) - val isServicesOnlyWifi: Boolean - get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only) - - val notificationsEnableKey = context.getString(R.string.pref_key_notifications_enable) - val isNotificationsEnable: Boolean - get() = getBoolean(notificationsEnableKey, R.bool.pref_default_notifications_enable) - - val isUpcomingLessonsNotificationsEnableKey = - context.getString(R.string.pref_key_notifications_upcoming_lessons_enable) - var isUpcomingLessonsNotificationsEnable: Boolean - set(value) { - sharedPref.edit { putBoolean(isUpcomingLessonsNotificationsEnableKey, value) } - } - get() = getBoolean( - isUpcomingLessonsNotificationsEnableKey, - R.bool.pref_default_notification_upcoming_lessons_enable - ) - - val isUpcomingLessonsNotificationsPersistentKey = - context.getString(R.string.pref_key_notifications_upcoming_lessons_persistent) - val isUpcomingLessonsNotificationsPersistent: Boolean - get() = getBoolean( - isUpcomingLessonsNotificationsPersistentKey, - R.bool.pref_default_notification_upcoming_lessons_persistent - ) - - val isNotificationPiggybackEnabledKey = - context.getString(R.string.pref_key_notifications_piggyback) - val isNotificationPiggybackEnabled: Boolean - get() = getBoolean( - R.string.pref_key_notifications_piggyback, - R.bool.pref_default_notification_piggyback - ) - - val isNotificationPiggybackRemoveOriginalEnabled: Boolean - get() = getBoolean( - R.string.pref_key_notifications_piggyback_cancel_original, - R.bool.pref_default_notification_piggyback_cancel_original - ) - - val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug) - val isDebugNotificationEnable: Boolean - get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug) - - val gradePlusModifier: Double - get() = getString( - R.string.pref_key_grade_modifier_plus, - R.string.pref_default_grade_modifier_plus - ).toDouble() - - val gradePlusModifierFlow: Flow - get() = getStringFlow( - R.string.pref_key_grade_modifier_plus, - R.string.pref_default_grade_modifier_plus - ).asFlow().map { it.toDouble() } - - val gradeMinusModifier: Double - get() = getString( - R.string.pref_key_grade_modifier_minus, - R.string.pref_default_grade_modifier_minus - ).toDouble() - - val gradeMinusModifierFlow: Flow - get() = getStringFlow( - R.string.pref_key_grade_modifier_minus, - R.string.pref_default_grade_modifier_minus - ).asFlow().map { it.toDouble() } - - val fillMessageContent: Boolean - get() = getBoolean( - R.string.pref_key_fill_message_content, - R.bool.pref_default_fill_message_content - ) - - val showGroupsInPlan: Boolean - get() = getBoolean( - R.string.pref_key_timetable_show_groups, - R.bool.pref_default_timetable_show_groups - ) - - val showWholeClassPlan: TimetableMode - get() = TimetableMode.getByValue( - getString( - R.string.pref_key_timetable_show_whole_class, - R.string.pref_default_timetable_show_whole_class - ) - ) - - val showAdditionalLessonsInPlan: ShowAdditionalLessonsMode - get() = getString( - R.string.pref_key_timetable_show_additional_lessons, - R.string.pref_default_timetable_show_additional_lessons - ).let { ShowAdditionalLessonsMode.getByValue(it) } - - val gradeSortingMode: GradeSortingMode - get() = GradeSortingMode.getByValue( - getString( - R.string.pref_key_grade_sorting_mode, - R.string.pref_default_grade_sorting_mode - ) - ) - - val showTimetableGaps: TimetableGapsMode - get() = TimetableGapsMode.getByValue( - getString( - R.string.pref_key_timetable_show_gaps, - R.string.pref_default_timetable_show_gaps - ) - ) - - val showSubjectsWithoutGrades: Boolean - get() = getBoolean( - R.string.pref_key_subjects_without_grades, - R.bool.pref_default_subjects_without_grades - ) - - val isOptionalArithmeticAverageFlow: Flow - get() = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_optional_arithmetic_average), - context.resources.getBoolean(R.bool.pref_default_optional_arithmetic_average) - ).asFlow() - - var lasSyncDate: Instant? - get() = getLong(R.string.pref_key_last_sync_date, R.string.pref_default_last_sync_date) - .takeIf { it != 0L }?.let(Instant::ofEpochMilli) - set(value) = sharedPref.edit().putLong("last_sync_date", value?.toEpochMilli() ?: 0).apply() - - var dashboardItemsPosition: Map? - get() { - val value = sharedPref.getString(PREF_KEY_DASHBOARD_ITEMS_POSITION, null) ?: return null - - return json.decodeFromString(value) - } - set(value) = sharedPref.edit { - putString( - PREF_KEY_DASHBOARD_ITEMS_POSITION, - json.encodeToString(value) - ) - } - - val selectedDashboardTilesFlow: Flow> - get() = selectedDashboardTilesPreference.asFlow() - .map { set -> - set.map { DashboardItem.Tile.valueOf(it) } - .plus( - listOfNotNull( - DashboardItem.Tile.ACCOUNT, - DashboardItem.Tile.ADMIN_MESSAGE, - DashboardItem.Tile.ADS.takeIf { isAdsEnabled } - ) - ) - .toSet() - } - - var selectedDashboardTiles: Set - get() = selectedDashboardTilesPreference.get() - .map { DashboardItem.Tile.valueOf(it) } - .plus( - listOfNotNull( - DashboardItem.Tile.ACCOUNT, - DashboardItem.Tile.ADMIN_MESSAGE, - DashboardItem.Tile.ADS.takeIf { isAdsEnabled } - ) - ) - .toSet() - set(value) { - val filteredValue = value.filterNot { - it == DashboardItem.Tile.ACCOUNT || it == DashboardItem.Tile.ADMIN_MESSAGE - } - .map { it.name } - .toSet() - - selectedDashboardTilesPreference.set(filteredValue) - } - - var attendancePercentage: Double? - get() = attendancePercentagePreference.get().takeIf { it != NO_ATTENDANCE_VALUE } - set(value) = attendancePercentagePreference.set(value ?: NO_ATTENDANCE_VALUE) - - var hiddenAttendanceItems: List - get() = hiddenAttendanceItemsPreference.get().toList() - set(value) = hiddenAttendanceItemsPreference.set(value.toSet()) - - var hiddenGrades: List - get() = hiddenGradesPreference.get().toList() - set(value) = hiddenGradesPreference.set(value.toSet()) - - var showNotes: Boolean - get() = showNotesPreference.get() - set(value) = showNotesPreference.set(value) - - var developerMode: Boolean - get() = developerModePreference.get() - set(value) = developerModePreference.set(value) - - private val developerModePreference: Preference - get() = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_developer_mode), - context.resources.getBoolean(R.bool.pref_default_developer_mode) - ) - - private val hiddenGradesPreference: Preference> - get() { - val defaultSet = context.resources.getStringArray(R.array.pref_default_hidden_grades).toSet() - val prefKey = "hidden_grades" - - return flowSharedPref.getStringSet(prefKey, defaultSet) - } - - private val showNotesPreference: Preference - get() = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_show_notes), - context.resources.getBoolean(R.bool.pref_default_show_notes) - ) - - private val hiddenAttendanceItemsPreference: Preference> - get() { - val defaultSet = - context.resources.getStringArray(R.array.pref_default_hidden_attendance_items).toSet() - val prefKey = "attendance_items" - - return flowSharedPref - .getStringSet(prefKey, defaultSet) - .map( - mapper = { it -> it.map { DashboardItem.HiddenAttendanceTile.valueOf(it) }.toSet() }, - reverse = { it -> it.map { it.name }.toSet() } - ) - } - - private val selectedDashboardTilesPreference: Preference> - get() { - val defaultSet = - context.resources.getStringArray(R.array.pref_default_dashboard_tiles).toSet() - val prefKey = context.getString(R.string.pref_key_dashboard_tiles) - - return flowSharedPref.getStringSet(prefKey, defaultSet) - } - - private val attendancePercentagePreference: Preference - get() { - val prefKey = context.getString(R.string.pref_key_attendance_percentage) - val defaultValue = context.resources.getString(R.string.pref_default_attendance_percentage) - - return flowSharedPref - .getString(prefKey, defaultValue) - .map( - mapper = { it.toDoubleOrNull() ?: NO_ATTENDANCE_VALUE }, - reverse = { it.toString() } - ) - } - - var dismissedAdminMessageIds: List - get() = sharedPref.getStringSet(PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS, emptySet()) - .orEmpty() - .map { it.toInt() } - set(value) = sharedPref.edit { - putStringSet(PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS, value.map { it.toString() }.toSet()) - } - - var inAppReviewCount: Int - get() = sharedPref.getInt(PREF_KEY_IN_APP_REVIEW_COUNT, 0) - set(value) = sharedPref.edit().putInt(PREF_KEY_IN_APP_REVIEW_COUNT, value).apply() - - var inAppReviewDate: Instant? - get() = sharedPref.getLong(PREF_KEY_IN_APP_REVIEW_DATE, 0).takeIf { it != 0L } - ?.let(Instant::ofEpochMilli) - set(value) = sharedPref.edit { - putLong(PREF_KEY_IN_APP_REVIEW_DATE, value?.toEpochMilli() ?: 0) - } - - var isAppReviewDone: Boolean - get() = sharedPref.getBoolean(PREF_KEY_IN_APP_REVIEW_DONE, false) - set(value) = sharedPref.edit { putBoolean(PREF_KEY_IN_APP_REVIEW_DONE, value) } - - var isAppSupportShown: Boolean - get() = sharedPref.getBoolean(PREF_KEY_APP_SUPPORT_SHOWN, false) - set(value) = sharedPref.edit { putBoolean(PREF_KEY_APP_SUPPORT_SHOWN, value) } - - val isAdsEnabledFlow = flowSharedPref.getBoolean( - context.getString(R.string.pref_key_ads_enabled), - context.resources.getBoolean(R.bool.pref_default_ads_enabled) - ).asFlow() - - var isAdsEnabled: Boolean - get() = getBoolean( - R.string.pref_key_ads_enabled, - R.bool.pref_default_ads_enabled - ) - set(value) = sharedPref.edit { - putBoolean(context.getString(R.string.pref_key_ads_enabled), value) - } - - var appMenuItemOrder: List - get() { - val value = sharedPref.getString(PREF_KEY_APP_MENU_ITEM_ORDER, null) - ?: return AppMenuItem.defaultAppMenuItemList - - return json.decodeFromString(value) - } - set(value) = sharedPref.edit { - putString( - PREF_KEY_APP_MENU_ITEM_ORDER, - json.encodeToString(value) - ) - } - - var isIncognitoMode: Boolean - get() = getBoolean(R.string.pref_key_incognito_moge, R.bool.pref_default_incognito_mode) - set(value) = sharedPref.edit { - putBoolean(context.getString(R.string.pref_key_incognito_moge), value) - } - - var installationId: String - get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty() - private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) } - - var mapping: Mapping? - get() { - val value = sharedPref.getString("mapping", null) - return value?.let { json.decodeFromString(it) } - } - set(value) = sharedPref.edit(commit = true) { - putString("mapping", value?.let { json.encodeToString(it) }) - } - - init { - if (installationId.isEmpty()) { - installationId = UUID.randomUUID().toString() - } - } - - private fun getLong(id: Int, default: Int) = getLong(context.getString(id), default) - - private fun getLong(id: String, default: Int) = - sharedPref.getLong(id, context.resources.getString(default).toLong()) - - private fun getStringFlow(id: Int, default: Int) = - flowSharedPref.getString(context.getString(id), context.getString(default)) - - private fun getObjectFlow( - @StringRes id: Int, - @StringRes default: Int, - serializer: Serializer - ): Preference = flowSharedPref.getObject( - key = context.getString(id), - serializer = serializer, - defaultValue = serializer.deserialize( - flowSharedPref.getString(context.getString(default)).get() - ) - ) - - private fun getString(id: Int, default: Int) = getString(context.getString(id), default) - - private fun getString(id: String, default: Int) = - sharedPref.getString(id, context.getString(default)) ?: context.getString(default) - - private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default) - - private fun getBoolean(id: String, default: Int) = - sharedPref.getBoolean(id, context.resources.getBoolean(default)) - - private companion object { - private const val PREF_KEY_APP_MENU_ITEM_ORDER = "app_menu_item_order" - private const val PREF_KEY_INSTALLATION_ID = "installation_id" - private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position" - private const val PREF_KEY_IN_APP_REVIEW_COUNT = "in_app_review_count" - private const val PREF_KEY_IN_APP_REVIEW_DATE = "in_app_review_date" - private const val PREF_KEY_IN_APP_REVIEW_DONE = "in_app_review_done" - private const val PREF_KEY_APP_SUPPORT_SHOWN = "app_support_shown" - private const val PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS = "admin_message_dismissed_ids" - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt deleted file mode 100644 index 8233d932..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt +++ /dev/null @@ -1,69 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.RecipientDao -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.MailboxType -import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.db.entities.Recipient -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RecipientRepository @Inject constructor( - private val recipientDb: RecipientDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val cacheKey = "recipient" - - suspend fun refreshRecipients(student: Student, mailbox: Mailbox, type: MailboxType) { - val new = wulkanowySdkFactory.create(student) - .getRecipients(mailbox.globalKey) - .mapToEntities(mailbox.globalKey) - val old = recipientDb.loadAll(type, mailbox.globalKey) - - recipientDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student)) - } - - suspend fun getRecipients( - student: Student, - mailbox: Mailbox?, - type: MailboxType, - ): List { - mailbox ?: return emptyList() - - val cached = recipientDb.loadAll(type, mailbox.globalKey) - - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student)) - return if (cached.isEmpty() || isExpired) { - refreshRecipients(student, mailbox, type) - recipientDb.loadAll(type, mailbox.globalKey) - } else cached - } - - suspend fun getMessageSender( - student: Student, - mailbox: Mailbox?, - message: Message, - ): List { - mailbox ?: return emptyList() - - return wulkanowySdkFactory.create(student) - .getMessageReplayDetails(message.messageGlobalKey) - .sender - .let(::listOf) - .mapToEntities(mailbox.globalKey) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/RecoverRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/RecoverRepository.kt deleted file mode 100644 index b554bda0..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/RecoverRepository.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RecoverRepository @Inject constructor( - private val wulkanowySdkFactory: WulkanowySdkFactory -) { - - suspend fun getReCaptchaSiteKey(host: String, symbol: String): Pair = - wulkanowySdkFactory.create() - .getPasswordResetCaptchaCode(host, symbol) - - suspend fun sendRecoverRequest( - url: String, - symbol: String, - email: String, - reCaptchaResponse: String - ): String = wulkanowySdkFactory.create() - .sendPasswordResetRequest(url, symbol, email, reCaptchaResponse) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt deleted file mode 100644 index 78d95699..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolAnnouncementRepository.kt +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SchoolAnnouncementRepository @Inject constructor( - private val schoolAnnouncementDb: SchoolAnnouncementDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "school_announcement" - - fun getSchoolAnnouncements( - student: Student, - forceRefresh: Boolean, - notify: Boolean = false - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { - schoolAnnouncementDb.loadAll(student.studentId) - }, - fetch = { - val sdk = wulkanowySdkFactory.create(student) - val lastAnnouncements = sdk.getLastAnnouncements().mapToEntities(student) - val directorInformation = sdk.getDirectorInformation().mapToEntities(student) - lastAnnouncements + directorInformation - }, - saveFetchResult = { old, new -> - schoolAnnouncementDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = (new uniqueSubtract old).onEach { - if (notify) it.isNotified = false - }, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student)) - } - ) - - fun getSchoolAnnouncementFromDatabase(student: Student): Flow> { - return schoolAnnouncementDb.loadAll(student.studentId) - } - - suspend fun updateSchoolAnnouncement(schoolAnnouncement: List) = - schoolAnnouncementDb.updateAll(schoolAnnouncement) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolRepository.kt deleted file mode 100644 index c48abb6f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolRepository.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.SchoolDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntity -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SchoolRepository @Inject constructor( - private val schoolDb: SchoolDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "school_info" - - fun getSchoolInfo( - student: Student, - semester: Semester, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it == null }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed( - key = getRefreshKey(cacheKey, student) - ) - it == null || forceRefresh || isExpired - }, - query = { schoolDb.load(semester.studentId, semester.classId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getSchool() - .mapToEntity(semester) - }, - saveFetchResult = { old, new -> - if (old != null && new != old) { - schoolDb.removeOldAndSaveNew( - oldItems = listOf(old), - newItems = listOf(new) - ) - } else if (old == null) { - schoolDb.insertAll(listOf(new)) - } - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student)) - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt deleted file mode 100644 index 25da241a..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SchoolsRepository.kt +++ /dev/null @@ -1,62 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.api.services.SchoolsService -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.pojos.IntegrityRequest -import io.github.wulkanowy.data.pojos.LoginEvent -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.utils.IntegrityHelper -import io.github.wulkanowy.utils.getCurrentOrLast -import kotlinx.coroutines.withTimeout -import timber.log.Timber -import java.util.UUID -import javax.inject.Inject -import javax.inject.Singleton -import kotlin.time.Duration.Companion.seconds - -@Singleton -class SchoolsRepository @Inject constructor( - private val integrityHelper: IntegrityHelper, - private val schoolsService: SchoolsService, - private val wulkanowySdkFactory: WulkanowySdkFactory, -) { - - suspend fun logSchoolLogin(loginData: LoginData, students: List) { - students.forEach { - runCatching { - withTimeout(10.seconds) { - logLogin(loginData, it.student, it.semesters.getCurrentOrLast()) - } - } - .onFailure { Timber.e(it) } - } - } - - private suspend fun logLogin(loginData: LoginData, student: Student, semester: Semester) { - val requestId = UUID.randomUUID().toString() - val token = integrityHelper.getIntegrityToken(requestId) ?: return - val updatedStudent = student.copy(password = loginData.password) - - val schoolInfo = wulkanowySdkFactory.create(updatedStudent, semester) - .getSchool() - - schoolsService.logLoginEvent( - IntegrityRequest( - tokenString = token, - data = LoginEvent( - uuid = requestId, - schoolAddress = schoolInfo.address, - schoolName = schoolInfo.name, - schoolShort = student.schoolShortName, - scraperBaseUrl = student.scrapperBaseUrl, - loginType = student.loginType, - symbol = student.symbol, - schoolId = student.schoolSymbol, - ) - ) - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt deleted file mode 100644 index 92d44650..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SemesterRepository.kt +++ /dev/null @@ -1,83 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.SemesterDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.utils.DispatchersProvider -import io.github.wulkanowy.utils.getCurrentOrLast -import io.github.wulkanowy.utils.isCurrent -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.withContext -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SemesterRepository @Inject constructor( - private val semesterDb: SemesterDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val dispatchers: DispatchersProvider, -) { - - suspend fun getSemesters( - student: Student, - forceRefresh: Boolean = false, - refreshOnNoCurrent: Boolean = false - ) = withContext(dispatchers.io) { - val semesters = semesterDb.loadAll(student.studentId, student.classId) - - if (isShouldFetch(student, semesters, forceRefresh, refreshOnNoCurrent)) { - refreshSemesters(student) - semesterDb.loadAll(student.studentId, student.classId) - } else semesters - } - - private fun isShouldFetch( - student: Student, - semesters: List, - forceRefresh: Boolean, - refreshOnNoCurrent: Boolean - ): Boolean { - val isNoSemesters = semesters.isEmpty() - - val isRefreshOnModeChangeRequired = when { - Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE -> { - semesters.firstOrNull { it.isCurrent() }?.let { - 0 == it.diaryId && 0 == it.kindergartenDiaryId - } == true - } - - else -> false - } - - val isRefreshOnNoCurrentAppropriate = - refreshOnNoCurrent && !semesters.any { semester -> semester.isCurrent() } - - return forceRefresh || isNoSemesters || isRefreshOnModeChangeRequired || isRefreshOnNoCurrentAppropriate - } - - private suspend fun refreshSemesters(student: Student) { - val new = wulkanowySdkFactory.create(student) - .getSemesters() - .mapToEntities(student.studentId) - - if (new.isEmpty()) { - Timber.i("Empty semester list from SDK!") - return - } - - val old = semesterDb.loadAll(student.studentId, student.classId) - semesterDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - } - - suspend fun getCurrentSemester(student: Student, forceRefresh: Boolean = false) = - withContext(dispatchers.io) { - getSemesters(student, forceRefresh).getCurrentOrLast() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentInfoRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentInfoRepository.kt deleted file mode 100644 index db4c0aeb..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentInfoRepository.kt +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.StudentInfoDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntity -import io.github.wulkanowy.data.networkBoundResource -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class StudentInfoRepository @Inject constructor( - private val studentInfoDao: StudentInfoDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, -) { - - private val saveFetchResultMutex = Mutex() - - fun getStudentInfo( - student: Student, - semester: Semester, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it == null }, - shouldFetch = { it == null || forceRefresh }, - query = { studentInfoDao.loadStudentInfo(student.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getStudentInfo() - .mapToEntity(semester) - }, - saveFetchResult = { old, new -> - if (old != null && new != old) { - studentInfoDao.removeOldAndSaveNew( - oldItems = listOf(old), - newItems = listOf(new), - ) - } else if (old == null) { - studentInfoDao.insertAll(listOf(new)) - } - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt deleted file mode 100644 index 575ca89f..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt +++ /dev/null @@ -1,241 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import androidx.room.withTransaction -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.AppDatabase -import io.github.wulkanowy.data.db.dao.SemesterDao -import io.github.wulkanowy.data.db.dao.StudentDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentIsAuthorized -import io.github.wulkanowy.data.db.entities.StudentName -import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.exceptions.NoCurrentStudentException -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.mappers.mapToPojo -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.utils.DispatchersProvider -import io.github.wulkanowy.utils.security.Scrambler -import kotlinx.coroutines.withContext -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class StudentRepository @Inject constructor( - private val dispatchers: DispatchersProvider, - private val studentDb: StudentDao, - private val semesterDb: SemesterDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val appDatabase: AppDatabase, - private val scrambler: Scrambler, -) { - - suspend fun isCurrentStudentSet() = studentDb.loadCurrent()?.isCurrent ?: false - - suspend fun getStudentsApi( - pin: String, - symbol: String, - token: String - ): RegisterUser = wulkanowySdkFactory.create() - .getStudentsFromHebe(token, pin, symbol, "") - .mapToPojo(null) - .also { it.logErrors() } - - suspend fun getUserSubjectsFromScrapper( - email: String, - password: String, - scrapperBaseUrl: String, - domainSuffix: String, - symbol: String - ): RegisterUser = wulkanowySdkFactory.create() - .getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, domainSuffix, symbol) - .mapToPojo(password) - .also { it.logErrors() } - - suspend fun getStudentsHybrid( - email: String, - password: String, - scrapperBaseUrl: String, - symbol: String - ): RegisterUser = wulkanowySdkFactory.create() - .getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol) - .mapToPojo(password) - .also { it.logErrors() } - - suspend fun getSavedStudents(decryptPass: Boolean = true): List { - return studentDb.loadStudentsWithSemesters().map { (student, semesters) -> - StudentWithSemesters( - student = student.apply { - if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) { - student.password = withContext(dispatchers.io) { - scrambler.decrypt(student.password) - } - } - }, - semesters = semesters, - ) - } - } - - suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true): StudentWithSemesters? = - studentDb.loadStudentWithSemestersById(id).let { res -> - StudentWithSemesters( - student = res.keys.firstOrNull() ?: return null, - semesters = res.values.first(), - ) - }.apply { - if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) { - student.password = withContext(dispatchers.io) { - scrambler.decrypt(student.password) - } - } - } - - suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student { - val student = studentDb.loadById(id) ?: throw NoCurrentStudentException() - - if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) { - student.password = withContext(dispatchers.io) { - scrambler.decrypt(student.password) - } - } - return student - } - - suspend fun updateCurrentStudentAuthStatus() { - Timber.i("Check isAuthorized: started") - val student = getCurrentStudent() - if (student.isAuthorized) { - Timber.i("Check isAuthorized: already authorized") - return - } - - val initializedSdk = wulkanowySdkFactory.create(student) - val newCurrentStudent = runCatching { initializedSdk.getCurrentStudent() } - .onFailure { Timber.e(it, "Check isAuthorized: error occurred") } - .getOrNull() - - if (newCurrentStudent == null) { - Timber.d("Check isAuthorized: current user is null") - return - } - - val currentStudentSemesters = semesterDb.loadAll(student.studentId, student.classId) - if (currentStudentSemesters.isEmpty()) { - Timber.d("Check isAuthorized: apply empty semesters workaround") - semesterDb.insertSemesters( - items = newCurrentStudent.semesters.mapToEntities(student.studentId), - ) - } - - if (!newCurrentStudent.isAuthorized) { - Timber.i("Check isAuthorized: authorization required") - throw NoAuthorizationException() - } - - val studentIsAuthorized = StudentIsAuthorized( - id = student.id, - isAuthorized = true - ) - - Timber.i("Check isAuthorized: already authorized, update local status") - studentDb.update(studentIsAuthorized) - } - - suspend fun getCurrentStudent(decryptPass: Boolean = true): Student { - val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException() - - if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.HEBE) { - student.password = withContext(dispatchers.io) { - scrambler.decrypt(student.password) - } - } - return student - } - - suspend fun saveStudents(studentsWithSemesters: List) { - val semesters = studentsWithSemesters.flatMap { it.semesters } - val students = studentsWithSemesters.map { it.student } - .map { - it.apply { - if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.HEBE) { - password = withContext(dispatchers.io) { - scrambler.encrypt(password) - } - } - } - } - .mapIndexed { index, student -> - if (index == 0) { - student.copy(isCurrent = true).apply { avatarColor = student.avatarColor } - } else student - } - - appDatabase.withTransaction { - studentDb.resetCurrent() - semesterDb.insertSemesters(semesters) - studentDb.insertAll(students) - } - } - - suspend fun switchStudent(studentWithSemesters: StudentWithSemesters) { - studentDb.switchCurrent(studentWithSemesters.student.id) - } - - suspend fun logoutStudent(student: Student) = studentDb.delete(student) - - suspend fun updateStudentNickAndAvatar(studentNickAndAvatar: StudentNickAndAvatar) = - studentDb.update(studentNickAndAvatar) - - suspend fun isOneUniqueStudent() = getSavedStudents(false) - .distinctBy { it.student.studentName }.size == 1 - - suspend fun authorizePermission(student: Student, semester: Semester, pesel: String) = - wulkanowySdkFactory.create(student, semester) - .authorizePermission(pesel) - - suspend fun refreshStudentAfterAuthorize(student: Student, semester: Semester) { - val wulkanowySdk = wulkanowySdkFactory.create(student, semester) - val newCurrentApiStudent = runCatching { wulkanowySdk.getCurrentStudent() } - .onFailure { Timber.e(it, "Can't find student with id ${student.studentId}") } - .getOrNull() ?: return - - val studentName = StudentName( - studentName = "${newCurrentApiStudent.studentName} ${newCurrentApiStudent.studentSurname}" - ).apply { id = student.id } - - studentDb.update(studentName) - semesterDb.removeOldAndSaveNew( - oldItems = semesterDb.loadAll(student.studentId, semester.classId), - newItems = newCurrentApiStudent.semesters.mapToEntities(newCurrentApiStudent.studentId) - ) - } - - suspend fun deleteStudentsAssociatedWithAccount(student: Student) { - studentDb.deleteByEmailAndUserName(student.email, student.userName) - } - - suspend fun clearAll() { - withContext(dispatchers.io) { - scrambler.clearKeyPair() - appDatabase.clearAllTables() - } - } - - private fun RegisterUser.logErrors() { - val symbolsErrors = symbols.filter { it.error != null } - .map { it.error } - val unitsErrors = symbols.flatMap { it.schools } - .filter { it.error != null } - .map { it.error } - - (symbolsErrors + unitsErrors).forEach { error -> - Timber.e(error, "Error occurred while fetching students") - } - } -} - -class NoAuthorizationException : Exception() diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/SubjectRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/SubjectRepository.kt deleted file mode 100644 index 573c7c14..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/SubjectRepository.kt +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.SubjectDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class SubjectRepository @Inject constructor( - private val subjectDao: SubjectDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "subjects" - - fun getSubjects( - student: Student, - semester: Semester, - forceRefresh: Boolean = false, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { subjectDao.loadAll(semester.diaryId, semester.studentId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getSubjects() - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - subjectDao.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt deleted file mode 100644 index a5a6e3f9..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/TeacherRepository.kt +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.TeacherDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.sync.Mutex -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class TeacherRepository @Inject constructor( - private val teacherDb: TeacherDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val refreshHelper: AutoRefreshHelper, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "teachers" - - fun getTeachers( - student: Student, - semester: Semester, - forceRefresh: Boolean, - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { it.isEmpty() }, - shouldFetch = { - val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester)) - it.isEmpty() || forceRefresh || isExpired - }, - query = { teacherDb.loadAll(semester.studentId, semester.classId) }, - fetch = { - wulkanowySdkFactory.create(student, semester) - .getTeachers() - .mapToEntities(semester) - }, - saveFetchResult = { old, new -> - teacherDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester)) - } - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt deleted file mode 100644 index 60c562e1..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/TimetableRepository.kt +++ /dev/null @@ -1,203 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.data.db.dao.TimetableAdditionalDao -import io.github.wulkanowy.data.db.dao.TimetableDao -import io.github.wulkanowy.data.db.dao.TimetableHeaderDao -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.db.entities.TimetableHeader -import io.github.wulkanowy.data.mappers.mapToEntities -import io.github.wulkanowy.data.networkBoundResource -import io.github.wulkanowy.data.pojos.TimetableFull -import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper -import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider -import io.github.wulkanowy.utils.AppWidgetUpdater -import io.github.wulkanowy.utils.AutoRefreshHelper -import io.github.wulkanowy.utils.getRefreshKey -import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.sunday -import io.github.wulkanowy.utils.uniqueSubtract -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.sync.Mutex -import java.time.Instant -import java.time.LocalDate -import javax.inject.Inject -import javax.inject.Singleton - - -@Singleton -class TimetableRepository @Inject constructor( - private val timetableDb: TimetableDao, - private val timetableAdditionalDb: TimetableAdditionalDao, - private val timetableHeaderDb: TimetableHeaderDao, - private val wulkanowySdkFactory: WulkanowySdkFactory, - private val schedulerHelper: TimetableNotificationSchedulerHelper, - private val refreshHelper: AutoRefreshHelper, - private val appWidgetUpdater: AppWidgetUpdater, -) { - - private val saveFetchResultMutex = Mutex() - - private val cacheKey = "timetable" - - enum class TimetableType { - NORMAL, ADDITIONAL - } - - fun getTimetable( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - forceRefresh: Boolean, - refreshAdditional: Boolean = false, - notify: Boolean = false, - timetableType: TimetableType = TimetableType.NORMAL, - isFromAppWidget: Boolean = false - ) = networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { - when (timetableType) { - TimetableType.NORMAL -> it.lessons.isEmpty() - TimetableType.ADDITIONAL -> it.additional.isEmpty() - } - }, - shouldFetch = { (timetable, additional, headers) -> - val refreshKey = getRefreshKey(cacheKey, semester, start, end) - val isExpired = refreshHelper.shouldBeRefreshed(refreshKey) - val isRefreshAdditional = additional.isEmpty() && refreshAdditional - - val isNoData = timetable.isEmpty() || isRefreshAdditional || headers.isEmpty() - - isNoData || forceRefresh || isExpired - }, - query = { getFullTimetableFromDatabase(student, semester, start, end) }, - fetch = { - val timetableFull = wulkanowySdkFactory.create(student, semester) - .getTimetable(start.monday, end.sunday) - - timetableFull.mapToEntities(semester) - }, - saveFetchResult = { timetableOld, timetableNew -> - refreshTimetable(student, timetableOld.lessons, timetableNew.lessons, notify) - refreshAdditional(timetableOld.additional, timetableNew.additional) - refreshDayHeaders(timetableOld.headers, timetableNew.headers) - - refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, semester, start, end)) - if (!isFromAppWidget) { - appWidgetUpdater.updateAllAppWidgetsByProvider(TimetableWidgetProvider::class) - } - }, - filterResult = { (timetable, additional, headers) -> - TimetableFull( - lessons = timetable.filter { it.date in start..end }, - additional = additional.filter { it.date in start..end }, - headers = headers.filter { it.date in start..end } - ) - } - ) - - private fun getFullTimetableFromDatabase( - student: Student, - semester: Semester, - start: LocalDate, - end: LocalDate, - ): Flow { - val timetableFlow = timetableDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - from = start.monday, - end = end.sunday - ) - val headersFlow = timetableHeaderDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - from = start.monday, - end = end.sunday - ) - val additionalFlow = timetableAdditionalDb.loadAll( - diaryId = semester.diaryId, - studentId = semester.studentId, - from = start.monday, - end = end.sunday - ) - return combine(timetableFlow, headersFlow, additionalFlow) { lessons, headers, additional -> - schedulerHelper.scheduleNotifications(lessons, student) - - TimetableFull( - lessons = lessons, - headers = headers, - additional = additional - ) - } - } - - suspend fun getTimetableFromDatabase( - semester: Semester, - start: LocalDate, - end: LocalDate - ): List { - return timetableDb.load(semester.diaryId, semester.studentId, start, end) - } - - suspend fun updateTimetable(timetable: List) { - return timetableDb.updateAll(timetable) - } - - private suspend fun refreshTimetable( - student: Student, - lessonsOld: List, - lessonsNew: List, - notify: Boolean - ) { - val lessonsToRemove = lessonsOld uniqueSubtract lessonsNew - val lessonsToAdd = (lessonsNew uniqueSubtract lessonsOld).map { new -> - new.apply { if (notify) isNotified = false } - } - - timetableDb.removeOldAndSaveNew( - oldItems = lessonsToRemove, - newItems = lessonsToAdd, - ) - - schedulerHelper.cancelScheduled(lessonsToRemove, student) - schedulerHelper.scheduleNotifications(lessonsToAdd, student) - } - - private suspend fun refreshAdditional( - old: List, - new: List - ) { - val oldFiltered = old.filter { !it.isAddedByUser } - timetableAdditionalDb.removeOldAndSaveNew( - oldItems = oldFiltered uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - } - - private suspend fun refreshDayHeaders(old: List, new: List) { - timetableHeaderDb.removeOldAndSaveNew( - oldItems = old uniqueSubtract new, - newItems = new uniqueSubtract old, - ) - } - - fun getLastRefreshTimestamp(semester: Semester, start: LocalDate, end: LocalDate): Instant { - val refreshKey = getRefreshKey(cacheKey, semester, start, end) - return refreshHelper.getLastRefreshTimestamp(refreshKey) - } - - suspend fun saveAdditionalList(additionalList: List) = - timetableAdditionalDb.insertAll(additionalList) - - suspend fun deleteAdditional(additional: TimetableAdditional, deleteSeries: Boolean) = - if (deleteSeries) { - timetableAdditionalDb.deleteAllByRepeatId(additional.repeatId!!) - } else { - timetableAdditionalDb.deleteAll(listOf(additional)) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt deleted file mode 100644 index 5b563b35..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/WulkanowyRepository.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.github.wulkanowy.data.repositories - -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.api.models.Mapping -import io.github.wulkanowy.data.api.services.WulkanowyService -import io.github.wulkanowy.data.db.dao.AdminMessageDao -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.networkBoundResource -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.filterNot -import kotlinx.coroutines.sync.Mutex -import timber.log.Timber -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class WulkanowyRepository @Inject constructor( - private val wulkanowyService: WulkanowyService, - private val adminMessageDao: AdminMessageDao, - private val preferencesRepository: PreferencesRepository, -) { - - private val saveFetchResultMutex = Mutex() - - fun getAdminMessages(): Flow>> = - networkBoundResource( - mutex = saveFetchResultMutex, - isResultEmpty = { false }, - query = { adminMessageDao.loadAll() }, - fetch = { wulkanowyService.getAdminMessages() }, - shouldFetch = { true }, - saveFetchResult = { oldItems, newItems -> - adminMessageDao.removeOldAndSaveNew(oldItems, newItems) - }, - ) - .filterNot { it is Resource.Intermediate } - - suspend fun getMapping(): Mapping? { - var savedMapping = preferencesRepository.mapping - - if (savedMapping == null) { - fetchMapping() - savedMapping = preferencesRepository.mapping - } - - return savedMapping - } - - suspend fun fetchMapping() { - runCatching { wulkanowyService.getMapping() } - .onFailure { Timber.e(it) } - .onSuccess { preferencesRepository.mapping = it } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt new file mode 100644 index 00000000..ff538969 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.data.repositories.appcreator + +import android.content.res.AssetManager +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import io.github.wulkanowy.data.pojos.Contributor +import io.github.wulkanowy.utils.DispatchersProvider +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AppCreatorRepository @Inject constructor( + private val assets: AssetManager, + private val dispatchers: DispatchersProvider +) { + + suspend fun getAppCreators() = withContext(dispatchers.backgroundThread) { + val moshi = Moshi.Builder().build() + val type = Types.newParameterizedType(List::class.java, Contributor::class.java) + val adapter = moshi.adapter>(type) + adapter.fromJson(assets.open("contributors.json").bufferedReader().use { it.readText() }) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt new file mode 100644 index 00000000..9aaa5230 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.attendance + +import io.github.wulkanowy.data.db.dao.AttendanceDao +import io.github.wulkanowy.data.db.entities.Attendance +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) { + + suspend fun saveAttendance(attendance: List) { + attendanceDb.insertAll(attendance) + } + + suspend fun deleteAttendance(attendance: List) { + attendanceDb.deleteAll(attendance) + } + + fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Flow> { + return attendanceDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt new file mode 100644 index 00000000..870690ec --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt @@ -0,0 +1,50 @@ +package io.github.wulkanowy.data.repositories.attendance + +import io.github.wulkanowy.data.db.entities.Attendance +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.sdk.pojo.Absent +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getAttendance(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getAttendance(startDate, endDate, semester.semesterId) + .map { + Attendance( + studentId = semester.studentId, + diaryId = semester.diaryId, + date = it.date, + timeId = it.timeId, + number = it.number, + subject = it.subject, + name = it.name, + presence = it.presence, + absence = it.absence, + exemption = it.exemption, + lateness = it.lateness, + excused = it.excused, + deleted = it.deleted, + excusable = it.excusable, + excuseStatus = it.excuseStatus?.name + ) + } + } + + suspend fun excuseAbsence(student: Student, semester: Semester, absenceList: List, reason: String?): Boolean { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance -> + Absent( + date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)), + timeId = attendance.timeId + ) + }, reason) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt new file mode 100644 index 00000000..60f864f2 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt @@ -0,0 +1,34 @@ +package io.github.wulkanowy.data.repositories.attendance + +import io.github.wulkanowy.data.db.entities.Attendance +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.uniqueSubtract +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceRepository @Inject constructor( + private val local: AttendanceLocal, + private val remote: AttendanceRemote +) { + + fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getAttendance(semester, start.monday, end.sunday) }, + fetch = { remote.getAttendance(student, semester, start.monday, end.sunday) }, + saveFetchResult = { old, new -> + local.deleteAttendance(old uniqueSubtract new) + local.saveAttendance(new uniqueSubtract old) + }, + filterResult = { it.filter { item -> item.date in start..end } } + ) + + suspend fun excuseForAbsence(student: Student, semester: Semester, attendanceList: List, reason: String? = null) { + remote.excuseAbsence(student, semester, attendanceList, reason) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/SentExcuseStatus.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt similarity index 60% rename from app/src/main/java/io/github/wulkanowy/data/enums/SentExcuseStatus.kt rename to app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt index 99878152..50d6b8ed 100644 --- a/app/src/main/java/io/github/wulkanowy/data/enums/SentExcuseStatus.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/SentExcuseStatus.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.data.enums +package io.github.wulkanowy.data.repositories.attendance enum class SentExcuseStatus(val id: Int = 0) { WAITING, diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt new file mode 100644 index 00000000..703bc947 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.data.repositories.attendancesummary + +import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao +import io.github.wulkanowy.data.db.entities.AttendanceSummary +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: AttendanceSummaryDao) { + + suspend fun saveAttendanceSummary(attendance: List) { + attendanceDb.insertAll(attendance) + } + + suspend fun deleteAttendanceSummary(attendance: List) { + attendanceDb.deleteAll(attendance) + } + + fun getAttendanceSummary(semester: Semester, subjectId: Int): Flow> { + return attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt new file mode 100644 index 00000000..29a0b9a7 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.data.repositories.attendancesummary + +import io.github.wulkanowy.data.db.entities.AttendanceSummary +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getAttendanceSummary(subjectId) + .map { + AttendanceSummary( + studentId = semester.studentId, + diaryId = semester.diaryId, + subjectId = subjectId, + month = it.month, + presence = it.presence, + absence = it.absence, + absenceExcused = it.absenceExcused, + absenceForSchoolReasons = it.absenceForSchoolReasons, + lateness = it.lateness, + latenessExcused = it.latenessExcused, + exemption = it.exemption + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt new file mode 100644 index 00000000..5dbe1ab0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.attendancesummary + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AttendanceSummaryRepository @Inject constructor( + private val local: AttendanceSummaryLocal, + private val remote: AttendanceSummaryRemote +) { + + fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getAttendanceSummary(semester, subjectId) }, + fetch = { remote.getAttendanceSummary(student, semester, subjectId) }, + saveFetchResult = { old, new -> + local.deleteAttendanceSummary(old uniqueSubtract new) + local.saveAttendanceSummary(new uniqueSubtract old) + } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt new file mode 100644 index 00000000..51a1bdbf --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.completedlessons + +import io.github.wulkanowy.data.db.dao.CompletedLessonsDao +import io.github.wulkanowy.data.db.entities.CompletedLesson +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb: CompletedLessonsDao) { + + suspend fun saveCompletedLessons(completedLessons: List) { + completedLessonsDb.insertAll(completedLessons) + } + + suspend fun deleteCompleteLessons(completedLessons: List) { + completedLessonsDb.deleteAll(completedLessons) + } + + fun getCompletedLessons(semester: Semester, start: LocalDate, end: LocalDate): Flow> { + return completedLessonsDb.loadAll(semester.diaryId, semester.studentId, start, end) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt new file mode 100644 index 00000000..d15a2762 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.data.repositories.completedlessons + +import io.github.wulkanowy.data.db.entities.CompletedLesson +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getCompletedLessons(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getCompletedLessons(startDate, endDate) + .map { + it.absence + CompletedLesson( + studentId = semester.studentId, + diaryId = semester.diaryId, + date = it.date, + number = it.number, + subject = it.subject, + topic = it.topic, + teacher = it.teacher, + teacherSymbol = it.teacherSymbol, + substitution = it.substitution, + absence = it.absence, + resources = it.resources + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt new file mode 100644 index 00000000..61268a66 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.data.repositories.completedlessons + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.uniqueSubtract +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class CompletedLessonsRepository @Inject constructor( + private val local: CompletedLessonsLocal, + private val remote: CompletedLessonsRemote +) { + + fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getCompletedLessons(semester, start.monday, end.sunday) }, + fetch = { remote.getCompletedLessons(student, semester, start.monday, end.sunday) }, + saveFetchResult = { old, new -> + local.deleteCompleteLessons(old uniqueSubtract new) + local.saveCompletedLessons(new uniqueSubtract old) + }, + filterResult = { it.filter { item -> item.date in start..end } } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceLocal.kt new file mode 100644 index 00000000..9f56641f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceLocal.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.conference + +import io.github.wulkanowy.data.db.dao.ConferenceDao +import io.github.wulkanowy.data.db.entities.Conference +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ConferenceLocal @Inject constructor(private val conferenceDb: ConferenceDao) { + + fun getConferences(student: Student, semester: Semester): Flow> { + return conferenceDb.loadAll(semester.diaryId, student.studentId) + } + + suspend fun saveConferences(items: List) { + conferenceDb.insertAll(items) + } + + suspend fun deleteConferences(items: List) { + conferenceDb.deleteAll(items) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRemote.kt new file mode 100644 index 00000000..50e869a9 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRemote.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.data.repositories.conference + +import io.github.wulkanowy.data.db.entities.Conference +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ConferenceRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getConferences(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getConferences() + .map { + it.agenda + Conference( + studentId = student.studentId, + diaryId = semester.diaryId, + agenda = it.agenda, + conferenceId = it.id, + date = it.date, + presentOnConference = it.presentOnConference, + subject = it.subject, + title = it.title + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRepository.kt new file mode 100644 index 00000000..187ecf58 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/conference/ConferenceRepository.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.conference + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ConferenceRepository @Inject constructor( + private val local: ConferenceLocal, + private val remote: ConferenceRemote +) { + + fun getConferences(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getConferences(student, semester) }, + fetch = { remote.getConferences(student, semester) }, + saveFetchResult = { old, new -> + local.deleteConferences(old uniqueSubtract new) + local.saveConferences(new uniqueSubtract old) + } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt new file mode 100644 index 00000000..acc55b5e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.exam + +import io.github.wulkanowy.data.db.dao.ExamDao +import io.github.wulkanowy.data.db.entities.Exam +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ExamLocal @Inject constructor(private val examDb: ExamDao) { + + fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Flow> { + return examDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate) + } + + suspend fun saveExams(exams: List) { + examDb.insertAll(exams) + } + + suspend fun deleteExams(exams: List) { + examDb.deleteAll(exams) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt new file mode 100644 index 00000000..ac4aa93d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt @@ -0,0 +1,33 @@ +package io.github.wulkanowy.data.repositories.exam + +import io.github.wulkanowy.data.db.entities.Exam +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ExamRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getExams(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getExams(startDate, endDate, semester.semesterId) + .map { + Exam( + studentId = semester.studentId, + diaryId = semester.diaryId, + date = it.date, + entryDate = it.entryDate, + subject = it.subject, + group = it.group, + type = it.type, + description = it.description, + teacher = it.teacher, + teacherSymbol = it.teacherSymbol + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt new file mode 100644 index 00000000..3f4591a2 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.data.repositories.exam + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.endExamsDay +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.startExamsDay +import io.github.wulkanowy.utils.uniqueSubtract +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ExamRepository @Inject constructor( + private val local: ExamLocal, + private val remote: ExamRemote +) { + + fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getExams(semester, start.startExamsDay, start.endExamsDay) }, + fetch = { remote.getExams(student, semester, start.startExamsDay, start.endExamsDay) }, + saveFetchResult = { old, new -> + local.deleteExams(old uniqueSubtract new) + local.saveExams(new uniqueSubtract old) + }, + filterResult = { it.filter { item -> item.date in start..end } } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt new file mode 100644 index 00000000..ed363542 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt @@ -0,0 +1,49 @@ +package io.github.wulkanowy.data.repositories.grade + +import io.github.wulkanowy.data.db.dao.GradeDao +import io.github.wulkanowy.data.db.dao.GradeSummaryDao +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.GradeSummary +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeLocal @Inject constructor( + private val gradeDb: GradeDao, + private val gradeSummaryDb: GradeSummaryDao +) { + + suspend fun saveGrades(grades: List) { + gradeDb.insertAll(grades) + } + + suspend fun deleteGrades(grades: List) { + gradeDb.deleteAll(grades) + } + + suspend fun updateGrades(grades: List) { + gradeDb.updateAll(grades) + } + + suspend fun updateGradesSummary(gradesSummary: List) { + gradeSummaryDb.updateAll(gradesSummary) + } + + fun getGradesDetails(semester: Semester): Flow> { + return gradeDb.loadAll(semester.semesterId, semester.studentId) + } + + suspend fun saveGradesSummary(gradesSummary: List) { + gradeSummaryDb.insertAll(gradesSummary) + } + + suspend fun deleteGradesSummary(gradesSummary: List) { + gradeSummaryDb.deleteAll(gradesSummary) + } + + fun getGradesSummary(semester: Semester): Flow> { + return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt new file mode 100644 index 00000000..9534a891 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt @@ -0,0 +1,53 @@ +package io.github.wulkanowy.data.repositories.grade + +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.GradeSummary +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getGrades(student: Student, semester: Semester): Pair, List> { + val (details, summary) = sdk + .init(student) + .switchDiary(semester.diaryId, semester.schoolYear) + .getGrades(semester.semesterId) + + return details.map { + Grade( + studentId = semester.studentId, + semesterId = semester.semesterId, + subject = it.subject, + entry = it.entry, + value = it.value, + modifier = it.modifier, + comment = it.comment, + color = it.color, + gradeSymbol = it.symbol, + description = it.description, + weight = it.weight, + weightValue = it.weightValue, + date = it.date, + teacher = it.teacher + ) + } to summary.map { + GradeSummary( + semesterId = semester.semesterId, + studentId = semester.studentId, + position = 0, + subject = it.name, + predictedGrade = it.predicted, + finalGrade = it.final, + pointsSum = it.pointsSum, + proposedPoints = it.proposedPoints, + finalPoints = it.finalPoints, + average = it.average + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt new file mode 100644 index 00000000..8cbbfdfb --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt @@ -0,0 +1,98 @@ +package io.github.wulkanowy.data.repositories.grade + +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.GradeSummary +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import java.time.LocalDateTime +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeRepository @Inject constructor( + private val local: GradeLocal, + private val remote: GradeRemote +) { + + fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource( + shouldFetch = { (details, summaries) -> details.isEmpty() || summaries.isEmpty() || forceRefresh }, + query = { local.getGradesDetails(semester).combine(local.getGradesSummary(semester)) { details, summaries -> details to summaries } }, + fetch = { remote.getGrades(student, semester) }, + saveFetchResult = { old, new -> + refreshGradeDetails(student, old.first, new.first, notify) + refreshGradeSummaries(old.second, new.second, notify) + } + ) + + private suspend fun refreshGradeDetails(student: Student, oldGrades: List, newDetails: List, notify: Boolean) { + val notifyBreakDate = oldGrades.maxByOrNull { it.date }?.date ?: student.registrationDate.toLocalDate() + local.deleteGrades(oldGrades uniqueSubtract newDetails) + local.saveGrades((newDetails uniqueSubtract oldGrades).onEach { + if (it.date >= notifyBreakDate) it.apply { + isRead = false + if (notify) isNotified = false + } + }) + } + + private suspend fun refreshGradeSummaries(oldSummaries: List, newSummary: List, notify: Boolean) { + local.deleteGradesSummary(oldSummaries uniqueSubtract newSummary) + local.saveGradesSummary((newSummary uniqueSubtract oldSummaries).onEach { summary -> + val oldSummary = oldSummaries.find { oldSummary -> oldSummary.subject == summary.subject } + summary.isPredictedGradeNotified = when { + summary.predictedGrade.isEmpty() -> true + notify && oldSummary?.predictedGrade != summary.predictedGrade -> false + else -> true + } + summary.isFinalGradeNotified = when { + summary.finalGrade.isEmpty() -> true + notify && oldSummary?.finalGrade != summary.finalGrade -> false + else -> true + } + + summary.predictedGradeLastChange = when { + oldSummary == null -> LocalDateTime.now() + summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now() + else -> oldSummary.predictedGradeLastChange + } + summary.finalGradeLastChange = when { + oldSummary == null -> LocalDateTime.now() + summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now() + else -> oldSummary.finalGradeLastChange + } + }) + } + + fun getUnreadGrades(semester: Semester): Flow> { + return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isRead } } + } + + fun getNotNotifiedGrades(semester: Semester): Flow> { + return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } } + } + + fun getNotNotifiedPredictedGrades(semester: Semester): Flow> { + return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } } + } + + fun getNotNotifiedFinalGrades(semester: Semester): Flow> { + return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } } + } + + suspend fun updateGrade(grade: Grade) { + return local.updateGrades(listOf(grade)) + } + + suspend fun updateGrades(grades: List) { + return local.updateGrades(grades) + } + + suspend fun updateGradesSummary(gradesSummary: List) { + return local.updateGradesSummary(gradesSummary) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt new file mode 100644 index 00000000..3e3c819f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt @@ -0,0 +1,59 @@ +package io.github.wulkanowy.data.repositories.gradestatistics + +import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao +import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao +import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao +import io.github.wulkanowy.data.db.entities.GradePartialStatistics +import io.github.wulkanowy.data.db.entities.GradePointsStatistics +import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeStatisticsLocal @Inject constructor( + private val gradePartialStatisticsDb: GradePartialStatisticsDao, + private val gradePointsStatisticsDb: GradePointsStatisticsDao, + private val gradeSemesterStatisticsDb: GradeSemesterStatisticsDao +) { + + // partial + fun getGradePartialStatistics(semester: Semester): Flow> { + return gradePartialStatisticsDb.loadAll(semester.semesterId, semester.studentId) + } + + suspend fun saveGradePartialStatistics(items: List) { + gradePartialStatisticsDb.insertAll(items) + } + + suspend fun deleteGradePartialStatistics(items: List) { + gradePartialStatisticsDb.deleteAll(items) + } + + // points + fun getGradePointsStatistics(semester: Semester): Flow> { + return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId) + } + + suspend fun saveGradePointsStatistics(gradePointsStatistics: List) { + gradePointsStatisticsDb.insertAll(gradePointsStatistics) + } + + suspend fun deleteGradePointsStatistics(gradesPointsStatistics: List) { + gradePointsStatisticsDb.deleteAll(gradesPointsStatistics) + } + + // semester + fun getGradeSemesterStatistics(semester: Semester): Flow> { + return gradeSemesterStatisticsDb.loadAll(semester.semesterId, semester.studentId) + } + + suspend fun saveGradeSemesterStatistics(items: List) { + gradeSemesterStatisticsDb.insertAll(items) + } + + suspend fun deleteGradeSemesterStatistics(items: List) { + gradeSemesterStatisticsDb.deleteAll(items) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt new file mode 100644 index 00000000..144df8a0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt @@ -0,0 +1,63 @@ +package io.github.wulkanowy.data.repositories.gradestatistics + +import io.github.wulkanowy.data.db.entities.GradePartialStatistics +import io.github.wulkanowy.data.db.entities.GradePointsStatistics +import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getGradePartialStatistics(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getGradesPartialStatistics(semester.semesterId) + .map { + GradePartialStatistics( + semesterId = semester.semesterId, + studentId = student.studentId, + subject = it.subject, + classAverage = it.classAverage, + studentAverage = it.studentAverage, + classAmounts = it.classItems + .sortedBy { item -> item.grade } + .map { item -> item.amount }, + studentAmounts = it.studentItems.map { item -> item.amount } + ) + } + } + + suspend fun getGradeSemesterStatistics(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getGradesSemesterStatistics(semester.semesterId) + .map { + GradeSemesterStatistics( + semesterId = semester.semesterId, + studentId = semester.studentId, + subject = it.subject, + amounts = it.items + .sortedBy { item -> item.grade } + .map { item -> item.amount }, + studentGrade = it.items.singleOrNull { item -> item.isStudentHere }?.grade ?: 0 + ) + } + } + + suspend fun getGradePointsStatistics(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getGradesPointsStatistics(semester.semesterId) + .map { + GradePointsStatistics( + semesterId = semester.semesterId, + studentId = semester.studentId, + subject = it.subject, + others = it.others, + student = it.student + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt new file mode 100644 index 00000000..ca0f6ffb --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt @@ -0,0 +1,144 @@ +package io.github.wulkanowy.data.repositories.gradestatistics + +import io.github.wulkanowy.data.db.entities.GradePartialStatistics +import io.github.wulkanowy.data.db.entities.GradePointsStatistics +import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.pojos.GradeStatisticsItem +import io.github.wulkanowy.ui.modules.grade.statistics.ViewType +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import java.util.Locale +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GradeStatisticsRepository @Inject constructor( + private val local: GradeStatisticsLocal, + private val remote: GradeStatisticsRemote +) { + + fun getGradesPartialStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getGradePartialStatistics(semester) }, + fetch = { remote.getGradePartialStatistics(student, semester) }, + saveFetchResult = { old, new -> + local.deleteGradePartialStatistics(old uniqueSubtract new) + local.saveGradePartialStatistics(new uniqueSubtract old) + }, + mapResult = { items -> + when (subjectName) { + "Wszystkie" -> { + val numerator = items.map { + it.classAverage.replace(",", ".").toDoubleOrNull() ?: .0 + }.filterNot { it == .0 } + (items.reversed() + GradePartialStatistics( + studentId = semester.studentId, + semesterId = semester.semesterId, + subject = subjectName, + classAverage = if (numerator.isEmpty()) "" else numerator.average().let { + "%.2f".format(Locale.FRANCE, it) + }, + studentAverage = "", + classAmounts = items.map { it.classAmounts }.sumGradeAmounts(), + studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts() + )).reversed() + } + else -> items.filter { it.subject == subjectName } + }.mapPartialToStatisticItems() + } + ) + + fun getGradesSemesterStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getGradeSemesterStatistics(semester) }, + fetch = { remote.getGradeSemesterStatistics(student, semester) }, + saveFetchResult = { old, new -> + local.deleteGradeSemesterStatistics(old uniqueSubtract new) + local.saveGradeSemesterStatistics(new uniqueSubtract old) + }, + mapResult = { items -> + val itemsWithAverage = items.map { item -> + item.copy().apply { + val denominator = item.amounts.sum() + average = if (denominator == 0) "" else (item.amounts.mapIndexed { gradeValue, amount -> + (gradeValue + 1) * amount + }.sum().toDouble() / denominator).let { + "%.2f".format(Locale.FRANCE, it) + } + } + } + when (subjectName) { + "Wszystkie" -> (itemsWithAverage.reversed() + GradeSemesterStatistics( + studentId = semester.studentId, + semesterId = semester.semesterId, + subject = subjectName, + amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(), + studentGrade = 0 + ).apply { + average = itemsWithAverage.mapNotNull { it.average.replace(",", ".").toDoubleOrNull() }.average().let { + "%.2f".format(Locale.FRANCE, it) + } + }).reversed() + else -> itemsWithAverage.filter { it.subject == subjectName } + }.mapSemesterToStatisticItems() + } + ) + + fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getGradePointsStatistics(semester) }, + fetch = { remote.getGradePointsStatistics(student, semester) }, + saveFetchResult = { old, new -> + local.deleteGradePointsStatistics(old uniqueSubtract new) + local.saveGradePointsStatistics(new uniqueSubtract old) + }, + mapResult = { items -> + when (subjectName) { + "Wszystkie" -> items + else -> items.filter { it.subject == subjectName } + }.mapPointsToStatisticsItems() + } + ) + + private fun List>.sumGradeAmounts(): List { + val result = mutableListOf(0, 0, 0, 0, 0, 0) + forEach { + it.forEachIndexed { grade, amount -> + result[grade] += amount + } + } + return result + } + + private fun List.mapPartialToStatisticItems() = filterNot { it.classAmounts.isEmpty() }.map { + GradeStatisticsItem( + type = ViewType.PARTIAL, + average = it.classAverage, + partial = it, + points = null, + semester = null + ) + } + + private fun List.mapSemesterToStatisticItems() = filterNot { it.amounts.isEmpty() }.map { + GradeStatisticsItem( + type = ViewType.SEMESTER, + partial = null, + points = null, + average = "", + semester = it + ) + } + + private fun List.mapPointsToStatisticsItems() = map { + GradeStatisticsItem( + type = ViewType.POINTS, + partial = null, + semester = null, + average = "", + points = it + ) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt new file mode 100644 index 00000000..f2cbb803 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.data.repositories.homework + +import io.github.wulkanowy.data.db.dao.HomeworkDao +import io.github.wulkanowy.data.db.entities.Homework +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) { + + suspend fun saveHomework(homework: List) { + homeworkDb.insertAll(homework) + } + + suspend fun deleteHomework(homework: List) { + homeworkDb.deleteAll(homework) + } + + suspend fun updateHomework(homework: List) { + homeworkDb.updateAll(homework) + } + + fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Flow> { + return homeworkDb.loadAll(semester.semesterId, semester.studentId, startDate, endDate) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt new file mode 100644 index 00000000..32109877 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt @@ -0,0 +1,32 @@ +package io.github.wulkanowy.data.repositories.homework + +import io.github.wulkanowy.data.db.entities.Homework +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class HomeworkRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getHomework(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getHomework(startDate, endDate) + .map { + Homework( + semesterId = semester.semesterId, + studentId = semester.studentId, + date = it.date, + entryDate = it.entryDate, + subject = it.subject, + content = it.content, + teacher = it.teacher, + teacherSymbol = it.teacherSymbol, + attachments = it.attachments.map { attachment -> attachment.url to attachment.name } + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt new file mode 100644 index 00000000..54397ea0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt @@ -0,0 +1,35 @@ +package io.github.wulkanowy.data.repositories.homework + +import io.github.wulkanowy.data.db.entities.Homework +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.uniqueSubtract +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class HomeworkRepository @Inject constructor( + private val local: HomeworkLocal, + private val remote: HomeworkRemote +) { + + fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getHomework(semester, start.monday, end.sunday) }, + fetch = { remote.getHomework(student, semester, start.monday, end.sunday) }, + saveFetchResult = { old, new -> + local.deleteHomework(old uniqueSubtract new) + local.saveHomework(new uniqueSubtract old) + } + ) + + suspend fun toggleDone(homework: Homework) { + local.updateHomework(listOf(homework.apply { + isDone = !isDone + })) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/LoggerRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt similarity index 55% rename from app/src/main/java/io/github/wulkanowy/data/repositories/LoggerRepository.kt rename to app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt index 1a8cd6ea..85168fee 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/LoggerRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.data.repositories +package io.github.wulkanowy.data.repositories.logger import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext @@ -15,23 +15,24 @@ class LoggerRepository @Inject constructor( suspend fun getLastLogLines() = getLastModified().readText().split("\n") - suspend fun getLogFiles() = withContext(dispatchers.io) { - File(context.filesDir.absolutePath).listFiles(File::isFile) - ?.filter { it.name.endsWith(".log") }!! + suspend fun getLogFiles() = withContext(dispatchers.backgroundThread) { + File(context.filesDir.absolutePath).listFiles(File::isFile)?.filter { + it.name.endsWith(".log") + }!! } - private suspend fun getLastModified() = withContext(dispatchers.io) { - var lastModifiedTime = Long.MIN_VALUE - var chosenFile: File? = null - - File(context.filesDir.absolutePath).listFiles(File::isFile) - ?.forEach { file -> + private suspend fun getLastModified(): File { + return withContext(dispatchers.backgroundThread) { + var lastModifiedTime = Long.MIN_VALUE + var chosenFile: File? = null + File(context.filesDir.absolutePath).listFiles(File::isFile)?.forEach { file -> if (file.lastModified() > lastModifiedTime) { lastModifiedTime = file.lastModified() chosenFile = file } } - - chosenFile ?: throw FileNotFoundException("Log file not found") + if (chosenFile == null) throw FileNotFoundException("Log file not found") + chosenFile!! + } } } diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt new file mode 100644 index 00000000..0c3156d1 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.data.repositories.luckynumber + +import io.github.wulkanowy.data.db.dao.LuckyNumberDao +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) { + + suspend fun saveLuckyNumber(luckyNumber: LuckyNumber?) { + luckyNumberDb.insertAll(listOfNotNull(luckyNumber)) + } + + suspend fun updateLuckyNumber(luckyNumber: LuckyNumber?) { + luckyNumberDb.updateAll(listOfNotNull(luckyNumber)) + } + + suspend fun deleteLuckyNumber(luckyNumber: LuckyNumber?) { + luckyNumberDb.deleteAll(listOfNotNull(luckyNumber)) + } + + fun getLuckyNumber(student: Student, date: LocalDate): Flow { + return luckyNumberDb.load(student.studentId, date) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt new file mode 100644 index 00000000..2872957d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt @@ -0,0 +1,23 @@ +package io.github.wulkanowy.data.repositories.luckynumber + +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getLuckyNumber(student: Student): LuckyNumber? { + return sdk.init(student).getLuckyNumber(student.schoolShortName)?.let { + LuckyNumber( + studentId = student.studentId, + date = LocalDate.now(), + luckyNumber = it + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt new file mode 100644 index 00000000..173ce7e4 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt @@ -0,0 +1,36 @@ +package io.github.wulkanowy.data.repositories.luckynumber + +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import java.time.LocalDate.now +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class LuckyNumberRepository @Inject constructor( + private val local: LuckyNumberLocal, + private val remote: LuckyNumberRemote +) { + + fun getLuckyNumber(student: Student, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource( + shouldFetch = { it == null || forceRefresh }, + query = { local.getLuckyNumber(student, now()) }, + fetch = { remote.getLuckyNumber(student) }, + saveFetchResult = { old, new -> + if (new != old) { + old?.let { local.deleteLuckyNumber(it) } + local.saveLuckyNumber(new?.apply { + if (notify) isNotified = false + }) + } + } + ) + + suspend fun getNotNotifiedLuckyNumber(student: Student) = + local.getLuckyNumber(student, now()).map { if (it?.isNotified == false) it else null }.first() + + suspend fun updateLuckyNumber(luckyNumber: LuckyNumber?) = local.updateLuckyNumber(luckyNumber) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageFolder.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageFolder.kt new file mode 100644 index 00000000..06f5a1e0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageFolder.kt @@ -0,0 +1,7 @@ +package io.github.wulkanowy.data.repositories.message + +enum class MessageFolder(val id: Int = 1) { + RECEIVED(1), + SENT(2), + TRASHED(3) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt new file mode 100644 index 00000000..f1c8eaf0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt @@ -0,0 +1,42 @@ +package io.github.wulkanowy.data.repositories.message + +import io.github.wulkanowy.data.db.dao.MessageAttachmentDao +import io.github.wulkanowy.data.db.dao.MessagesDao +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.MessageAttachment +import io.github.wulkanowy.data.db.entities.MessageWithAttachment +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MessageLocal @Inject constructor( + private val messagesDb: MessagesDao, + private val messageAttachmentDao: MessageAttachmentDao +) { + + suspend fun saveMessages(messages: List) { + messagesDb.insertAll(messages) + } + + suspend fun updateMessages(messages: List) { + messagesDb.updateAll(messages) + } + + suspend fun deleteMessages(messages: List) { + messagesDb.deleteAll(messages) + } + + fun getMessageWithAttachment(student: Student, message: Message): Flow { + return messagesDb.loadMessageWithAttachment(student.id.toInt(), message.messageId) + } + + suspend fun saveMessageAttachments(attachments: List) { + messageAttachmentDao.insertAttachments(attachments) + } + + fun getMessages(student: Student, folder: MessageFolder): Flow> { + return messagesDb.loadAll(student.id.toInt(), folder.id) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt new file mode 100644 index 00000000..044a13a2 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt @@ -0,0 +1,78 @@ +package io.github.wulkanowy.data.repositories.message + +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.MessageAttachment +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.sdk.pojo.Folder +import io.github.wulkanowy.sdk.pojo.SentMessage +import io.github.wulkanowy.utils.init +import java.time.LocalDateTime.now +import javax.inject.Inject +import javax.inject.Singleton +import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient + +@Singleton +class MessageRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getMessages(student: Student, semester: Semester, folder: MessageFolder): List { + return sdk.init(student).getMessages(Folder.valueOf(folder.name), now().minusMonths(3), now()).map { + Message( + studentId = student.id.toInt(), + realId = it.id ?: 0, + messageId = it.messageId ?: 0, + sender = it.sender?.name.orEmpty(), + senderId = it.sender?.loginId ?: 0, + recipient = it.recipients.singleOrNull()?.name ?: "Wielu adresatów", + subject = it.subject.trim(), + date = it.date ?: now(), + folderId = it.folderId, + unread = it.unread ?: false, + removed = it.removed, + hasAttachments = it.hasAttachments + ).apply { + content = it.content.orEmpty() + unreadBy = it.unreadBy ?: 0 + readBy = it.readBy ?: 0 + } + } + } + + suspend fun getMessagesContentDetails(student: Student, message: Message, markAsRead: Boolean = false): Pair> { + return sdk.init(student).getMessageDetails(message.messageId, message.folderId, markAsRead, message.realId).let { details -> + details.content to details.attachments.map { + MessageAttachment( + realId = it.id, + messageId = it.messageId, + oneDriveId = it.oneDriveId, + url = it.url, + filename = it.filename + ) + } + } + } + + suspend fun sendMessage(student: Student, subject: String, content: String, recipients: List): SentMessage { + return sdk.init(student).sendMessage( + subject = subject, + content = content, + recipients = recipients.map { + SdkRecipient( + id = it.realId, + name = it.realName, + loginId = it.loginId, + reportingUnitId = it.unitId, + role = it.role, + hash = it.hash, + shortName = it.name + ) + } + ) + } + + suspend fun deleteMessage(student: Student, message: Message): Boolean { + return sdk.init(student).deleteMessages(listOf(message.messageId), message.folderId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt new file mode 100644 index 00000000..bb932699 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRepository.kt @@ -0,0 +1,76 @@ +package io.github.wulkanowy.data.repositories.message + +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED +import io.github.wulkanowy.sdk.pojo.SentMessage +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MessageRepository @Inject constructor( + private val local: MessageLocal, + private val remote: MessageRemote +) { + + fun getMessages(student: Student, semester: Semester, folder: MessageFolder, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getMessages(student, folder) }, + fetch = { remote.getMessages(student, semester, folder) }, + saveFetchResult = { old, new -> + local.deleteMessages(old uniqueSubtract new) + local.saveMessages((new uniqueSubtract old).onEach { + it.isNotified = !notify + }) + } + ) + + fun getMessage(student: Student, message: Message, markAsRead: Boolean = false) = networkBoundResource( + shouldFetch = { + checkNotNull(it, { "This message no longer exist!" }) + Timber.d("Message content in db empty: ${it.message.content.isEmpty()}") + it.message.unread || it.message.content.isEmpty() + }, + query = { local.getMessageWithAttachment(student, message) }, + fetch = { remote.getMessagesContentDetails(student, it!!.message, markAsRead) }, + saveFetchResult = { old, (downloadedMessage, attachments) -> + checkNotNull(old, { "Fetched message no longer exist!" }) + local.updateMessages(listOf(old.message.copy(unread = !markAsRead).apply { + id = old.message.id + content = content.ifBlank { downloadedMessage } + })) + local.saveMessageAttachments(attachments) + Timber.d("Message ${message.messageId} with blank content: ${old.message.content.isBlank()}, marked as read") + } + ) + + fun getNotNotifiedMessages(student: Student): Flow> { + return local.getMessages(student, RECEIVED).map { it.filter { message -> !message.isNotified && message.unread } } + } + + suspend fun updateMessages(messages: List) { + return local.updateMessages(messages) + } + + suspend fun sendMessage(student: Student, subject: String, content: String, recipients: List): SentMessage { + return remote.sendMessage(student, subject, content, recipients) + } + + suspend fun deleteMessage(student: Student, message: Message) { + val isDeleted = remote.deleteMessage(student, message) + + if (message.folderId != MessageFolder.TRASHED.id) { + if (isDeleted) local.updateMessages(listOf(message.copy(folderId = MessageFolder.TRASHED.id).apply { + id = message.id + content = message.content + })) + } else local.deleteMessages(listOf(message)) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceLocal.kt new file mode 100644 index 00000000..0ccb3d7e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceLocal.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.data.repositories.mobiledevice + +import io.github.wulkanowy.data.db.dao.MobileDeviceDao +import io.github.wulkanowy.data.db.entities.MobileDevice +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MobileDeviceLocal @Inject constructor(private val mobileDb: MobileDeviceDao) { + + suspend fun saveDevices(devices: List) { + mobileDb.insertAll(devices) + } + + suspend fun deleteDevices(devices: List) { + mobileDb.deleteAll(devices) + } + + fun getDevices(semester: Semester): Flow> { + return mobileDb.loadAll(semester.studentId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRemote.kt new file mode 100644 index 00000000..907e965c --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRemote.kt @@ -0,0 +1,45 @@ +package io.github.wulkanowy.data.repositories.mobiledevice + +import io.github.wulkanowy.data.db.entities.MobileDevice +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.pojos.MobileDeviceToken +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getDevices(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getRegisteredDevices() + .map { + MobileDevice( + studentId = semester.studentId, + date = it.createDate, + deviceId = it.id, + name = it.name + ) + } + } + + suspend fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice): Boolean { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .unregisterDevice(device.deviceId) + } + + suspend fun getToken(student: Student, semester: Semester): MobileDeviceToken { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getToken() + .let { + MobileDeviceToken( + token = it.token, + symbol = it.symbol, + pin = it.pin, + qr = it.qrCodeImage + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRepository.kt new file mode 100644 index 00000000..65526ef8 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/mobiledevice/MobileDeviceRepository.kt @@ -0,0 +1,36 @@ +package io.github.wulkanowy.data.repositories.mobiledevice + +import io.github.wulkanowy.data.db.entities.MobileDevice +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.pojos.MobileDeviceToken +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MobileDeviceRepository @Inject constructor( + private val local: MobileDeviceLocal, + private val remote: MobileDeviceRemote +) { + + fun getDevices(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getDevices(semester) }, + fetch = { remote.getDevices(student, semester) }, + saveFetchResult = { old, new -> + local.deleteDevices(old uniqueSubtract new) + local.saveDevices(new uniqueSubtract old) + } + ) + + suspend fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice) { + remote.unregisterDevice(student, semester, device) + local.deleteDevices(listOf(device)) + } + + suspend fun getToken(student: Student, semester: Semester): MobileDeviceToken { + return remote.getToken(student, semester) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteLocal.kt new file mode 100644 index 00000000..85ba5e22 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteLocal.kt @@ -0,0 +1,28 @@ +package io.github.wulkanowy.data.repositories.note + +import io.github.wulkanowy.data.db.dao.NoteDao +import io.github.wulkanowy.data.db.entities.Note +import io.github.wulkanowy.data.db.entities.Student +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NoteLocal @Inject constructor(private val noteDb: NoteDao) { + + suspend fun saveNotes(notes: List) { + noteDb.insertAll(notes) + } + + suspend fun updateNotes(notes: List) { + noteDb.updateAll(notes) + } + + suspend fun deleteNotes(notes: List) { + noteDb.deleteAll(notes) + } + + fun getNotes(student: Student): Flow> { + return noteDb.loadAll(student.studentId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRemote.kt new file mode 100644 index 00000000..0e488b7d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRemote.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.data.repositories.note + +import io.github.wulkanowy.data.db.entities.Note +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NoteRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getNotes(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getNotes(semester.semesterId) + .map { + Note( + studentId = semester.studentId, + date = it.date, + teacher = it.teacher, + teacherSymbol = it.teacherSymbol, + category = it.category, + categoryType = it.categoryType.id, + isPointsShow = it.showPoints, + points = it.points, + content = it.content + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRepository.kt new file mode 100644 index 00000000..6cf62ba2 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/note/NoteRepository.kt @@ -0,0 +1,45 @@ +package io.github.wulkanowy.data.repositories.note + +import io.github.wulkanowy.data.db.entities.Note +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class NoteRepository @Inject constructor( + private val local: NoteLocal, + private val remote: NoteRemote +) { + + fun getNotes(student: Student, semester: Semester, forceRefresh: Boolean, notify: Boolean = false) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getNotes(student) }, + fetch = { remote.getNotes(student, semester) }, + saveFetchResult = { old, new -> + local.deleteNotes(old uniqueSubtract new) + local.saveNotes((new uniqueSubtract old).onEach { + if (it.date >= student.registrationDate.toLocalDate()) it.apply { + isRead = false + if (notify) isNotified = false + } + }) + } + ) + + fun getNotNotifiedNotes(student: Student): Flow> { + return local.getNotes(student).map { it.filter { note -> !note.isNotified } } + } + + suspend fun updateNote(note: Note) { + local.updateNotes(listOf(note)) + } + + suspend fun updateNotes(notes: List) { + return local.updateNotes(notes) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt new file mode 100644 index 00000000..da31751a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt @@ -0,0 +1,104 @@ +package io.github.wulkanowy.data.repositories.preferences + +import android.content.Context +import android.content.SharedPreferences +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.ui.modules.grade.GradeAverageMode +import io.github.wulkanowy.ui.modules.grade.GradeSortingMode +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class PreferencesRepository @Inject constructor( + private val sharedPref: SharedPreferences, + @ApplicationContext val context: Context +) { + val startMenuIndex: Int + get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt() + + val isShowPresent: Boolean + get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present) + + val gradeAverageMode: GradeAverageMode + get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)) + + val gradeAverageForceCalc: Boolean + get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc) + + val isGradeExpandable: Boolean + get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade) + + val showAllSubjectsOnStatisticsList: Boolean + get() = getBoolean(R.string.pref_key_grade_statistics_list, R.bool.pref_default_grade_statistics_list) + + val appThemeKey = context.getString(R.string.pref_key_app_theme) + val appTheme: String + get() = getString(appThemeKey, R.string.pref_default_app_theme) + + val gradeColorTheme: String + get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme) + + val appLanguageKey = context.getString(R.string.pref_key_app_language) + val appLanguage + get() = getString(appLanguageKey, R.string.pref_default_app_language) + + val serviceEnableKey = context.getString(R.string.pref_key_services_enable) + val isServiceEnabled: Boolean + get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable) + + val servicesIntervalKey = context.getString(R.string.pref_key_services_interval) + val servicesInterval: Long + get() = getString(servicesIntervalKey, R.string.pref_default_services_interval).toLong() + + val servicesOnlyWifiKey = context.getString(R.string.pref_key_services_wifi_only) + val isServicesOnlyWifi: Boolean + get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only) + + val isNotificationsEnable: Boolean + get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable) + + val isUpcomingLessonsNotificationsEnableKey = context.getString(R.string.pref_key_notifications_upcoming_lessons_enable) + val isUpcomingLessonsNotificationsEnable: Boolean + get() = getBoolean(isUpcomingLessonsNotificationsEnableKey, R.bool.pref_default_notification_upcoming_lessons_enable) + + val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug) + val isDebugNotificationEnable: Boolean + get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug) + + val gradePlusModifier: Double + get() = getString(R.string.pref_key_grade_modifier_plus, R.string.pref_default_grade_modifier_plus).toDouble() + + val gradeMinusModifier: Double + get() = getString(R.string.pref_key_grade_modifier_minus, R.string.pref_default_grade_modifier_minus).toDouble() + + val fillMessageContent: Boolean + get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content) + + val showGroupsInPlan: Boolean + get() = getBoolean(R.string.pref_key_timetable_show_groups, R.bool.pref_default_timetable_show_groups) + + val showWholeClassPlan: String + get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class) + + val gradeSortingMode: GradeSortingMode + get() = GradeSortingMode.getByValue(getString(R.string.pref_key_grade_sorting_mode, R.string.pref_default_grade_sorting_mode)) + + val showTimetableTimers: Boolean + get() = getBoolean(R.string.pref_key_timetable_show_timers, R.bool.pref_default_timetable_show_timers) + + var isHomeworkFullscreen: Boolean + get() = getBoolean(R.string.pref_key_homework_fullscreen, R.bool.pref_default_homework_fullscreen) + set(value) = sharedPref.edit().putBoolean("homework_fullscreen", value).apply() + + val showSubjectsWithoutGrades: Boolean + get() = getBoolean(R.string.pref_key_subjects_without_grades, R.bool.pref_default_subjects_without_grades) + + private fun getString(id: Int, default: Int) = getString(context.getString(id), default) + + private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default) + + private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default) + + private fun getBoolean(id: String, default: Int) = sharedPref.getBoolean(id, context.resources.getBoolean(default)) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt new file mode 100644 index 00000000..fac1645e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.data.repositories.recipient + +import io.github.wulkanowy.data.db.dao.RecipientDao +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class RecipientLocal @Inject constructor(private val recipientDb: RecipientDao) { + + suspend fun getRecipients(student: Student, role: Int, unit: ReportingUnit): List { + return recipientDb.load(student.studentId, role, unit.realId) + } + + suspend fun saveRecipients(recipients: List): List { + return recipientDb.insertAll(recipients) + } + + suspend fun deleteRecipients(recipients: List) { + recipientDb.deleteAll(recipients) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt new file mode 100644 index 00000000..a5318e77 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRemote.kt @@ -0,0 +1,38 @@ +package io.github.wulkanowy.data.repositories.recipient + +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton +import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient + +@Singleton +class RecipientRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getRecipients(student: Student, role: Int, unit: ReportingUnit): List { + return sdk.init(student).getRecipients(unit.realId, role) + .map { it.toRecipient() } + } + + suspend fun getMessageRecipients(student: Student, message: Message): List { + return sdk.init(student).getMessageRecipients(message.messageId, message.senderId) + .map { it.toRecipient() } + } + + private fun SdkRecipient.toRecipient(): Recipient { + return Recipient( + studentId = sdk.studentId, + realId = id, + realName = name, + name = shortName, + hash = hash, + loginId = loginId, + role = role, + unitId = reportingUnitId ?: 0 + ) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt new file mode 100644 index 00000000..f5e876b0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientRepository.kt @@ -0,0 +1,36 @@ +package io.github.wulkanowy.data.repositories.recipient + +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.Recipient +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class RecipientRepository @Inject constructor( + private val local: RecipientLocal, + private val remote: RecipientRemote +) { + + suspend fun refreshRecipients(student: Student, role: Int, unit: ReportingUnit) { + val new = remote.getRecipients(student, role, unit) + val old = local.getRecipients(student, role, unit) + + local.deleteRecipients(old uniqueSubtract new) + local.saveRecipients(new uniqueSubtract old) + } + + suspend fun getRecipients(student: Student, role: Int, unit: ReportingUnit): List { + return local.getRecipients(student, role, unit).ifEmpty { + refreshRecipients(student, role, unit) + + local.getRecipients(student, role, unit) + } + } + + suspend fun getMessageRecipients(student: Student, message: Message): List { + return remote.getMessageRecipients(student, message) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRemote.kt new file mode 100644 index 00000000..11eac71e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRemote.kt @@ -0,0 +1,18 @@ +package io.github.wulkanowy.data.repositories.recover + +import io.github.wulkanowy.sdk.Sdk +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class RecoverRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getReCaptchaSiteKey(host: String, symbol: String): Pair { + return sdk.getPasswordResetCaptchaCode(host, symbol) + } + + suspend fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): String { + return sdk.sendPasswordResetRequest(url, symbol, email, reCaptchaResponse) + } +} + diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRepository.kt new file mode 100644 index 00000000..3117a606 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recover/RecoverRepository.kt @@ -0,0 +1,16 @@ +package io.github.wulkanowy.data.repositories.recover + +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class RecoverRepository @Inject constructor(private val remote: RecoverRemote) { + + suspend fun getReCaptchaSiteKey(host: String, symbol: String): Pair { + return remote.getReCaptchaSiteKey(host, symbol) + } + + suspend fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): String { + return remote.sendRecoverRequest(url, symbol, email, reCaptchaResponse) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt new file mode 100644 index 00000000..737f1a04 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt @@ -0,0 +1,27 @@ +package io.github.wulkanowy.data.repositories.reportingunit + +import io.github.wulkanowy.data.db.dao.ReportingUnitDao +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ReportingUnitLocal @Inject constructor(private val reportingUnitDb: ReportingUnitDao) { + + suspend fun getReportingUnits(student: Student): List { + return reportingUnitDb.load(student.studentId) + } + + suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? { + return reportingUnitDb.loadOne(student.studentId, unitId) + } + + suspend fun saveReportingUnits(reportingUnits: List): List { + return reportingUnitDb.insertAll(reportingUnits) + } + + suspend fun deleteReportingUnits(reportingUnits: List) { + reportingUnitDb.deleteAll(reportingUnits) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRemote.kt new file mode 100644 index 00000000..6b11c2cc --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRemote.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.reportingunit + +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ReportingUnitRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getReportingUnits(student: Student): List { + return sdk.init(student).getReportingUnits().map { unit -> + ReportingUnit( + studentId = sdk.studentId, + realId = unit.id, + roles = unit.roles, + senderId = unit.senderId, + senderName = unit.senderName, + shortName = unit.short + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRepository.kt new file mode 100644 index 00000000..ff583946 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitRepository.kt @@ -0,0 +1,38 @@ +package io.github.wulkanowy.data.repositories.reportingunit + +import io.github.wulkanowy.data.db.entities.ReportingUnit +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class ReportingUnitRepository @Inject constructor( + private val local: ReportingUnitLocal, + private val remote: ReportingUnitRemote +) { + + suspend fun refreshReportingUnits(student: Student) { + val new = remote.getReportingUnits(student) + val old = local.getReportingUnits(student) + + local.deleteReportingUnits(old.uniqueSubtract(new)) + local.saveReportingUnits(new.uniqueSubtract(old)) + } + + suspend fun getReportingUnits(student: Student): List { + return local.getReportingUnits(student).ifEmpty { + refreshReportingUnits(student) + + local.getReportingUnits(student) + } + } + + suspend fun getReportingUnit(student: Student, unitId: Int): ReportingUnit? { + return local.getReportingUnit(student, unitId) ?: run { + refreshReportingUnits(student) + + return local.getReportingUnit(student, unitId) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt new file mode 100644 index 00000000..bc1b2f44 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolLocal.kt @@ -0,0 +1,22 @@ +package io.github.wulkanowy.data.repositories.school + +import io.github.wulkanowy.data.db.dao.SchoolDao +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.data.db.entities.Semester +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class SchoolLocal @Inject constructor(private val schoolDb: SchoolDao) { + + suspend fun saveSchool(school: School) { + schoolDb.insertAll(listOf(school)) + } + + suspend fun deleteSchool(school: School) { + schoolDb.deleteAll(listOf(school)) + } + + fun getSchool(semester: Semester): Flow { + return schoolDb.load(semester.studentId, semester.classId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt new file mode 100644 index 00000000..4d2e0cd6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRemote.kt @@ -0,0 +1,27 @@ +package io.github.wulkanowy.data.repositories.school + +import io.github.wulkanowy.data.db.entities.School +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject + +class SchoolRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getSchoolInfo(student: Student, semester: Semester): School { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getSchool() + .let { + School( + studentId = semester.studentId, + classId = semester.classId, + name = it.name, + address = it.address, + contact = it.contact, + headmaster = it.headmaster, + pedagogue = it.pedagogue + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt new file mode 100644 index 00000000..4c84c319 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/school/SchoolRepository.kt @@ -0,0 +1,27 @@ +package io.github.wulkanowy.data.repositories.school + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SchoolRepository @Inject constructor( + private val local: SchoolLocal, + private val remote: SchoolRemote +) { + + fun getSchoolInfo(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it == null || forceRefresh }, + query = { local.getSchool(semester) }, + fetch = { remote.getSchoolInfo(student, semester) }, + saveFetchResult = { old, new -> + if (new != old && old != null) { + local.deleteSchool(old) + local.saveSchool(new) + } + local.saveSchool(new) + } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterLocal.kt new file mode 100644 index 00000000..8ecf1595 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterLocal.kt @@ -0,0 +1,23 @@ +package io.github.wulkanowy.data.repositories.semester + +import io.github.wulkanowy.data.db.dao.SemesterDao +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) { + + suspend fun saveSemesters(semesters: List) { + semesterDb.insertSemesters(semesters) + } + + suspend fun deleteSemesters(semesters: List) { + semesterDb.deleteAll(semesters) + } + + suspend fun getSemesters(student: Student): List { + return semesterDb.loadAll(student.studentId, student.classId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt new file mode 100644 index 00000000..e1a920b6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRemote.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.data.repositories.semester + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SemesterRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getSemesters(student: Student): List { + return sdk.init(student).getSemesters().map { + Semester( + studentId = student.studentId, + diaryId = it.diaryId, + diaryName = it.diaryName, + schoolYear = it.schoolYear, + semesterId = it.semesterId, + semesterName = it.semesterNumber, + start = it.start, + end = it.end, + classId = it.classId, + unitId = it.unitId + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt new file mode 100644 index 00000000..2748f1df --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/semester/SemesterRepository.kt @@ -0,0 +1,55 @@ +package io.github.wulkanowy.data.repositories.semester + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.DispatchersProvider +import io.github.wulkanowy.utils.getCurrentOrLast +import io.github.wulkanowy.utils.isCurrent +import io.github.wulkanowy.utils.uniqueSubtract +import kotlinx.coroutines.withContext +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SemesterRepository @Inject constructor( + private val remote: SemesterRemote, + private val local: SemesterLocal, + private val dispatchers: DispatchersProvider +) { + + suspend fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false) = withContext(dispatchers.backgroundThread) { + val semesters = local.getSemesters(student) + + if (isShouldFetch(student, semesters, forceRefresh, refreshOnNoCurrent)) { + refreshSemesters(student) + local.getSemesters(student) + } else semesters + } + + private fun isShouldFetch(student: Student, semesters: List, forceRefresh: Boolean, refreshOnNoCurrent: Boolean): Boolean { + val isNoSemesters = semesters.isEmpty() + + val isRefreshOnModeChangeRequired = if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) { + semesters.firstOrNull { it.isCurrent }?.diaryId == 0 + } else false + + val isRefreshOnNoCurrentAppropriate = refreshOnNoCurrent && !semesters.any { semester -> semester.isCurrent } + + return forceRefresh || isNoSemesters || isRefreshOnModeChangeRequired || isRefreshOnNoCurrentAppropriate + } + + private suspend fun refreshSemesters(student: Student) { + val new = remote.getSemesters(student) + if (new.isEmpty()) return Timber.i("Empty semester list!") + + val old = local.getSemesters(student) + local.deleteSemesters(old.uniqueSubtract(new)) + local.saveSemesters(new.uniqueSubtract(old)) + } + + suspend fun getCurrentSemester(student: Student, forceRefresh: Boolean = false) = withContext(dispatchers.backgroundThread) { + getSemesters(student, forceRefresh).getCurrentOrLast() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentLocal.kt new file mode 100644 index 00000000..c01d1d04 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentLocal.kt @@ -0,0 +1,59 @@ +package io.github.wulkanowy.data.repositories.student + +import android.content.Context +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.data.db.dao.StudentDao +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.DispatchersProvider +import io.github.wulkanowy.utils.security.decrypt +import io.github.wulkanowy.utils.security.encrypt +import kotlinx.coroutines.withContext +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class StudentLocal @Inject constructor( + private val studentDb: StudentDao, + private val dispatchers: DispatchersProvider, + @ApplicationContext private val context: Context +) { + + suspend fun saveStudents(students: List) = withContext(dispatchers.backgroundThread) { + studentDb.insertAll(students.map { + if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.API) it.copy(password = encrypt(it.password, context)) + else it + }) + } + + suspend fun getStudents(decryptPass: Boolean) = withContext(dispatchers.backgroundThread) { + studentDb.loadStudentsWithSemesters().map { + it.apply { + if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) student.password = decrypt(student.password) + } + } + } + + suspend fun getStudentById(id: Int) = withContext(dispatchers.backgroundThread) { + studentDb.loadById(id)?.apply { + if (Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) + } + } + + suspend fun getCurrentStudent(decryptPass: Boolean) = withContext(dispatchers.backgroundThread) { + studentDb.loadCurrent()?.apply { + if (decryptPass && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) + } + } + + suspend fun setCurrentStudent(student: Student) = withContext(dispatchers.backgroundThread) { + studentDb.run { + resetCurrent() + updateCurrent(student.id) + } + } + + suspend fun logoutStudent(student: Student) = withContext(dispatchers.backgroundThread) { + studentDb.delete(student) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt new file mode 100644 index 00000000..dcb12623 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt @@ -0,0 +1,23 @@ +package io.github.wulkanowy.data.repositories.student + +import io.github.wulkanowy.data.mappers.mapToEntities +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.sdk.Sdk +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class StudentRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getStudentsMobileApi(token: String, pin: String, symbol: String): List { + return sdk.getStudentsFromMobileApi(token, pin, symbol, "").mapToEntities() + } + + suspend fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): List { + return sdk.getStudentsFromScrapper(email, password, scrapperBaseUrl, symbol).mapToEntities(password) + } + + suspend fun getStudentsHybrid(email: String, password: String, scrapperBaseUrl: String, symbol: String): List { + return sdk.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol).mapToEntities(password) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRepository.kt new file mode 100644 index 00000000..19e0e208 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRepository.kt @@ -0,0 +1,57 @@ +package io.github.wulkanowy.data.repositories.student + +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.exceptions.NoCurrentStudentException +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.data.repositories.semester.SemesterLocal +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class StudentRepository @Inject constructor( + private val local: StudentLocal, + private val semestersLocal: SemesterLocal, + private val remote: StudentRemote +) { + + suspend fun isStudentSaved(): Boolean = local.getStudents(false).isNotEmpty() + + suspend fun isCurrentStudentSet(): Boolean = local.getCurrentStudent(false)?.isCurrent ?: false + + suspend fun getStudentsApi(pin: String, symbol: String, token: String): List { + return remote.getStudentsMobileApi(token, pin, symbol) + } + + suspend fun getStudentsScrapper(email: String, password: String, endpoint: String, symbol: String): List { + return remote.getStudentsScrapper(email, password, endpoint, symbol) + } + + suspend fun getStudentsHybrid(email: String, password: String, endpoint: String, symbol: String): List { + return remote.getStudentsHybrid(email, password, endpoint, symbol) + } + + suspend fun getSavedStudents(decryptPass: Boolean = true): List { + return local.getStudents(decryptPass) + } + + suspend fun getStudentById(id: Int): Student { + return local.getStudentById(id) ?: throw NoCurrentStudentException() + } + + suspend fun getCurrentStudent(decryptPass: Boolean = true): Student { + return local.getCurrentStudent(decryptPass) ?: throw NoCurrentStudentException() + } + + suspend fun saveStudents(studentsWithSemesters: List): List { + semestersLocal.saveSemesters(studentsWithSemesters.flatMap { it.semesters }) + return local.saveStudents(studentsWithSemesters.map { it.student }) + } + + suspend fun switchStudent(studentWithSemesters: StudentWithSemesters) { + return local.setCurrentStudent(studentWithSemesters.student) + } + + suspend fun logoutStudent(student: Student) { + return local.logoutStudent(student) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectLocal.kt new file mode 100644 index 00000000..e225a381 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectLocal.kt @@ -0,0 +1,24 @@ +package io.github.wulkanowy.data.repositories.subject + +import io.github.wulkanowy.data.db.dao.SubjectDao +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Subject +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SubjectLocal @Inject constructor(private val subjectDao: SubjectDao) { + + fun getSubjects(semester: Semester): Flow> { + return subjectDao.loadAll(semester.diaryId, semester.studentId) + } + + suspend fun saveSubjects(subjects: List) { + subjectDao.insertAll(subjects) + } + + suspend fun deleteSubjects(subjects: List) { + subjectDao.deleteAll(subjects) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRemote.kt new file mode 100644 index 00000000..624a5a00 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRemote.kt @@ -0,0 +1,26 @@ +package io.github.wulkanowy.data.repositories.subject + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.db.entities.Subject +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SubjectRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getSubjects(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getSubjects() + .map { + Subject( + studentId = semester.studentId, + diaryId = semester.diaryId, + name = it.name, + realId = it.id + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRepository.kt new file mode 100644 index 00000000..60a0c3e7 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/subject/SubjectRepository.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.subject + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class SubjectRepository @Inject constructor( + private val local: SubjectLocal, + private val remote: SubjectRemote +) { + + fun getSubjects(student: Student, semester: Semester, forceRefresh: Boolean = false) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getSubjects(semester) }, + fetch = { remote.getSubjects(student, semester) }, + saveFetchResult = { old, new -> + local.deleteSubjects(old uniqueSubtract new) + local.saveSubjects(new uniqueSubtract old) + } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt new file mode 100644 index 00000000..908f45a1 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherLocal.kt @@ -0,0 +1,22 @@ +package io.github.wulkanowy.data.repositories.teacher + +import io.github.wulkanowy.data.db.dao.TeacherDao +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Teacher +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) { + + suspend fun saveTeachers(teachers: List) { + teacherDb.insertAll(teachers) + } + + suspend fun deleteTeachers(teachers: List) { + teacherDb.deleteAll(teachers) + } + + fun getTeachers(semester: Semester): Flow> { + return teacherDb.loadAll(semester.studentId, semester.classId) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRemote.kt new file mode 100644 index 00000000..1d1caa68 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRemote.kt @@ -0,0 +1,27 @@ +package io.github.wulkanowy.data.repositories.teacher + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.db.entities.Teacher +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TeacherRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getTeachers(student: Student, semester: Semester): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getTeachers(semester.semesterId) + .map { + Teacher( + studentId = semester.studentId, + name = it.name, + subject = it.subject, + shortName = it.short, + classId = semester.classId + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt new file mode 100644 index 00000000..df25a53e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/teacher/TeacherRepository.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.teacher + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.uniqueSubtract +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TeacherRepository @Inject constructor( + private val local: TeacherLocal, + private val remote: TeacherRemote +) { + + fun getTeachers(student: Student, semester: Semester, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getTeachers(semester) }, + fetch = { remote.getTeachers(student, semester) }, + saveFetchResult = { old, new -> + local.deleteTeachers(old uniqueSubtract new) + local.saveTeachers(new uniqueSubtract old) + } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocal.kt new file mode 100644 index 00000000..df4bfb20 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocal.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.data.repositories.timetable + +import io.github.wulkanowy.data.db.dao.TimetableDao +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Timetable +import kotlinx.coroutines.flow.Flow +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TimetableLocal @Inject constructor(private val timetableDb: TimetableDao) { + + suspend fun saveTimetable(timetables: List) { + timetableDb.insertAll(timetables) + } + + suspend fun deleteTimetable(timetables: List) { + timetableDb.deleteAll(timetables) + } + + fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Flow> { + return timetableDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt new file mode 100644 index 00000000..9fb80e77 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRemote.kt @@ -0,0 +1,40 @@ +package io.github.wulkanowy.data.repositories.timetable + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.sdk.Sdk +import io.github.wulkanowy.utils.init +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TimetableRemote @Inject constructor(private val sdk: Sdk) { + + suspend fun getTimetable(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List { + return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear) + .getTimetable(startDate, endDate).first + .map { + Timetable( + studentId = semester.studentId, + diaryId = semester.diaryId, + number = it.number, + start = it.start, + end = it.end, + date = it.date, + subject = it.subject, + subjectOld = it.subjectOld, + group = it.group, + room = it.room, + roomOld = it.roomOld, + teacher = it.teacher, + teacherOld = it.teacherOld, + info = it.info, + isStudentPlan = it.studentPlan, + changes = it.changes, + canceled = it.canceled + ) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt new file mode 100644 index 00000000..ee2734aa --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepository.kt @@ -0,0 +1,41 @@ +package io.github.wulkanowy.data.repositories.timetable + +import io.github.wulkanowy.data.db.entities.Semester +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.networkBoundResource +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.uniqueSubtract +import kotlinx.coroutines.flow.map +import java.time.LocalDate +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TimetableRepository @Inject constructor( + private val local: TimetableLocal, + private val remote: TimetableRemote, + private val schedulerHelper: TimetableNotificationSchedulerHelper +) { + + fun getTimetable(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean) = networkBoundResource( + shouldFetch = { it.isEmpty() || forceRefresh }, + query = { local.getTimetable(semester, start.monday, end.sunday).map { schedulerHelper.scheduleNotifications(it, student); it } }, + fetch = { remote.getTimetable(student, semester, start.monday, end.sunday) }, + saveFetchResult = { old, new -> + local.deleteTimetable(old.uniqueSubtract(new).also { schedulerHelper.cancelScheduled(it) }) + local.saveTimetable(new.uniqueSubtract(old).also { schedulerHelper.scheduleNotifications(it, student) }.map { item -> + item.also { new -> + old.singleOrNull { new.start == it.start }?.let { old -> + return@map new.copy( + room = if (new.room.isEmpty()) old.room else new.room, + teacher = if (new.teacher.isEmpty() && !new.changes && !old.changes) old.teacher else new.teacher + ) + } + } + }) + }, + filterResult = { it.filter { item -> item.date in start..end } } + ) +} diff --git a/app/src/main/java/io/github/wulkanowy/data/serializers/LocalDateSerializer.kt b/app/src/main/java/io/github/wulkanowy/data/serializers/LocalDateSerializer.kt deleted file mode 100644 index ba97d37a..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/serializers/LocalDateSerializer.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.data.serializers - -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.nullable -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import java.time.LocalDate - -@OptIn(ExperimentalSerializationApi::class) -object LocalDateSerializer : KSerializer { - - override val descriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.LONG).nullable - - override fun serialize(encoder: Encoder, value: LocalDate?) { - if (value == null) { - encoder.encodeNull() - } else { - encoder.encodeNotNullMark() - encoder.encodeLong(value.toEpochDay()) - } - } - - override fun deserialize(decoder: Decoder): LocalDate? = - if (decoder.decodeNotNullMark()) { - LocalDate.ofEpochDay(decoder.decodeLong()) - } else { - decoder.decodeNull() - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/serializers/SafeMessageTypeEnumListSerializer.kt b/app/src/main/java/io/github/wulkanowy/data/serializers/SafeMessageTypeEnumListSerializer.kt deleted file mode 100644 index a95eab80..00000000 --- a/app/src/main/java/io/github/wulkanowy/data/serializers/SafeMessageTypeEnumListSerializer.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.wulkanowy.data.serializers - -import io.github.wulkanowy.data.enums.MessageType -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -@OptIn(ExperimentalSerializationApi::class) -object SafeMessageTypeEnumListSerializer : KSerializer> { - - private val serializer = ListSerializer(String.serializer()) - - override val descriptor = serializer.descriptor - - override fun serialize(encoder: Encoder, value: List) { - encoder.encodeNotNullMark() - serializer.serialize(encoder, value.map { it.name }) - } - - override fun deserialize(decoder: Decoder): List = - serializer.deserialize(decoder).mapNotNull { enumName -> - MessageType.entries.find { it.name == enumName } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt deleted file mode 100644 index 8b0d67b5..00000000 --- a/app/src/main/java/io/github/wulkanowy/domain/adminmessage/GetAppropriateAdminMessageUseCase.kt +++ /dev/null @@ -1,64 +0,0 @@ -package io.github.wulkanowy.domain.adminmessage - -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.mapResourceData -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.WulkanowyRepository -import io.github.wulkanowy.utils.AppInfo -import kotlinx.coroutines.flow.Flow -import javax.inject.Inject - -class GetAppropriateAdminMessageUseCase @Inject constructor( - private val wulkanowyRepository: WulkanowyRepository, - private val preferencesRepository: PreferencesRepository, - private val appInfo: AppInfo -) { - - operator fun invoke(student: Student, type: MessageType): Flow> { - return invoke(student.scrapperBaseUrl, type) - } - - operator fun invoke(scrapperBaseUrl: String, type: MessageType): Flow> { - return wulkanowyRepository.getAdminMessages().mapResourceData { adminMessages -> - adminMessages - .asSequence() - .filter { it.isNotDismissed() } - .filter { it.isVersionMatch() } - .filter { it.isRegisterHostMatch(scrapperBaseUrl) } - .filter { it.isFlavorMatch() } - .filter { it.isTypeMatch(type) } - .maxByOrNull { it.id } - } - } - - private fun AdminMessage.isNotDismissed(): Boolean { - return id !in preferencesRepository.dismissedAdminMessageIds - } - - private fun AdminMessage.isRegisterHostMatch(scrapperBaseUrl: String): Boolean { - return targetRegisterHost?.let { - scrapperBaseUrl.contains(it, true) - } ?: true - } - - private fun AdminMessage.isFlavorMatch(): Boolean { - return targetFlavor?.equals(appInfo.buildFlavor, true) ?: true - } - - private fun AdminMessage.isVersionMatch(): Boolean { - val isCorrectMaxVersion = versionMax?.let { it >= appInfo.versionCode } ?: true - val isCorrectMinVersion = versionMin?.let { it <= appInfo.versionCode } ?: true - - return isCorrectMaxVersion && isCorrectMinVersion - } - - private fun AdminMessage.isTypeMatch(messageType: MessageType): Boolean { - if (messageType in types) return true - if (MessageType.GENERAL_MESSAGE in types) return true - - return false - } -} diff --git a/app/src/main/java/io/github/wulkanowy/domain/attendance/GetAttendanceCalculatorDataUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/attendance/GetAttendanceCalculatorDataUseCase.kt deleted file mode 100644 index 294abd1b..00000000 --- a/app/src/main/java/io/github/wulkanowy/domain/attendance/GetAttendanceCalculatorDataUseCase.kt +++ /dev/null @@ -1,106 +0,0 @@ -package io.github.wulkanowy.domain.attendance - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.AttendanceSummary -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.Subject -import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode -import io.github.wulkanowy.data.enums.AttendanceCalculatorSortingMode.* -import io.github.wulkanowy.data.pojos.AttendanceData -import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SubjectRepository -import io.github.wulkanowy.utils.allAbsences -import io.github.wulkanowy.utils.allPresences -import kotlinx.coroutines.flow.Flow -import javax.inject.Inject -import kotlin.math.ceil -import kotlin.math.floor - -class GetAttendanceCalculatorDataUseCase @Inject constructor( - private val subjectRepository: SubjectRepository, - private val attendanceSummaryRepository: AttendanceSummaryRepository, - private val preferencesRepository: PreferencesRepository, -) { - - operator fun invoke( - student: Student, - semester: Semester, - forceRefresh: Boolean, - ): Flow>> = - subjectRepository.getSubjects(student, semester, forceRefresh) - .mapResourceData { subjects -> subjects.sortedBy(Subject::name) } - .combineWithResourceData(preferencesRepository.targetAttendanceFlow, ::Pair) - .flatMapResourceData { (subjects, targetFreq) -> - combineResourceFlows(subjects.map { subject -> - attendanceSummaryRepository.getAttendanceSummary( - student = student, - semester = semester, - subjectId = subject.realId, - forceRefresh = forceRefresh - ).mapResourceData { summaries -> - summaries.toAttendanceData(subject.name, targetFreq) - } - }) - // Every individual combined flow causes separate network requests to update data. - // When there is N child flows, they can cause up to N-1 items to be emitted. Since all - // requests are usually completed in less than 5s, there is no need to emit multiple - // intermediates that will be visible for barely any time. - .debounceIntermediates() - } - .combineWithResourceData(preferencesRepository.attendanceCalculatorShowEmptySubjects) { attendanceDataList, showEmptySubjects -> - attendanceDataList.filter { it.total != 0 || showEmptySubjects } - } - .combineWithResourceData(preferencesRepository.attendanceCalculatorSortingModeFlow, List::sortedBy) -} - -private fun List.toAttendanceData(subjectName: String, targetFreq: Int): AttendanceData { - val presences = sumOf { it.allPresences } - val absences = sumOf { it.allAbsences } - return AttendanceData( - subjectName = subjectName, - lessonBalance = calcLessonBalance( - targetFreq.toDouble() / 100, presences, absences - ), - presences = presences, - absences = absences, - ) -} - -private fun calcLessonBalance(targetFreq: Double, presences: Int, absences: Int): Int { - val total = presences + absences - // The `+ 1` is to avoid false positives in close cases. Eg.: - // target frequency 99%, 1 presence. Without the `+ 1` this would be reported shown as - // a positive balance of +1, however that is not actually true as skipping one class - // would make it so that the balance would actually be negative (-98). The `+ 1` - // fixes this and makes sure that in situations like these, it's not reporting incorrect - // balances - return when { - presences / (total + 1f) >= targetFreq -> calcMissingAbsences( - targetFreq, absences, presences - ) - presences / (total + 0f) < targetFreq -> -calcMissingPresences( - targetFreq, absences, presences - ) - else -> 0 - } -} - -private fun calcMissingPresences(targetFreq: Double, absences: Int, presences: Int) = - calcMinRequiredPresencesFor(targetFreq, absences) - presences - -private fun calcMinRequiredPresencesFor(targetFreq: Double, absences: Int) = - ceil((targetFreq / (1 - targetFreq)) * absences).toInt() - -private fun calcMissingAbsences(targetFreq: Double, absences: Int, presences: Int) = - calcMinRequiredAbsencesFor(targetFreq, presences) - absences - -private fun calcMinRequiredAbsencesFor(targetFreq: Double, presences: Int) = - floor((presences * (1 - targetFreq)) / targetFreq).toInt() - -private fun List.sortedBy(mode: AttendanceCalculatorSortingMode) = when (mode) { - ALPHABETIC -> sortedBy(AttendanceData::subjectName) - ATTENDANCE -> sortedByDescending(AttendanceData::presencePercentage) - LESSON_BALANCE -> sortedBy(AttendanceData::lessonBalance) -} diff --git a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt deleted file mode 100644 index 8f25eba1..00000000 --- a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.wulkanowy.domain.messages - -import io.github.wulkanowy.data.db.dao.MailboxDao -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.Student -import javax.inject.Inject - -class GetMailboxByStudentUseCase @Inject constructor( - private val mailboxDao: MailboxDao, -) { - - suspend operator fun invoke(student: Student): Mailbox? { - return mailboxDao.loadAll(student.email) - .filterByStudent(student) - } - - private fun List.filterByStudent(student: Student): Mailbox? { - val normalizedStudentName = student.studentName.normalizeStudentName() - - return singleOrNull { - it.studentName.normalizeStudentName() == normalizedStudentName - } ?: singleOrNull { - it.studentName.normalizeStudentName() == normalizedStudentName - && it.schoolNameShort == student.schoolShortName - } ?: singleOrNull { - it.studentName.getFirstAndLastPart() == normalizedStudentName.getFirstAndLastPart() - } ?: singleOrNull { - it.studentName.getReversedName() == normalizedStudentName - } ?: singleOrNull { - it.studentName.getUnauthorizedVersion() == normalizedStudentName - } - } - - private fun String.normalizeStudentName(): String { - return trim().split(" ") - .filter { it.isNotBlank() } - .joinToString(" ") { part -> - part.lowercase().replaceFirstChar { it.uppercase() } - } - } - - private fun String.getFirstAndLastPart(): String { - val parts = normalizeStudentName().split(" ") - - val endParts = parts.filterIndexed { i, _ -> - i == 0 || parts.size - 1 == i - } - return endParts.joinToString(" ") - } - - private fun String.getReversedName(): String { - val parts = normalizeStudentName().split(" ") - - return parts - .asReversed() - .joinToString(" ") - } - - private fun String.getUnauthorizedVersion(): String { - return normalizeStudentName().split(" ") - .joinToString(" ") { - it.firstOrNull()?.toString().orEmpty() + "*".repeat((it.length - 1).coerceAtLeast(0)) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/domain/timetable/IsStudentHasLessonsOnWeekendUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/timetable/IsStudentHasLessonsOnWeekendUseCase.kt deleted file mode 100644 index ffd00574..00000000 --- a/app/src/main/java/io/github/wulkanowy/domain/timetable/IsStudentHasLessonsOnWeekendUseCase.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.wulkanowy.domain.timetable - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.sunday -import java.time.LocalDate -import javax.inject.Inject - -class IsStudentHasLessonsOnWeekendUseCase @Inject constructor( - private val timetableRepository: TimetableRepository, - private val isWeekendHasLessonsUseCase: IsWeekendHasLessonsUseCase, -) { - - suspend operator fun invoke( - semester: Semester, - currentDate: LocalDate = LocalDate.now(), - ): Boolean { - val lessons = timetableRepository.getTimetableFromDatabase( - semester = semester, - start = currentDate.monday, - end = currentDate.sunday, - ) - return isWeekendHasLessonsUseCase(lessons) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/domain/timetable/IsWeekendHasLessonsUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/timetable/IsWeekendHasLessonsUseCase.kt deleted file mode 100644 index 908c9df7..00000000 --- a/app/src/main/java/io/github/wulkanowy/domain/timetable/IsWeekendHasLessonsUseCase.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.wulkanowy.domain.timetable - -import io.github.wulkanowy.data.db.entities.Timetable -import java.time.DayOfWeek -import javax.inject.Inject - -class IsWeekendHasLessonsUseCase @Inject constructor() { - - operator fun invoke( - lessons: List, - ): Boolean = lessons.any { - it.date.dayOfWeek in listOf( - DayOfWeek.SATURDAY, - DayOfWeek.SUNDAY, - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/HiltBroadcastReceiver.kt b/app/src/main/java/io/github/wulkanowy/services/HiltBroadcastReceiver.kt new file mode 100644 index 00000000..1e795d43 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/services/HiltBroadcastReceiver.kt @@ -0,0 +1,9 @@ +package io.github.wulkanowy.services + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +abstract class HiltBroadcastReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) {} +} diff --git a/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt b/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt index 1729f100..891f07da 100644 --- a/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt +++ b/app/src/main/java/io/github/wulkanowy/services/ServicesModule.kt @@ -15,21 +15,14 @@ import dagger.multibindings.IntoSet import io.github.wulkanowy.services.sync.channels.Channel import io.github.wulkanowy.services.sync.channels.DebugChannel import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel -import io.github.wulkanowy.services.sync.channels.NewAttendanceChannel -import io.github.wulkanowy.services.sync.channels.NewConferencesChannel -import io.github.wulkanowy.services.sync.channels.NewExamChannel import io.github.wulkanowy.services.sync.channels.NewGradesChannel -import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel import io.github.wulkanowy.services.sync.channels.NewMessagesChannel import io.github.wulkanowy.services.sync.channels.NewNotesChannel -import io.github.wulkanowy.services.sync.channels.NewSchoolAnnouncementsChannel import io.github.wulkanowy.services.sync.channels.PushChannel -import io.github.wulkanowy.services.sync.channels.TimetableChangeChannel import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork import io.github.wulkanowy.services.sync.works.AttendanceWork import io.github.wulkanowy.services.sync.works.CompletedLessonWork -import io.github.wulkanowy.services.sync.works.ConferenceWork import io.github.wulkanowy.services.sync.works.ExamWork import io.github.wulkanowy.services.sync.works.GradeStatisticsWork import io.github.wulkanowy.services.sync.works.GradeWork @@ -38,7 +31,6 @@ import io.github.wulkanowy.services.sync.works.LuckyNumberWork import io.github.wulkanowy.services.sync.works.MessageWork import io.github.wulkanowy.services.sync.works.NoteWork import io.github.wulkanowy.services.sync.works.RecipientWork -import io.github.wulkanowy.services.sync.works.SchoolAnnouncementWork import io.github.wulkanowy.services.sync.works.TeacherWork import io.github.wulkanowy.services.sync.works.TimetableWork import io.github.wulkanowy.services.sync.works.Work @@ -52,18 +44,15 @@ abstract class ServicesModule { companion object { @Provides - fun provideWorkManager(@ApplicationContext context: Context) = - WorkManager.getInstance(context) + fun provideWorkManager(@ApplicationContext context: Context) = WorkManager.getInstance(context) @Singleton @Provides - fun provideNotificationManager(@ApplicationContext context: Context) = - NotificationManagerCompat.from(context) + fun provideNotificationManager(@ApplicationContext context: Context) = NotificationManagerCompat.from(context) @Singleton @Provides - fun provideAlarmManager(@ApplicationContext context: Context): AlarmManager = - context.getSystemService()!! + fun provideAlarmManager(@ApplicationContext context: Context): AlarmManager = context.getSystemService()!! } @Binds @@ -78,10 +67,6 @@ abstract class ServicesModule { @IntoSet abstract fun provideAttendanceWork(work: AttendanceWork): Work - @Binds - @IntoSet - abstract fun provideConferenceWork(work: ConferenceWork): Work - @Binds @IntoSet abstract fun provideExamWork(work: ExamWork): Work @@ -122,10 +107,6 @@ abstract class ServicesModule { @IntoSet abstract fun provideGradeStatistics(work: GradeStatisticsWork): Work - @Binds - @IntoSet - abstract fun provideSchoolAnnouncementWork(work: SchoolAnnouncementWork): Work - @Binds @IntoSet abstract fun provideDebugChannel(channel: DebugChannel): Channel @@ -134,18 +115,6 @@ abstract class ServicesModule { @IntoSet abstract fun provideLuckyNumberChannel(channel: LuckyNumberChannel): Channel - @Binds - @IntoSet - abstract fun provideNewConferenceChannel(channel: NewConferencesChannel): Channel - - @Binds - @IntoSet - abstract fun provideNewExamChannel(channel: NewExamChannel): Channel - - @Binds - @IntoSet - abstract fun provideNewHomeworkChannel(channel: NewHomeworkChannel): Channel - @Binds @IntoSet abstract fun provideNewGradesChannel(channel: NewGradesChannel): Channel @@ -158,10 +127,6 @@ abstract class ServicesModule { @IntoSet abstract fun provideNewNotesChannel(channel: NewNotesChannel): Channel - @Binds - @IntoSet - abstract fun provideNewSchoolAnnouncementChannel(channel: NewSchoolAnnouncementsChannel): Channel - @Binds @IntoSet abstract fun providePushChannel(channel: PushChannel): Channel @@ -169,12 +134,4 @@ abstract class ServicesModule { @Binds @IntoSet abstract fun provideUpcomingLessonsChannel(channel: UpcomingLessonsChannel): Channel - - @Binds - @IntoSet - abstract fun provideChangeTimetableChannel(channel: TimetableChangeChannel): Channel - - @Binds - @IntoSet - abstract fun provideNewAttendanceChannel(channel: NewAttendanceChannel): Channel } diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt index 01a583e1..592d0919 100644 --- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt +++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationReceiver.kt @@ -1,7 +1,8 @@ package io.github.wulkanowy.services.alarm +import android.annotation.SuppressLint import android.app.PendingIntent -import android.content.BroadcastReceiver +import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.content.Context import android.content.Intent import android.os.Build @@ -10,38 +11,33 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.services.HiltBroadcastReceiver import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.PendingIntentCompat +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.getCompatColor -import kotlinx.coroutines.DelicateCoroutinesApi +import io.github.wulkanowy.utils.toLocalDateTime import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint -class TimetableNotificationReceiver : BroadcastReceiver() { +class TimetableNotificationReceiver : HiltBroadcastReceiver() { @Inject lateinit var studentRepository: StudentRepository - @Inject - lateinit var preferencesRepository: PreferencesRepository - companion object { const val NOTIFICATION_TYPE_CURRENT = 1 const val NOTIFICATION_TYPE_UPCOMING = 2 const val NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION = 3 - // FIXME only shows one notification even if there are multiple students. - // Probably want to fix after #721 is merged. - const val NOTIFICATION_ID = 2137 + const val NOTIFICATION_ID = "id" const val STUDENT_NAME = "student_name" const val STUDENT_ID = "student_id" @@ -54,35 +50,31 @@ class TimetableNotificationReceiver : BroadcastReceiver() { const val LESSON_END = "end_timestamp" } - @OptIn(DelicateCoroutinesApi::class) + @SuppressLint("CheckResult") override fun onReceive(context: Context, intent: Intent) { + super.onReceive(context, intent) Timber.d("Receiving intent... ${intent.toUri(0)}") - resourceFlow { - val showStudentName = !studentRepository.isOneUniqueStudent() + flowWithResource { val student = studentRepository.getCurrentStudent(false) val studentId = intent.getIntExtra(STUDENT_ID, 0) - - if (student.studentId == studentId) { - prepareNotification(context, intent, showStudentName) - } else { - Timber.d("Notification studentId($studentId) differs from current(${student.studentId})") - } - } - .onResourceError { Timber.e(it) } - .launchIn(GlobalScope) + if (student.studentId == studentId) prepareNotification(context, intent) + else Timber.d("Notification studentId($studentId) differs from current(${student.studentId})") + }.onEach { + if (it.status == Status.ERROR) Timber.e(it.error!!) + }.launchIn(GlobalScope) } - private fun prepareNotification(context: Context, intent: Intent, showStudentName: Boolean) { + private fun prepareNotification(context: Context, intent: Intent) { val type = intent.getIntExtra(LESSON_TYPE, 0) - val isPersistent = preferencesRepository.isUpcomingLessonsNotificationsPersistent + val notificationId = intent.getIntExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id) if (type == NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION) { - return NotificationManagerCompat.from(context).cancel(NOTIFICATION_ID) + return NotificationManagerCompat.from(context).cancel(notificationId) } val studentId = intent.getIntExtra(STUDENT_ID, 0) - val studentName = intent.getStringExtra(STUDENT_NAME).takeIf { showStudentName } + val studentName = intent.getStringExtra(STUDENT_NAME) val subject = intent.getStringExtra(LESSON_TITLE) val room = intent.getStringExtra(LESSON_ROOM) @@ -93,68 +85,35 @@ class TimetableNotificationReceiver : BroadcastReceiver() { val nextSubject = intent.getStringExtra(LESSON_NEXT_TITLE) val nextRoom = intent.getStringExtra(LESSON_NEXT_ROOM) - Timber.d("TimetableNotification receive: type: $type, subject: $subject, start: $start, student: $studentId") + Timber.d("TimetableNotification receive: type: $type, subject: $subject, start: ${start.toLocalDateTime()}, student: $studentId") - val notificationTitleResId = - if (type == NOTIFICATION_TYPE_CURRENT) R.string.timetable_now else R.string.timetable_next - val notificationTitle = - context.getString(notificationTitleResId, "($room) $subject".removePrefix("()")) - - val nextLessonText = nextSubject?.let { - context.getString( - R.string.timetable_later, - "($nextRoom) $nextSubject".removePrefix("()") - ) - } - - showNotification( - context = context, - isPersistent = isPersistent, - studentName = studentName, - countDown = if (type == NOTIFICATION_TYPE_CURRENT) end else start, - timeout = end - start, - title = notificationTitle, - next = nextLessonText + showNotification(context, notificationId, studentName, + if (type == NOTIFICATION_TYPE_CURRENT) end else start, end - start, + context.getString(if (type == NOTIFICATION_TYPE_CURRENT) R.string.timetable_now else R.string.timetable_next, "($room) $subject".removePrefix("()")), + nextSubject?.let { context.getString(R.string.timetable_later, "($nextRoom) $nextSubject".removePrefix("()")) } ) } - private fun showNotification( - context: Context, - isPersistent: Boolean, - studentName: String?, - countDown: Long, - timeout: Long, - title: String, - next: String? - ) { - NotificationManagerCompat.from(context) - .notify(NOTIFICATION_ID, NotificationCompat.Builder(context, CHANNEL_ID) - .setContentTitle(title) - .setContentText(next) - .setAutoCancel(false) - .setWhen(countDown) - .setOngoing(isPersistent) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .apply { - if (Build.VERSION.SDK_INT >= N) setUsesChronometer(true) - } - .setTimeoutAfter(timeout) - .setSmallIcon(R.drawable.ic_stat_timetable) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setStyle(NotificationCompat.InboxStyle() - .addLine(next) - .also { inboxStyle -> - studentName?.let { inboxStyle.setSummaryText(it) } - }) - .setContentIntent( - PendingIntent.getActivity( - context, - NOTIFICATION_ID, - SplashActivity.getStartIntent(context, Destination.Timetable()), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - ) - .build() - ) + private fun showNotification(context: Context, notificationId: Int, studentName: String?, countDown: Long, timeout: Long, title: String, next: String?) { + NotificationManagerCompat.from(context).notify(notificationId, NotificationCompat.Builder(context, CHANNEL_ID) + .setContentTitle(title) + .setContentText(next) + .setAutoCancel(false) + .setOngoing(true) + .setWhen(countDown) + .apply { + if (Build.VERSION.SDK_INT >= N) setUsesChronometer(true) + } + .setTimeoutAfter(timeout) + .setSmallIcon(R.drawable.ic_stat_timetable) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setStyle(NotificationCompat.InboxStyle().also { + it.setSummaryText(studentName) + it.addLine(next) + }) + .setContentIntent(PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id, + MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT)) + .build() + ) } } diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt index aae7882f..2593a555 100644 --- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt @@ -3,15 +3,15 @@ package io.github.wulkanowy.services.alarm import android.app.AlarmManager import android.app.AlarmManager.RTC_WAKEUP import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.content.Context import android.content.Intent -import android.os.Build import androidx.core.app.AlarmManagerCompat import androidx.core.app.NotificationManagerCompat import dagger.hilt.android.qualifiers.ApplicationContext import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_END import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_NEXT_ROOM import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_NEXT_TITLE @@ -25,15 +25,13 @@ import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companio import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.NOTIFICATION_TYPE_UPCOMING import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.STUDENT_ID import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.STUDENT_NAME +import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.DispatchersProvider -import io.github.wulkanowy.utils.PendingIntentCompat -import io.github.wulkanowy.utils.nickOrName +import io.github.wulkanowy.utils.toTimestamp import kotlinx.coroutines.withContext import timber.log.Timber -import java.time.Duration.ofMinutes -import java.time.Instant -import java.time.Instant.now -import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalDateTime.now import javax.inject.Inject class TimetableNotificationSchedulerHelper @Inject constructor( @@ -43,65 +41,35 @@ class TimetableNotificationSchedulerHelper @Inject constructor( private val dispatchersProvider: DispatchersProvider, ) { - private fun getRequestCode(time: Instant, studentId: Int): Int = - (time.toEpochMilli() * studentId).toInt() + private fun getRequestCode(time: LocalDateTime, studentId: Int) = (time.toTimestamp() * studentId).toInt() - private fun getUpcomingLessonTime( - index: Int, - day: List, - lesson: Timetable - ): Instant = day.getOrNull(index - 1)?.end ?: lesson.start.minus(ofMinutes(30)) + private fun getUpcomingLessonTime(index: Int, day: List, lesson: Timetable): LocalDateTime { + return day.getOrNull(index - 1)?.end ?: lesson.start.minusMinutes(30) + } - suspend fun cancelScheduled(lessons: List, student: Student) { - val studentId = student.studentId - withContext(dispatchersProvider.io) { + suspend fun cancelScheduled(lessons: List, studentId: Int = 1) { + withContext(dispatchersProvider.backgroundThread) { lessons.sortedBy { it.start }.forEachIndexed { index, lesson -> val upcomingTime = getUpcomingLessonTime(index, lessons, lesson) - cancelScheduledTo( - range = upcomingTime..lesson.start, - requestCode = getRequestCode(upcomingTime, studentId) - ) - cancelScheduledTo( - range = lesson.start..lesson.end, - requestCode = getRequestCode(lesson.start, studentId) - ) + cancelScheduledTo(upcomingTime..lesson.start, getRequestCode(upcomingTime, studentId)) + cancelScheduledTo(lesson.start..lesson.end, getRequestCode(lesson.start, studentId)) + + Timber.d("TimetableNotification canceled: type 1 & 2, subject: ${lesson.subject}, start: ${lesson.start}, student: $studentId") } } } - private fun cancelScheduledTo(range: ClosedRange, requestCode: Int) { + private fun cancelScheduledTo(range: ClosedRange, requestCode: Int) { if (now() in range) cancelNotification() - - alarmManager.cancel( - PendingIntent.getBroadcast( - context, - requestCode, - Intent(), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - ) + alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_UPDATE_CURRENT)) } - fun cancelNotification() = - NotificationManagerCompat.from(context).cancel(NOTIFICATION_ID) + fun cancelNotification() = NotificationManagerCompat.from(context).cancel(MainView.Section.TIMETABLE.id) suspend fun scheduleNotifications(lessons: List, student: Student) { - if (!preferencesRepository.isUpcomingLessonsNotificationsEnable) { - return cancelScheduled(lessons, student) - } + if (!preferencesRepository.isUpcomingLessonsNotificationsEnable) return cancelScheduled(lessons, student.studentId) - if (!canScheduleExactAlarms()) { - Timber.w("Exact alarms are disabled by user") - preferencesRepository.isUpcomingLessonsNotificationsEnable = false - return - } - - if (lessons.firstOrNull()?.date?.isAfter(LocalDate.now().plusDays(2)) == true) { - Timber.d("Timetable notification scheduling skipped - lessons are too far") - return - } - - withContext(dispatchersProvider.io) { + withContext(dispatchersProvider.backgroundThread) { lessons.groupBy { it.date } .map { it.value.sortedBy { lesson -> lesson.start } } .map { it.filter { lesson -> lesson.isStudentPlan } } @@ -109,33 +77,18 @@ class TimetableNotificationSchedulerHelper @Inject constructor( val canceled = day.filter { it.canceled } val active = day.filter { !it.canceled } - cancelScheduled(canceled, student) + cancelScheduled(canceled) active.forEachIndexed { index, lesson -> val intent = createIntent(student, lesson, active.getOrNull(index + 1)) if (lesson.start > now()) { - scheduleBroadcast( - intent = intent, - studentId = student.studentId, - notificationType = NOTIFICATION_TYPE_UPCOMING, - time = getUpcomingLessonTime(index, active, lesson) - ) + scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_UPCOMING, getUpcomingLessonTime(index, active, lesson)) } if (lesson.end > now()) { - scheduleBroadcast( - intent = intent, - studentId = student.studentId, - notificationType = NOTIFICATION_TYPE_CURRENT, - time = lesson.start - ) + scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_CURRENT, lesson.start) if (active.lastIndex == index) { - scheduleBroadcast( - intent = intent, - studentId = student.studentId, - notificationType = NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION, - time = lesson.end - ) + scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION, lesson.end) } } } @@ -146,46 +99,23 @@ class TimetableNotificationSchedulerHelper @Inject constructor( private fun createIntent(student: Student, lesson: Timetable, nextLesson: Timetable?): Intent { return Intent(context, TimetableNotificationReceiver::class.java).apply { putExtra(STUDENT_ID, student.studentId) - putExtra(STUDENT_NAME, student.nickOrName) + putExtra(STUDENT_NAME, student.studentName) putExtra(LESSON_ROOM, lesson.room) - putExtra(LESSON_START, lesson.start.toEpochMilli()) - putExtra(LESSON_END, lesson.end.toEpochMilli()) + putExtra(LESSON_START, lesson.start.toTimestamp()) + putExtra(LESSON_END, lesson.end.toTimestamp()) putExtra(LESSON_TITLE, lesson.subject) putExtra(LESSON_NEXT_TITLE, nextLesson?.subject) putExtra(LESSON_NEXT_ROOM, nextLesson?.room) } } - private fun scheduleBroadcast( - intent: Intent, - studentId: Int, - notificationType: Int, - time: Instant - ) { - try { - AlarmManagerCompat.setExactAndAllowWhileIdle( - alarmManager, RTC_WAKEUP, time.toEpochMilli(), - PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also { - it.putExtra(LESSON_TYPE, notificationType) - }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE) - ) - Timber.d( - "TimetableNotification scheduled: type: $notificationType, subject: ${ - intent.getStringExtra(LESSON_TITLE) - }, start: $time, student: $studentId" - ) - } catch (e: Throwable) { - Timber.e(e) - } - } - - fun canScheduleExactAlarms(): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - try { - alarmManager.canScheduleExactAlarms() - } catch (e: Throwable) { - false - } - } else true + private fun scheduleBroadcast(intent: Intent, studentId: Int, notificationType: Int, time: LocalDateTime) { + AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, RTC_WAKEUP, time.toTimestamp(), + PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also { + it.putExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id) + it.putExtra(LESSON_TYPE, notificationType) + }, FLAG_UPDATE_CURRENT) + ) + Timber.d("TimetableNotification scheduled: type: $notificationType, subject: ${intent.getStringExtra(LESSON_TITLE)}, start: $time, student: $studentId") } } diff --git a/app/src/main/java/io/github/wulkanowy/services/piggyback/VulcanNotificationListenerService.kt b/app/src/main/java/io/github/wulkanowy/services/piggyback/VulcanNotificationListenerService.kt deleted file mode 100644 index 3c173495..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/piggyback/VulcanNotificationListenerService.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.github.wulkanowy.services.piggyback - -import android.service.notification.NotificationListenerService -import android.service.notification.StatusBarNotification -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.services.sync.SyncManager -import javax.inject.Inject - -@AndroidEntryPoint -class VulcanNotificationListenerService : NotificationListenerService() { - - @Inject - lateinit var syncManager: SyncManager - - @Inject - lateinit var preferenceRepository: PreferencesRepository - - override fun onNotificationPosted(statusBarNotification: StatusBarNotification?) { - if (statusBarNotification?.packageName == "pl.edu.vulcan.hebe" && preferenceRepository.isNotificationPiggybackEnabled) { - syncManager.startOneTimeSyncWorker() - if (preferenceRepository.isNotificationPiggybackRemoveOriginalEnabled) { - cancelNotification(statusBarNotification.key) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/services/shortcuts/ShortcutsHelper.kt b/app/src/main/java/io/github/wulkanowy/services/shortcuts/ShortcutsHelper.kt deleted file mode 100644 index 5e59aa54..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/shortcuts/ShortcutsHelper.kt +++ /dev/null @@ -1,55 +0,0 @@ -package io.github.wulkanowy.services.shortcuts - -import android.content.Context -import android.content.Intent -import androidx.core.content.pm.ShortcutInfoCompat -import androidx.core.content.pm.ShortcutManagerCompat -import androidx.core.graphics.drawable.IconCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class ShortcutsHelper @Inject constructor(@ApplicationContext private val context: Context) { - - fun initializeShortcuts() { - val shortcutsInfo = listOf( - ShortcutInfoCompat.Builder(context, "grade_shortcut") - .setShortLabel(context.getString(R.string.grade_title)) - .setLongLabel(context.getString(R.string.grade_title)) - .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_grade)) - .setIntent(SplashActivity.getStartIntent(context, Destination.Grade) - .apply { action = Intent.ACTION_VIEW }) - .build(), - - ShortcutInfoCompat.Builder(context, "attendance_shortcut") - .setShortLabel(context.getString(R.string.attendance_title)) - .setLongLabel(context.getString(R.string.attendance_title)) - .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_attendance)) - .setIntent(SplashActivity.getStartIntent(context, Destination.Attendance) - .apply { action = Intent.ACTION_VIEW }) - .build(), - - ShortcutInfoCompat.Builder(context, "exam_shortcut") - .setShortLabel(context.getString(R.string.exam_title)) - .setLongLabel(context.getString(R.string.exam_title)) - .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_exam)) - .setIntent(SplashActivity.getStartIntent(context, Destination.Exam) - .apply { action = Intent.ACTION_VIEW }) - .build(), - - ShortcutInfoCompat.Builder(context, "timetable_shortcut") - .setShortLabel(context.getString(R.string.timetable_title)) - .setLongLabel(context.getString(R.string.timetable_title)) - .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_timetable)) - .setIntent(SplashActivity.getStartIntent(context, Destination.Timetable()) - .apply { action = Intent.ACTION_VIEW }) - .build() - ) - - shortcutsInfo.forEach { ShortcutManagerCompat.pushDynamicShortcut(context, it) } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/SyncManager.kt b/app/src/main/java/io/github/wulkanowy/services/sync/SyncManager.kt index e0a136f9..47a94927 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/SyncManager.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/SyncManager.kt @@ -4,15 +4,21 @@ import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION_CODES.O import androidx.core.app.NotificationManagerCompat import androidx.lifecycle.asFlow -import androidx.work.* import androidx.work.BackoffPolicy.EXPONENTIAL +import androidx.work.Constraints +import androidx.work.Data import androidx.work.ExistingPeriodicWorkPolicy.KEEP -import androidx.work.ExistingPeriodicWorkPolicy.UPDATE +import androidx.work.ExistingPeriodicWorkPolicy.REPLACE +import androidx.work.ExistingWorkPolicy import androidx.work.NetworkType.CONNECTED import androidx.work.NetworkType.UNMETERED +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkInfo +import androidx.work.WorkManager import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.services.sync.channels.Channel import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.isHolidays @@ -51,39 +57,27 @@ class SyncManager @Inject constructor( fun startPeriodicSyncWorker(restart: Boolean = false) { if (preferencesRepository.isServiceEnabled && !now().isHolidays) { - val serviceInterval = preferencesRepository.servicesInterval - - workManager.enqueueUniquePeriodicWork( - SyncWorker::class.java.simpleName, if (restart) UPDATE else KEEP, - PeriodicWorkRequestBuilder(serviceInterval, MINUTES) + workManager.enqueueUniquePeriodicWork(SyncWorker::class.java.simpleName, if (restart) REPLACE else KEEP, + PeriodicWorkRequestBuilder(preferencesRepository.servicesInterval, MINUTES) .setInitialDelay(10, MINUTES) .setBackoffCriteria(EXPONENTIAL, 30, MINUTES) - .setConstraints( - Constraints.Builder() - .setRequiredNetworkType(if (preferencesRepository.isServicesOnlyWifi) UNMETERED else CONNECTED) - .build() - ) - .build() - ) + .setConstraints(Constraints.Builder() + .setRequiredNetworkType(if (preferencesRepository.isServicesOnlyWifi) UNMETERED else CONNECTED) + .build()) + .build()) } } - // if quiet, no notifications will be sent - fun startOneTimeSyncWorker(quiet: Boolean = false): Flow { + fun startOneTimeSyncWorker(): Flow { val work = OneTimeWorkRequestBuilder() .setInputData( Data.Builder() - .putBoolean("quiet", quiet) .putBoolean("one_time", true) .build() ) .build() - workManager.enqueueUniqueWork( - "${SyncWorker::class.java.simpleName}_one_time", - ExistingWorkPolicy.REPLACE, - work - ) + workManager.enqueueUniqueWork("${SyncWorker::class.java.simpleName}_one_time", ExistingWorkPolicy.REPLACE, work) return workManager.getWorkInfoByIdLiveData(work.id).asFlow() } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt b/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt index bcbc23ef..13326ca0 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/SyncWorker.kt @@ -5,110 +5,82 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat.BigTextStyle import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT import androidx.core.app.NotificationManagerCompat -import androidx.hilt.work.HiltWorker +import androidx.hilt.Assisted +import androidx.hilt.work.WorkerInject import androidx.work.CoroutineWorker import androidx.work.Data import androidx.work.WorkerParameters -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException -import io.github.wulkanowy.sdk.scrapper.exception.FeatureUnavailableException import io.github.wulkanowy.services.sync.channels.DebugChannel import io.github.wulkanowy.services.sync.works.Work -import io.github.wulkanowy.utils.DispatchersProvider import io.github.wulkanowy.utils.getCompatColor -import kotlinx.coroutines.withContext +import kotlinx.coroutines.coroutineScope import timber.log.Timber -import java.time.Instant import kotlin.random.Random -@HiltWorker -class SyncWorker @AssistedInject constructor( +class SyncWorker @WorkerInject constructor( @Assisted appContext: Context, @Assisted workerParameters: WorkerParameters, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, private val works: Set<@JvmSuppressWildcards Work>, private val preferencesRepository: PreferencesRepository, - private val notificationManager: NotificationManagerCompat, - private val dispatchersProvider: DispatchersProvider + private val notificationManager: NotificationManagerCompat ) : CoroutineWorker(appContext, workerParameters) { - override suspend fun doWork(): Result = withContext(dispatchersProvider.io) { + override suspend fun doWork() = coroutineScope { Timber.i("SyncWorker is starting") - if (!studentRepository.isCurrentStudentSet()) return@withContext Result.failure() + if (!studentRepository.isCurrentStudentSet()) return@coroutineScope Result.failure() - val (student, semester) = try { - val student = studentRepository.getCurrentStudent() - val semester = semesterRepository.getCurrentSemester(student, true) - student to semester - } catch (e: Throwable) { - Timber.e(e) - return@withContext getResultFromErrors(listOf(e)) - } + val student = studentRepository.getCurrentStudent() + val semester = semesterRepository.getCurrentSemester(student, true) val exceptions = works.mapNotNull { work -> try { Timber.i("${work::class.java.simpleName} is starting") - work.doWork(student, semester, isNotificationsEnabled()) + work.doWork(student, semester) Timber.i("${work::class.java.simpleName} result: Success") null } catch (e: Throwable) { Timber.w("${work::class.java.simpleName} result: An exception ${e.message} occurred") - if (e is FeatureDisabledException || e is FeatureNotAvailableException || e is FeatureUnavailableException) { - null - } else { + if (e is FeatureDisabledException || e is FeatureNotAvailableException) null + else { Timber.e(e) e } } } - val result = getResultFromErrors(exceptions) + val result = when { + exceptions.isNotEmpty() && inputData.getBoolean("one_time", false) -> { + Result.failure(Data.Builder() + .putString("error", exceptions.map { it.stackTraceToString() }.toString()) + .build() + ) + } + exceptions.isNotEmpty() -> Result.retry() + else -> Result.success() + } if (preferencesRepository.isDebugNotificationEnable) notify(result) Timber.i("SyncWorker result: $result") - return@withContext result - } - - private fun isNotificationsEnabled(): Boolean { - val quiet = inputData.getBoolean("quiet", false) - return preferencesRepository.isNotificationsEnable && !quiet - } - - private fun getResultFromErrors(errors: List): Result = when { - errors.isNotEmpty() && inputData.getBoolean("one_time", false) -> { - Result.failure( - Data.Builder() - .putString("error_message", errors.joinToString { it.message.toString() }) - .putString("error_stack", errors.map { it.stackTraceToString() }.toString()) - .build() - ) - } - errors.isNotEmpty() -> Result.retry() - else -> { - preferencesRepository.lasSyncDate = Instant.now() - Result.success() - } + result } private fun notify(result: Result) { - notificationManager.notify( - Random.nextInt(Int.MAX_VALUE), - NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID) - .setContentTitle("Debug notification") - .setSmallIcon(R.drawable.ic_stat_all) - .setAutoCancel(true) - .setColor(applicationContext.getCompatColor(R.color.colorPrimary)) - .setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result")) - .setPriority(PRIORITY_DEFAULT) - .build() - ) + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(applicationContext, DebugChannel.CHANNEL_ID) + .setContentTitle("Debug notification") + .setSmallIcon(R.drawable.ic_stat_push) + .setAutoCancel(true) + .setColor(applicationContext.getCompatColor(R.color.colorPrimary)) + .setStyle(BigTextStyle().bigText("${SyncWorker::class.java.simpleName} result: $result")) + .setPriority(PRIORITY_DEFAULT) + .build()) } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewAttendanceChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewAttendanceChannel.kt deleted file mode 100644 index 3110099e..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewAttendanceChannel.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class NewAttendanceChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "new_attendance_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel( - CHANNEL_ID, - context.getString(R.string.channel_new_attendance), - NotificationManager.IMPORTANCE_HIGH - ) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewConferencesChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewConferencesChannel.kt deleted file mode 100644 index 397e67c6..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewConferencesChannel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class NewConferencesChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "new_conferences_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_conference), NotificationManager.IMPORTANCE_HIGH) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewExamChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewExamChannel.kt deleted file mode 100644 index 1bf5f855..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewExamChannel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class NewExamChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "new_exam_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_exam), NotificationManager.IMPORTANCE_HIGH) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewHomeworkChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewHomeworkChannel.kt deleted file mode 100644 index 4b7dd0e9..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewHomeworkChannel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class NewHomeworkChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "new_homework_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_homework), NotificationManager.IMPORTANCE_HIGH) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewSchoolAnnouncementsChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewSchoolAnnouncementsChannel.kt deleted file mode 100644 index 2b21ba40..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/NewSchoolAnnouncementsChannel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class NewSchoolAnnouncementsChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "new_school_announcements_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_new_school_announcement), NotificationManager.IMPORTANCE_HIGH) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/channels/TimetableChangeChannel.kt b/app/src/main/java/io/github/wulkanowy/services/sync/channels/TimetableChangeChannel.kt deleted file mode 100644 index 10dd3e00..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/channels/TimetableChangeChannel.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.services.sync.channels - -import android.annotation.TargetApi -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.content.Context -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import javax.inject.Inject - -@TargetApi(26) -class TimetableChangeChannel @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context -) : Channel { - - companion object { - const val CHANNEL_ID = "change_timetable_channel" - } - - override fun create() { - notificationManager.createNotificationChannel( - NotificationChannel( - CHANNEL_ID, - context.getString(R.string.channel_change_timetable), - NotificationManager.IMPORTANCE_HIGH - ) - .apply { - enableLights(true) - enableVibration(true) - lockscreenVisibility = Notification.VISIBILITY_PUBLIC - }) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt deleted file mode 100644 index dadb68c5..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/AppNotificationManager.kt +++ /dev/null @@ -1,179 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.annotation.SuppressLint -import android.app.PendingIntent -import android.content.Context -import android.os.Build -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Notification -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.data.repositories.NotificationRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.PendingIntentCompat -import io.github.wulkanowy.utils.getCompatBitmap -import io.github.wulkanowy.utils.getCompatColor -import io.github.wulkanowy.utils.nickOrName -import java.time.Instant -import javax.inject.Inject -import kotlin.random.Random - -class AppNotificationManager @Inject constructor( - private val notificationManager: NotificationManagerCompat, - @ApplicationContext private val context: Context, - private val studentRepository: StudentRepository, - private val notificationRepository: NotificationRepository -) { - - @SuppressLint("InlinedApi") - suspend fun sendSingleNotification( - notificationData: NotificationData, - notificationType: NotificationType, - student: Student - ) { - val notification = NotificationCompat.Builder(context, notificationType.channel) - .setLargeIcon(context.getCompatBitmap(notificationType.icon, R.color.colorPrimary)) - .setSmallIcon(R.drawable.ic_stat_all) - .setAutoCancel(true) - .setDefaults(NotificationCompat.DEFAULT_ALL) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) - .setContentIntent( - PendingIntent.getActivity( - context, - Random.nextInt(), - SplashActivity.getStartIntent(context, notificationData.destination), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - ) - .setContentTitle(notificationData.title) - .setContentText(notificationData.content) - .setStyle( - NotificationCompat.BigTextStyle() - .bigText(notificationData.content) - .also { builder -> - if (!studentRepository.isOneUniqueStudent()) { - builder.setSummaryText(student.nickOrName) - } - } - ) - .build() - - notificationManager.notify(Random.nextInt(), notification) - saveNotification(notificationData, notificationType, student) - } - - @SuppressLint("InlinedApi") - suspend fun sendMultipleNotifications( - groupNotificationData: GroupNotificationData, - student: Student - ) { - val notificationType = groupNotificationData.type - val groupType = notificationType.channel - val group = "${groupType}_${student.id}" - - sendSummaryNotification(groupNotificationData, group, student) - - groupNotificationData.notificationDataList.forEach { notificationData -> - val notification = NotificationCompat.Builder(context, notificationType.channel) - .setLargeIcon(context.getCompatBitmap(notificationType.icon, R.color.colorPrimary)) - .setSmallIcon(R.drawable.ic_stat_all) - .setAutoCancel(true) - .setDefaults(NotificationCompat.DEFAULT_ALL) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY) - .setContentIntent( - PendingIntent.getActivity( - context, - Random.nextInt(), - SplashActivity.getStartIntent(context, notificationData.destination), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - ) - .setContentTitle(notificationData.title) - .setContentText(notificationData.content) - .setStyle( - NotificationCompat.BigTextStyle() - .bigText(notificationData.content) - .also { builder -> - if (!studentRepository.isOneUniqueStudent()) { - builder.setSummaryText(student.nickOrName) - } - } - ) - .setGroup(group) - .build() - - notificationManager.notify(Random.nextInt(), notification) - saveNotification(notificationData, groupNotificationData.type, student) - } - } - - private suspend fun sendSummaryNotification( - groupNotificationData: GroupNotificationData, - group: String, - student: Student - ) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return - - val summaryNotification = - NotificationCompat.Builder(context, groupNotificationData.type.channel) - .setContentTitle(groupNotificationData.title) - .setContentText(groupNotificationData.content) - .setSmallIcon(groupNotificationData.type.icon) - .setAutoCancel(true) - .setDefaults(NotificationCompat.DEFAULT_ALL) - .setPriority(NotificationCompat.PRIORITY_HIGH) - .setColor(context.getCompatColor(R.color.colorPrimary)) - .setStyle( - NotificationCompat.InboxStyle() - .also { builder -> - if (!studentRepository.isOneUniqueStudent()) { - builder.setSummaryText(student.nickOrName) - } - groupNotificationData.notificationDataList.forEach { - builder.addLine(it.content) - } - } - ) - .setContentIntent( - PendingIntent.getActivity( - context, - Random.nextInt(), - SplashActivity.getStartIntent(context, groupNotificationData.destination), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - ) - .setLocalOnly(true) - .setGroup(group) - .setGroupSummary(true) - .build() - - val groupId = student.id * 100 + groupNotificationData.type.ordinal - notificationManager.notify(groupId.toInt(), summaryNotification) - } - - private suspend fun saveNotification( - notificationData: NotificationData, - notificationType: NotificationType, - student: Student - ) { - val notificationEntity = Notification( - studentId = student.id, - title = notificationData.title, - content = notificationData.content, - destination = notificationData.destination, - type = notificationType, - date = Instant.now(), - ) - - notificationRepository.saveNotification(notificationEntity) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt deleted file mode 100644 index 43ae1fea..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/ChangeTimetableNotification.kt +++ /dev/null @@ -1,120 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.utils.getPlural -import io.github.wulkanowy.utils.toFormattedString -import java.time.Instant -import java.time.LocalDate -import javax.inject.Inject - -class ChangeTimetableNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context, -) { - - suspend fun notify(items: List, student: Student) { - val currentTime = Instant.now() - val changedLessons = items.filter { (it.canceled || it.changes) && it.start > currentTime } - val lessonsByDate = changedLessons.groupBy { it.date } - val notificationDataList = lessonsByDate - .flatMap { (date, lessons) -> - getNotificationContents(date, lessons).map { - NotificationData( - title = context.getPlural( - R.plurals.timetable_notify_new_items_title, - 1 - ), - content = it, - destination = Destination.Timetable(date) - ) - } - } - .ifEmpty { return } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural( - R.plurals.timetable_notify_new_items_title, - changedLessons.size - ), - content = context.getPlural( - R.plurals.timetable_notify_new_items_group, - changedLessons.size, - changedLessons.size - ), - destination = Destination.Timetable(lessonsByDate.toSortedMap().firstKey()), - type = NotificationType.CHANGE_TIMETABLE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } - - private fun getNotificationContents(date: LocalDate, lessons: List): List { - val formattedDate = date.toFormattedString("EEE dd.MM") - - return if (lessons.size > 2) { - listOf( - context.getPlural( - R.plurals.timetable_notify_new_items, - lessons.size, - formattedDate, - lessons.size, - ) - ) - } else { - lessons.map { - buildString { - append( - context.getString( - R.string.timetable_notify_lesson, - formattedDate, - it.number, - it.subject - ) - ) - if (it.roomOld.isNotBlank()) { - appendLine() - append( - context.getString( - R.string.timetable_notify_change_room, - it.roomOld, - it.room - ) - ) - } - if (it.teacherOld.isNotBlank() && it.teacher != it.teacherOld) { - appendLine() - append( - context.getString( - R.string.timetable_notify_change_teacher, - it.teacherOld, - it.teacher - ) - ) - } - if (it.subjectOld.isNotBlank()) { - appendLine() - append( - context.getString( - R.string.timetable_notify_change_subject, - it.subjectOld, - it.subject - ) - ) - } - if (it.info.isNotBlank()) { - appendLine() - append(it.info) - } - } - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt deleted file mode 100644 index 99473a8e..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt +++ /dev/null @@ -1,55 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.utils.descriptionRes -import io.github.wulkanowy.utils.getPlural -import io.github.wulkanowy.utils.toFormattedString -import javax.inject.Inject - -class NewAttendanceNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val lines = items.filterNot { it.presence || it.name == "UNKNOWN" } - .map { - val lesson = it.subject.ifBlank { "Lekcja ${it.number}" } - val description = context.getString(it.descriptionRes) - "${it.date.toFormattedString("dd.MM")} - $lesson: $description" - } - .ifEmpty { return } - - val notificationDataList = lines.map { - NotificationData( - title = context.getPlural(R.plurals.attendance_notify_new_items_title, 1), - content = it, - destination = Destination.Attendance - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural( - R.plurals.attendance_notify_new_items_title, - notificationDataList.size - ), - content = context.getPlural( - R.plurals.attendance_notify_new_items, - notificationDataList.size, - notificationDataList.size - ), - destination = Destination.Attendance, - type = NotificationType.NEW_ATTENDANCE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt deleted file mode 100644 index 92977ebb..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewConferenceNotification.kt +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.getPlural -import io.github.wulkanowy.utils.toFormattedString -import java.time.Instant -import javax.inject.Inject - -class NewConferenceNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val today = Instant.now() - val lines = items.filter { !it.date.isBefore(today) } - .map { - "${it.date.toFormattedString("dd.MM")} - ${it.title}: ${it.subject}" - } - .ifEmpty { return } - - val notificationDataList = lines.map { - NotificationData( - title = context.getPlural(R.plurals.conference_notify_new_item_title, 1), - content = it, - destination = Destination.Conference - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.conference_notify_new_item_title, lines.size), - content = context.getPlural( - R.plurals.conference_notify_new_items, - lines.size, - lines.size - ), - destination = Destination.Conference, - type = NotificationType.NEW_CONFERENCE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt deleted file mode 100644 index 125bbf92..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewExamNotification.kt +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Exam -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.getPlural -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate -import javax.inject.Inject - -class NewExamNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val today = LocalDate.now() - val lines = items.filter { !it.date.isBefore(today) } - .map { - "${it.date.toFormattedString("dd.MM")} - ${it.subject}: ${it.description}" - } - .ifEmpty { return } - - val notificationDataList = lines.map { - NotificationData( - title = context.getPlural(R.plurals.exam_notify_new_item_title, 1), - content = it, - destination = Destination.Exam, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.exam_notify_new_item_title, lines.size), - content = context.getPlural( - R.plurals.exam_notify_new_item_content, - lines.size, - lines.size - ), - destination = Destination.Exam, - type = NotificationType.NEW_EXAM - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt deleted file mode 100644 index 232ba672..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewGradeNotification.kt +++ /dev/null @@ -1,117 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive -import io.github.wulkanowy.data.db.entities.GradeSummary -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.utils.getPlural -import javax.inject.Inject - -class NewGradeNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notifyDetails(items: List, student: Student) { - val notificationDataList = items - .filter { !it.isNotified } - .map { - NotificationData( - title = context.getPlural(R.plurals.grade_new_items, 1), - content = buildString { - append("${it.subject}: ${it.entry}") - if (it.comment.isNotBlank()) append(" (${it.comment})") - }, - destination = Destination.Grade, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.grade_new_items, items.size), - content = context.getPlural(R.plurals.grade_notify_new_items, items.size, items.size), - destination = Destination.Grade, - type = NotificationType.NEW_GRADE_DETAILS - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } - - suspend fun notifyPredicted(items: List, student: Student) { - val notificationDataList = items.map { - NotificationData( - title = context.getPlural(R.plurals.grade_new_items_predicted, 1), - content = "${it.subject}: ${it.predictedGrade}", - destination = Destination.Grade, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.grade_new_items_predicted, items.size), - content = context.getPlural( - R.plurals.grade_notify_new_items_predicted, - items.size, - items.size - ), - destination = Destination.Grade, - type = NotificationType.NEW_GRADE_PREDICTED - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } - - suspend fun notifyFinal(items: List, student: Student) { - val notificationDataList = items.map { - NotificationData( - title = context.getPlural(R.plurals.grade_new_items_final, 1), - content = "${it.subject}: ${it.finalGrade}", - destination = Destination.Grade, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.grade_new_items_final, items.size), - content = context.getPlural( - R.plurals.grade_notify_new_items_final, - items.size, - items.size - ), - destination = Destination.Grade, - type = NotificationType.NEW_GRADE_FINAL - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } - - suspend fun notifyDescriptive(items: List, student: Student) { - val notificationDataList = items.map { - NotificationData( - title = context.getPlural(R.plurals.grade_new_items_descriptive, 1), - content = "${it.subject}: ${it.description}", - destination = Destination.Grade, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.grade_new_items_descriptive, items.size), - content = context.getPlural( - R.plurals.grade_notify_new_items_descriptive, - items.size, - items.size - ), - destination = Destination.Grade, - type = NotificationType.NEW_GRADE_DESCRIPTIVE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt deleted file mode 100644 index 856c5158..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewHomeworkNotification.kt +++ /dev/null @@ -1,52 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.getPlural -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate -import javax.inject.Inject - -class NewHomeworkNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val today = LocalDate.now() - val lines = items.filter { !it.date.isBefore(today) } - .map { - "${it.date.toFormattedString("dd.MM")} - ${it.subject}: ${it.content}" - } - .ifEmpty { return } - - val notificationDataList = lines.map { - NotificationData( - title = context.getPlural(R.plurals.homework_notify_new_item_title, 1), - content = it, - destination = Destination.Homework, - ) - } - - val groupNotificationData = GroupNotificationData( - title = context.getPlural(R.plurals.homework_notify_new_item_title, lines.size), - content = context.getPlural( - R.plurals.homework_notify_new_item_content, - lines.size, - lines.size - ), - destination = Destination.Homework, - type = NotificationType.NEW_HOMEWORK, - notificationDataList = notificationDataList - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt deleted file mode 100644 index bbe9b8a1..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewLuckyNumberNotification.kt +++ /dev/null @@ -1,34 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import javax.inject.Inject - -class NewLuckyNumberNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(item: LuckyNumber, student: Student) { - val notificationData = NotificationData( - title = context.getString(R.string.lucky_number_notify_new_item_title), - content = context.getString( - R.string.lucky_number_notify_new_item, - item.luckyNumber.toString() - ), - destination = Destination.LuckyNumber - ) - - appNotificationManager.sendSingleNotification( - notificationData = notificationData, - notificationType = NotificationType.NEW_LUCKY_NUMBER, - student = student - ) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt deleted file mode 100644 index 45523d51..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.utils.getPlural -import javax.inject.Inject - -class NewMessageNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val notificationDataList = items.map { - NotificationData( - title = context.getPlural(R.plurals.message_new_items, 1), - content = "${it.correspondents}: ${it.subject}", - destination = Destination.Message, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - title = context.getPlural(R.plurals.message_new_items, items.size), - content = context.getPlural(R.plurals.message_notify_new_items, items.size, items.size), - destination = Destination.Message, - type = NotificationType.NEW_MESSAGE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt deleted file mode 100644 index dae7d433..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewNoteNotification.kt +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.getPlural -import javax.inject.Inject - -class NewNoteNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val notificationDataList = items.map { - val titleRes = when (NoteCategory.getByValue(it.categoryType)) { - NoteCategory.POSITIVE -> R.plurals.praise_new_items - NoteCategory.NEUTRAL -> R.plurals.neutral_note_new_items - else -> R.plurals.note_new_items - } - - NotificationData( - title = context.getPlural(titleRes, 1), - content = "${it.teacher}: ${it.category}", - destination = Destination.Note, - ) - } - - val groupNotificationData = GroupNotificationData( - notificationDataList = notificationDataList, - destination = Destination.Note, - title = context.getPlural(R.plurals.note_new_items, items.size), - content = context.getPlural(R.plurals.note_notify_new_items, items.size, items.size), - type = NotificationType.NEW_NOTE - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt deleted file mode 100644 index cc7e4656..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewSchoolAnnouncementNotification.kt +++ /dev/null @@ -1,49 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import android.content.Context -import androidx.core.text.parseAsHtml -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.pojos.GroupNotificationData -import io.github.wulkanowy.data.pojos.NotificationData -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.getPlural -import javax.inject.Inject - -class NewSchoolAnnouncementNotification @Inject constructor( - private val appNotificationManager: AppNotificationManager, - @ApplicationContext private val context: Context -) { - - suspend fun notify(items: List, student: Student) { - val notificationDataList = items.map { - NotificationData( - destination = Destination.SchoolAnnouncement, - title = context.getPlural( - R.plurals.school_announcement_notify_new_item_title, - 1 - ), - content = "${it.subject}: ${it.content.parseAsHtml()}" - ) - } - val groupNotificationData = GroupNotificationData( - type = NotificationType.NEW_ANNOUNCEMENT, - destination = Destination.SchoolAnnouncement, - title = context.getPlural( - R.plurals.school_announcement_notify_new_item_title, - items.size - ), - content = context.getPlural( - R.plurals.school_announcement_notify_new_items, - items.size, - items.size - ), - notificationDataList = notificationDataList - ) - - appNotificationManager.sendMultipleNotifications(groupNotificationData, student) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NotificationType.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NotificationType.kt deleted file mode 100644 index 4e7f2735..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NotificationType.kt +++ /dev/null @@ -1,76 +0,0 @@ -package io.github.wulkanowy.services.sync.notifications - -import io.github.wulkanowy.R -import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel -import io.github.wulkanowy.services.sync.channels.NewAttendanceChannel -import io.github.wulkanowy.services.sync.channels.NewConferencesChannel -import io.github.wulkanowy.services.sync.channels.NewExamChannel -import io.github.wulkanowy.services.sync.channels.NewGradesChannel -import io.github.wulkanowy.services.sync.channels.NewHomeworkChannel -import io.github.wulkanowy.services.sync.channels.NewMessagesChannel -import io.github.wulkanowy.services.sync.channels.NewNotesChannel -import io.github.wulkanowy.services.sync.channels.NewSchoolAnnouncementsChannel -import io.github.wulkanowy.services.sync.channels.PushChannel -import io.github.wulkanowy.services.sync.channels.TimetableChangeChannel - -enum class NotificationType( - val channel: String, - val icon: Int -) { - NEW_CONFERENCE( - channel = NewConferencesChannel.CHANNEL_ID, - icon = R.drawable.ic_more_conferences, - ), - NEW_EXAM( - channel = NewExamChannel.CHANNEL_ID, - icon = R.drawable.ic_main_exam - ), - NEW_GRADE_DETAILS( - channel = NewGradesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_grade, - ), - NEW_GRADE_PREDICTED( - channel = NewGradesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_grade, - ), - NEW_GRADE_FINAL( - channel = NewGradesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_grade, - ), - NEW_GRADE_DESCRIPTIVE( - channel = NewGradesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_grade, - ), - NEW_HOMEWORK( - channel = NewHomeworkChannel.CHANNEL_ID, - icon = R.drawable.ic_more_homework, - ), - NEW_LUCKY_NUMBER( - channel = LuckyNumberChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_luckynumber, - ), - NEW_MESSAGE( - channel = NewMessagesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_message, - ), - NEW_NOTE( - channel = NewNotesChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_note - ), - NEW_ANNOUNCEMENT( - channel = NewSchoolAnnouncementsChannel.CHANNEL_ID, - icon = R.drawable.ic_all_about - ), - CHANGE_TIMETABLE( - channel = TimetableChangeChannel.CHANNEL_ID, - icon = R.drawable.ic_main_timetable - ), - NEW_ATTENDANCE( - channel = NewAttendanceChannel.CHANNEL_ID, - icon = R.drawable.ic_main_attendance - ), - PUSH( - channel = PushChannel.CHANNEL_ID, - icon = R.drawable.ic_stat_all - ) -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceSummaryWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceSummaryWork.kt index 55ce7e90..9e4ab902 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceSummaryWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceSummaryWork.kt @@ -2,20 +2,15 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository -import io.github.wulkanowy.data.waitForResult +import io.github.wulkanowy.data.repositories.attendancesummary.AttendanceSummaryRepository +import io.github.wulkanowy.utils.waitForResult import javax.inject.Inject class AttendanceSummaryWork @Inject constructor( private val attendanceSummaryRepository: AttendanceSummaryRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - attendanceSummaryRepository.getAttendanceSummary( - student = student, - semester = semester, - subjectId = -1, - forceRefresh = true, - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + attendanceSummaryRepository.getAttendanceSummary(student, semester, -1, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceWork.kt index 4fc09749..ecf0be01 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/AttendanceWork.kt @@ -2,46 +2,16 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.AttendanceRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewAttendanceNotification -import io.github.wulkanowy.utils.previousOrSameSchoolDay -import kotlinx.coroutines.flow.first +import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.waitForResult import java.time.LocalDate.now import javax.inject.Inject -class AttendanceWork @Inject constructor( - private val attendanceRepository: AttendanceRepository, - private val newAttendanceNotification: NewAttendanceNotification, -) : Work { +class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val startDate = now().previousOrSameSchoolDay - val endDate = startDate.plusDays(7) - - attendanceRepository.getAttendance( - student = student, - semester = semester, - start = startDate, - end = endDate, - forceRefresh = true, - notify = notify, - ) - .waitForResult() - - attendanceRepository.getAttendanceFromDatabase( - semester = semester, - start = startDate, - end = endDate, - ) - .first() - .filterNot { it.isNotified } - .let { - if (it.isNotEmpty()) newAttendanceNotification.notify(it, student) - - attendanceRepository.updateTimetable(it.onEach { attendance -> - attendance.isNotified = true - }) - } + override suspend fun doWork(student: Student, semester: Semester) { + attendanceRepository.getAttendance(student, semester, now().monday, now().sunday, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/CompletedLessonWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/CompletedLessonWork.kt index f898aa04..212ea632 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/CompletedLessonWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/CompletedLessonWork.kt @@ -2,10 +2,10 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.CompletedLessonsRepository -import io.github.wulkanowy.data.waitForResult +import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.waitForResult import java.time.LocalDate.now import javax.inject.Inject @@ -13,13 +13,7 @@ class CompletedLessonWork @Inject constructor( private val completedLessonsRepository: CompletedLessonsRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - completedLessonsRepository.getCompletedLessons( - student = student, - semester = semester, - start = now().monday, - end = now().sunday, - forceRefresh = true, - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().sunday, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt deleted file mode 100644 index c85c0043..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/ConferenceWork.kt +++ /dev/null @@ -1,33 +0,0 @@ -package io.github.wulkanowy.services.sync.works - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.ConferenceRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewConferenceNotification -import kotlinx.coroutines.flow.first -import javax.inject.Inject - -class ConferenceWork @Inject constructor( - private val conferenceRepository: ConferenceRepository, - private val newConferenceNotification: NewConferenceNotification, -) : Work { - - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - conferenceRepository.getConferences( - student = student, - semester = semester, - forceRefresh = true, - notify = notify - ).waitForResult() - - conferenceRepository.getConferenceFromDatabase(semester).first() - .filter { !it.isNotified }.let { - if (it.isNotEmpty()) newConferenceNotification.notify(it, student) - - conferenceRepository.updateConference(it.onEach { conference -> - conference.isNotified = true - }) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt index 4b0b1bdb..899d45cb 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/ExamWork.kt @@ -2,43 +2,14 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.ExamRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewExamNotification -import io.github.wulkanowy.utils.endExamsDay -import io.github.wulkanowy.utils.startExamsDay -import kotlinx.coroutines.flow.first +import io.github.wulkanowy.data.repositories.exam.ExamRepository +import io.github.wulkanowy.utils.waitForResult import java.time.LocalDate.now import javax.inject.Inject -class ExamWork @Inject constructor( - private val examRepository: ExamRepository, - private val newExamNotification: NewExamNotification, -) : Work { +class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val startDate = now().startExamsDay - val endDate = startDate.endExamsDay - - examRepository.getExams( - student = student, - semester = semester, - start = startDate, - end = endDate, - forceRefresh = true, - notify = notify, - ).waitForResult() - - examRepository.getExamsFromDatabase( - semester = semester, - start = startDate, - end = endDate, - ) - .first() - .filter { !it.isNotified }.let { - if (it.isNotEmpty()) newExamNotification.notify(it, student) - - examRepository.updateExam(it.onEach { exam -> exam.isNotified = true }) - } + override suspend fun doWork(student: Student, semester: Semester) { + examRepository.getExams(student, semester, now(), now(), true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt index ac35bc9a..461836b8 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt @@ -2,16 +2,15 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.GradeStatisticsRepository -import io.github.wulkanowy.data.waitForResult - +import io.github.wulkanowy.data.repositories.gradestatistics.GradeStatisticsRepository +import io.github.wulkanowy.utils.waitForResult import javax.inject.Inject class GradeStatisticsWork @Inject constructor( private val gradeStatisticsRepository: GradeStatisticsRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { + override suspend fun doWork(student: Student, semester: Semester) { with(gradeStatisticsRepository) { getGradesPartialStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult() getGradesSemesterStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult() diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt index b62ad94b..00bce109 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt @@ -1,59 +1,103 @@ package io.github.wulkanowy.services.sync.works +import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.content.Context +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationCompat.DEFAULT_ALL +import androidx.core.app.NotificationCompat.PRIORITY_HIGH +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Grade +import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.GradeRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewGradeNotification +import io.github.wulkanowy.data.repositories.grade.GradeRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.services.sync.channels.NewGradesChannel +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.getCompatColor +import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject +import kotlin.random.Random class GradeWork @Inject constructor( + @ApplicationContext private val context: Context, + private val notificationManager: NotificationManagerCompat, private val gradeRepository: GradeRepository, - private val newGradeNotification: NewGradeNotification, + private val preferencesRepository: PreferencesRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - gradeRepository.getGrades( - student = student, - semester = semester, - forceRefresh = true, - notify = notify, - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() - gradeRepository.getGradesFromDatabase(semester).first() - .filter { !it.isNotified }.let { - if (it.isNotEmpty()) newGradeNotification.notifyDetails(it, student) + gradeRepository.getNotNotifiedGrades(semester).first().let { + if (it.isNotEmpty()) notifyDetails(it) + gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true }) + } - gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true }) - } + gradeRepository.getNotNotifiedPredictedGrades(semester).first().let { + if (it.isNotEmpty()) notifyPredicted(it) + gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true }) + } - gradeRepository.getGradesPredictedFromDatabase(semester).first() - .filter { !it.isPredictedGradeNotified }.let { - if (it.isNotEmpty()) newGradeNotification.notifyPredicted(it, student) + gradeRepository.getNotNotifiedFinalGrades(semester).first().let { + if (it.isNotEmpty()) notifyFinal(it) + gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true }) + } + } - gradeRepository.updateGradesSummary(it.onEach { grade -> - grade.isPredictedGradeNotified = true - }) - } + private fun getNotificationBuilder(): NotificationCompat.Builder { + return NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID) + .setSmallIcon(R.drawable.ic_stat_grade) + .setAutoCancel(true) + .setPriority(PRIORITY_HIGH) + .setDefaults(DEFAULT_ALL) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setContentIntent( + PendingIntent.getActivity(context, MainView.Section.GRADE.id, + MainActivity.getStartIntent(context, MainView.Section.GRADE, true), FLAG_UPDATE_CURRENT)) + } - gradeRepository.getGradesFinalFromDatabase(semester).first() - .filter { !it.isFinalGradeNotified }.let { - if (it.isNotEmpty()) newGradeNotification.notifyFinal(it, student) + private fun notifyDetails(grades: List) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() + .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size)) + .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size)) + .setStyle(NotificationCompat.InboxStyle().run { + setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size)) + grades.forEach { addLine("${it.subject}: ${it.entry}") } + this + }) + .build() + ) + } - gradeRepository.updateGradesSummary(it.onEach { grade -> - grade.isFinalGradeNotified = true - }) - } + private fun notifyPredicted(gradesSummary: List) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() + .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_predicted, gradesSummary.size, gradesSummary.size)) + .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_predicted, gradesSummary.size, gradesSummary.size)) + .setStyle(NotificationCompat.InboxStyle().run { + setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size)) + gradesSummary.forEach { addLine("${it.subject}: ${it.predictedGrade}") } + this + }) + .build() + ) + } - gradeRepository.getGradesDescriptiveFromDatabase(semester).first() - .filter { !it.isNotified } - .let { - if (it.isNotEmpty()) newGradeNotification.notifyDescriptive(it, student) - - gradeRepository.updateGradesDescriptive(it.onEach { grade -> - grade.isNotified = true - }) - } + private fun notifyFinal(gradesSummary: List) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder() + .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_final, gradesSummary.size, gradesSummary.size)) + .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_final, gradesSummary.size, gradesSummary.size)) + .setStyle(NotificationCompat.InboxStyle().run { + setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size)) + gradesSummary.forEach { addLine("${it.subject}: ${it.finalGrade}") } + this + }) + .build() + ) } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt index ddff3af7..a07f1107 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/HomeworkWork.kt @@ -2,46 +2,16 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewHomeworkNotification +import io.github.wulkanowy.data.repositories.homework.HomeworkRepository import io.github.wulkanowy.utils.monday -import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.sunday -import kotlinx.coroutines.flow.first +import io.github.wulkanowy.utils.waitForResult import java.time.LocalDate.now import javax.inject.Inject -class HomeworkWork @Inject constructor( - private val homeworkRepository: HomeworkRepository, - private val newHomeworkNotification: NewHomeworkNotification, -) : Work { +class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val startDate = now().nextOrSameSchoolDay.monday - val endDate = startDate.sunday - - homeworkRepository.getHomework( - student = student, - semester = semester, - start = startDate, - end = endDate, - forceRefresh = true, - notify = notify, - ).waitForResult() - - homeworkRepository.getHomeworkFromDatabase( - semester = semester, - start = startDate, - end = endDate - ) - .first() - .filter { !it.isNotified }.let { - if (it.isNotEmpty()) newHomeworkNotification.notify(it, student) - - homeworkRepository.updateHomework(it.onEach { homework -> - homework.isNotified = true - }) - } + override suspend fun doWork(student: Student, semester: Semester) { + homeworkRepository.getHomework(student, semester, now().monday, now().sunday, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt index 668b1b6b..7b9f5ab3 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/LuckyNumberWork.kt @@ -1,27 +1,55 @@ package io.github.wulkanowy.services.sync.works +import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.content.Context +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationCompat.DEFAULT_ALL +import androidx.core.app.NotificationCompat.PRIORITY_HIGH +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.LuckyNumberRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewLuckyNumberNotification +import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.getCompatColor +import io.github.wulkanowy.utils.waitForResult import javax.inject.Inject +import kotlin.random.Random class LuckyNumberWork @Inject constructor( + @ApplicationContext private val context: Context, + private val notificationManager: NotificationManagerCompat, private val luckyNumberRepository: LuckyNumberRepository, - private val newLuckyNumberNotification: NewLuckyNumberNotification, + private val preferencesRepository: PreferencesRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - luckyNumberRepository.getLuckyNumber( - student = student, - forceRefresh = true, - notify = notify, - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + luckyNumberRepository.getLuckyNumber(student, true, preferencesRepository.isNotificationsEnable).waitForResult() luckyNumberRepository.getNotNotifiedLuckyNumber(student)?.let { - newLuckyNumberNotification.notify(it, student) + notify(it) luckyNumberRepository.updateLuckyNumber(it.apply { isNotified = true }) } } + + private fun notify(luckyNumber: LuckyNumber) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, LuckyNumberChannel.CHANNEL_ID) + .setContentTitle(context.getString(R.string.lucky_number_notify_new_item_title)) + .setContentText(context.getString(R.string.lucky_number_notify_new_item, luckyNumber.luckyNumber)) + .setSmallIcon(R.drawable.ic_stat_luckynumber) + .setAutoCancel(true) + .setDefaults(DEFAULT_ALL) + .setPriority(PRIORITY_HIGH) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setContentIntent( + PendingIntent.getActivity(context, MainView.Section.MESSAGE.id, + MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT)) + .build()) + } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt index c7824e61..7b32f13b 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt @@ -1,33 +1,63 @@ package io.github.wulkanowy.services.sync.works +import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.content.Context +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationCompat.DEFAULT_ALL +import androidx.core.app.NotificationCompat.PRIORITY_HIGH +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewMessageNotification +import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED +import io.github.wulkanowy.data.repositories.message.MessageRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.services.sync.channels.NewMessagesChannel +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.getCompatColor +import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject +import kotlin.random.Random class MessageWork @Inject constructor( + @ApplicationContext private val context: Context, + private val notificationManager: NotificationManagerCompat, private val messageRepository: MessageRepository, - private val newMessageNotification: NewMessageNotification, + private val preferencesRepository: PreferencesRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val mailbox = messageRepository.getMailboxByStudent(student) - messageRepository.getMessages( - student = student, - mailbox = mailbox, - folder = RECEIVED, - forceRefresh = true, - notify = notify - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + messageRepository.getMessages(student, semester, RECEIVED, true, preferencesRepository.isNotificationsEnable).waitForResult() - messageRepository.getMessagesFromDatabase(student, mailbox).first() - .filter { !it.isNotified && it.unread }.let { - if (it.isNotEmpty()) newMessageNotification.notify(it, student) - messageRepository.updateMessages(it.onEach { message -> message.isNotified = true }) - } + messageRepository.getNotNotifiedMessages(student).first().let { + if (it.isNotEmpty()) notify(it) + messageRepository.updateMessages(it.onEach { message -> message.isNotified = true }) + } + } + + private fun notify(messages: List) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewMessagesChannel.CHANNEL_ID) + .setContentTitle(context.resources.getQuantityString(R.plurals.message_new_items, messages.size, messages.size)) + .setContentText(context.resources.getQuantityString(R.plurals.message_notify_new_items, messages.size, messages.size)) + .setSmallIcon(R.drawable.ic_stat_message) + .setAutoCancel(true) + .setDefaults(DEFAULT_ALL) + .setPriority(PRIORITY_HIGH) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setContentIntent( + PendingIntent.getActivity(context, MainView.Section.MESSAGE.id, + MainActivity.getStartIntent(context, MainView.Section.MESSAGE, true), FLAG_UPDATE_CURRENT) + ) + .setStyle(NotificationCompat.InboxStyle().run { + setSummaryText(context.resources.getQuantityString(R.plurals.message_number_item, messages.size, messages.size)) + messages.forEach { addLine("${it.sender}: ${it.subject}") } + this + }) + .build()) } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt index df6e2b06..b0889696 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/NoteWork.kt @@ -1,32 +1,83 @@ package io.github.wulkanowy.services.sync.works +import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.content.Context +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationCompat.DEFAULT_ALL +import androidx.core.app.NotificationCompat.PRIORITY_HIGH +import androidx.core.app.NotificationManagerCompat +import dagger.hilt.android.qualifiers.ApplicationContext +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.NoteRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewNoteNotification +import io.github.wulkanowy.data.repositories.note.NoteRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory +import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory.NEUTRAL +import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory.POSITIVE +import io.github.wulkanowy.services.sync.channels.NewNotesChannel +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.getCompatColor +import io.github.wulkanowy.utils.waitForResult import kotlinx.coroutines.flow.first import javax.inject.Inject +import kotlin.random.Random class NoteWork @Inject constructor( + @ApplicationContext private val context: Context, + private val notificationManager: NotificationManagerCompat, private val noteRepository: NoteRepository, - private val newNoteNotification: NewNoteNotification, + private val preferencesRepository: PreferencesRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - noteRepository.getNotes( - student = student, - semester = semester, - forceRefresh = true, - notify = notify, - ).waitForResult() + override suspend fun doWork(student: Student, semester: Semester) { + noteRepository.getNotes(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() - noteRepository.getNotesFromDatabase(student).first() - .filter { !it.isNotified }.let { - if (it.isNotEmpty()) newNoteNotification.notify(it, student) + noteRepository.getNotNotifiedNotes(student).first().let { + if (it.isNotEmpty()) notify(it) + noteRepository.updateNotes(it.onEach { note -> note.isNotified = true }) + } + } - noteRepository.updateNotes(it.onEach { note -> note.isNotified = true }) - } + private fun notify(notes: List) { + notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewNotesChannel.CHANNEL_ID) + .setContentTitle( + when (NoteCategory.getByValue(notes.first().categoryType)) { + POSITIVE -> context.resources.getQuantityString(R.plurals.praise_new_items, notes.size, notes.size) + NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_new_items, notes.size, notes.size) + else -> context.resources.getQuantityString(R.plurals.note_new_items, notes.size, notes.size) + } + ) + .setContentText( + when (NoteCategory.getByValue(notes.first().categoryType)) { + POSITIVE -> context.resources.getQuantityString(R.plurals.praise_notify_new_items, notes.size, notes.size) + NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_notify_new_items, notes.size, notes.size) + else -> context.resources.getQuantityString(R.plurals.note_notify_new_items, notes.size, notes.size) + } + ) + .setSmallIcon(R.drawable.ic_stat_note) + .setAutoCancel(true) + .setDefaults(DEFAULT_ALL) + .setPriority(PRIORITY_HIGH) + .setColor(context.getCompatColor(R.color.colorPrimary)) + .setContentIntent( + PendingIntent.getActivity(context, MainView.Section.NOTE.id, + MainActivity.getStartIntent(context, MainView.Section.NOTE, true), FLAG_UPDATE_CURRENT)) + .setStyle(NotificationCompat.InboxStyle().run { + setSummaryText( + when (NoteCategory.getByValue(notes.first().categoryType)) { + POSITIVE -> context.resources.getQuantityString(R.plurals.praise_number_item, notes.size, notes.size) + NEUTRAL -> context.resources.getQuantityString(R.plurals.neutral_note_number_item, notes.size, notes.size) + else -> context.resources.getQuantityString(R.plurals.note_number_item, notes.size, notes.size) + } + ) + notes.forEach { addLine("${it.teacher}: ${it.category}") } + this + }) + .build()) } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt index 90b20651..c433c0ac 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt @@ -1,23 +1,23 @@ package io.github.wulkanowy.services.sync.works -import io.github.wulkanowy.data.dataOrNull -import io.github.wulkanowy.data.db.entities.MailboxType import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.repositories.RecipientRepository -import io.github.wulkanowy.data.toFirstResult +import io.github.wulkanowy.data.repositories.recipient.RecipientRepository +import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository import javax.inject.Inject class RecipientWork @Inject constructor( - private val messageRepository: MessageRepository, + private val reportingUnitRepository: ReportingUnitRepository, private val recipientRepository: RecipientRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val mailboxes = messageRepository.getMailboxes(student, forceRefresh = true).toFirstResult() - mailboxes.dataOrNull?.forEach { - recipientRepository.refreshRecipients(student, it, MailboxType.EMPLOYEE) + override suspend fun doWork(student: Student, semester: Semester) { + reportingUnitRepository.refreshReportingUnits(student) + + reportingUnitRepository.getReportingUnits(student).let { units -> + units.map { + recipientRepository.refreshRecipients(student, 2, it) + } } } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt deleted file mode 100644 index 1aedc839..00000000 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/SchoolAnnouncementWork.kt +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.wulkanowy.services.sync.works - -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification -import kotlinx.coroutines.flow.first -import java.time.LocalDate -import javax.inject.Inject - -class SchoolAnnouncementWork @Inject constructor( - private val schoolAnnouncementRepository: SchoolAnnouncementRepository, - private val newSchoolAnnouncementNotification: NewSchoolAnnouncementNotification, -) : Work { - - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - schoolAnnouncementRepository.getSchoolAnnouncements( - student = student, - forceRefresh = true, - notify = notify, - ).waitForResult() - - schoolAnnouncementRepository.getSchoolAnnouncementFromDatabase(student) - .first() - .filter { !it.isNotified && it.date >= LocalDate.now() } - .let { - if (it.isNotEmpty()) { - newSchoolAnnouncementNotification.notify(it, student) - } - - schoolAnnouncementRepository.updateSchoolAnnouncement(it.onEach { schoolAnnouncement -> - schoolAnnouncement.isNotified = true - }) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/TeacherWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/TeacherWork.kt index e7c72bf0..a9abdaa7 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/TeacherWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/TeacherWork.kt @@ -2,14 +2,13 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.TeacherRepository -import io.github.wulkanowy.data.waitForResult - +import io.github.wulkanowy.data.repositories.teacher.TeacherRepository +import io.github.wulkanowy.utils.waitForResult import javax.inject.Inject class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { + override suspend fun doWork(student: Student, semester: Semester) { teacherRepository.getTeachers(student, semester, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/TimetableWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/TimetableWork.kt index 2d10d925..3b8c6f5d 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/TimetableWork.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/TimetableWork.kt @@ -2,44 +2,18 @@ package io.github.wulkanowy.services.sync.works import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.data.waitForResult -import io.github.wulkanowy.services.sync.notifications.ChangeTimetableNotification -import io.github.wulkanowy.utils.nextOrSameSchoolDay +import io.github.wulkanowy.data.repositories.timetable.TimetableRepository +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.waitForResult import java.time.LocalDate.now import javax.inject.Inject class TimetableWork @Inject constructor( - private val timetableRepository: TimetableRepository, - private val changeTimetableNotification: ChangeTimetableNotification, + private val timetableRepository: TimetableRepository ) : Work { - override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) { - val startDate = now().nextOrSameSchoolDay - val endDate = startDate.plusDays(7) - - timetableRepository.getTimetable( - student = student, - semester = semester, - start = startDate, - end = endDate, - forceRefresh = true, - notify = notify, - ) - .waitForResult() - - timetableRepository.getTimetableFromDatabase( - semester = semester, - start = startDate, - end = endDate, - ) - .filterNot { it.isNotified } - .let { - if (it.isNotEmpty()) changeTimetableNotification.notify(it, student) - - timetableRepository.updateTimetable(it.onEach { timetable -> - timetable.isNotified = true - }) - } + override suspend fun doWork(student: Student, semester: Semester) { + timetableRepository.getTimetable(student, semester, now().monday, now().sunday, true).waitForResult() } } diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/Work.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/Work.kt index 1c0214cd..c41f41ce 100644 --- a/app/src/main/java/io/github/wulkanowy/services/sync/works/Work.kt +++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/Work.kt @@ -5,5 +5,5 @@ import io.github.wulkanowy.data.db.entities.Student interface Work { - suspend fun doWork(student: Student, semester: Semester, notify: Boolean) + suspend fun doWork(student: Student, semester: Semester) } diff --git a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt index ffdb07ec..42c6d3bf 100644 --- a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt +++ b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt @@ -4,10 +4,10 @@ import android.content.Intent import android.widget.RemoteViewsService import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.timetable.TimetableRepository import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetFactory import timber.log.Timber import javax.inject.Inject @@ -25,21 +25,13 @@ class TimetableWidgetService : RemoteViewsService() { lateinit var semesterRepo: SemesterRepository @Inject - lateinit var sharedPref: SharedPrefProvider + lateinit var prefRepository: PreferencesRepository @Inject - lateinit var prefRepository: PreferencesRepository + lateinit var sharedPref: SharedPrefProvider override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory { Timber.d("TimetableWidgetFactory created") - return TimetableWidgetFactory( - timetableRepository = timetableRepo, - studentRepository = studentRepo, - semesterRepository = semesterRepo, - sharedPref = sharedPref, - prefRepository = prefRepository, - context = applicationContext, - intent = intent, - ) + return TimetableWidgetFactory(timetableRepo, studentRepo, semesterRepo, prefRepository, sharedPref, applicationContext, intent) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseActivity.kt index 922c3536..86b6701b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BaseActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseActivity.kt @@ -1,25 +1,24 @@ package io.github.wulkanowy.ui.base import android.app.ActivityManager -import android.os.Build +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP import android.os.Bundle import android.view.View import android.widget.Toast +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate import androidx.viewbinding.ViewBinding -import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar.LENGTH_LONG import io.github.wulkanowy.R -import io.github.wulkanowy.ui.modules.auth.AuthDialog -import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.utils.FragmentLifecycleLogger import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.lifecycleAwareVariable -import io.github.wulkanowy.utils.openInternetBrowser -import timber.log.Timber -import java.time.Instant import javax.inject.Inject abstract class BaseActivity, VB : ViewBinding> : @@ -35,29 +34,17 @@ abstract class BaseActivity, VB : ViewBinding> : protected var messageContainer: View? = null - protected var messageAnchor: View? = null - abstract var presenter: T - private var lastDialogOpenTime = mutableMapOf() - override fun onCreate(savedInstanceState: Bundle?) { - inject() themeManager.applyActivityTheme(this) super.onCreate(savedInstanceState) supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleLogger, true) - applyCustomTaskDescription() - } + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) - @Suppress("DEPRECATION") - private fun applyCustomTaskDescription() { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) return - try { - val newColor = getThemeAttrColor(R.attr.colorSurface) - val taskDescription = ActivityManager.TaskDescription(null, null, newColor) - setTaskDescription(taskDescription) - } catch (e: Exception) { - Timber.e(e) + if (SDK_INT >= LOLLIPOP) { + @Suppress("DEPRECATION") + setTaskDescription(ActivityManager.TaskDescription(null, null, getThemeAttrColor(R.attr.colorSurface))) } } @@ -65,7 +52,6 @@ abstract class BaseActivity, VB : ViewBinding> : if (messageContainer != null) { Snackbar.make(messageContainer!!, text, LENGTH_LONG) .setAction(R.string.all_details) { showErrorDetailsDialog(error) } - .apply { messageAnchor?.let { anchorView = it } } .show() } else showMessage(text) } @@ -75,55 +61,22 @@ abstract class BaseActivity, VB : ViewBinding> : } override fun showMessage(text: String) { - if (messageContainer != null) { - Snackbar.make(messageContainer!!, text, LENGTH_LONG) - .apply { messageAnchor?.let { anchorView = it } } - .show() - } else Toast.makeText(this, text, Toast.LENGTH_LONG).show() + if (messageContainer != null) Snackbar.make(messageContainer!!, text, LENGTH_LONG).show() + else Toast.makeText(this, text, Toast.LENGTH_LONG).show() } - override fun showExpiredCredentialsDialog() { - if (!shouldShowDialog(DIALOG_ERROR_BAD_CREDENTIALS)) return - - MaterialAlertDialogBuilder(this) - .setTitle(R.string.main_expired_credentials_title) - .setMessage(R.string.main_expired_credentials_description) - .setPositiveButton(R.string.main_log_in) { _, _ -> presenter.onConfirmExpiredCredentialsSelected() } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() - } - - override fun onCaptchaVerificationRequired(url: String?) { - CaptchaDialog.newInstance(url).show(supportFragmentManager, "captcha_dialog") - } - - override fun showDecryptionFailedDialog() { - if (!shouldShowDialog(DIALOG_ERROR_DECRYPTION_FAILED)) return - - MaterialAlertDialogBuilder(this) + override fun showExpiredDialog() { + AlertDialog.Builder(this) .setTitle(R.string.main_session_expired) .setMessage(R.string.main_session_relogin) - .setPositiveButton(R.string.main_log_in) { _, _ -> presenter.onConfirmDecryptionFailedSelected() } + .setPositiveButton(R.string.main_log_in) { _, _ -> presenter.onExpiredLoginSelected() } .setNegativeButton(android.R.string.cancel) { _, _ -> } .show() } - override fun showAuthDialog() { - AuthDialog.newInstance().show(supportFragmentManager, "auth_dialog") - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - messageContainer?.let { - Snackbar.make(it, R.string.error_password_change_required, LENGTH_LONG) - .setAction(R.string.all_change) { openInternetBrowser(redirectUrl) } - .apply { messageAnchor?.let { anchorView = it } } - .show() - } - } - override fun openClearLoginView() { - startActivity(LoginActivity.getStartIntent(this)) - finishAffinity() + startActivity(LoginActivity.getStartIntent(this) + .apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) }) } override fun onDestroy() { @@ -131,26 +84,4 @@ abstract class BaseActivity, VB : ViewBinding> : invalidateOptionsMenu() presenter.onDetachView() } - - //https://github.com/google/dagger/releases/tag/dagger-2.33 - protected open fun inject() { - throw UnsupportedOperationException() - } - - private fun shouldShowDialog(name: String): Boolean { - val lastOpenTime = lastDialogOpenTime[name] - val now = Instant.now() - - if (lastOpenTime != null && now.isBefore(lastOpenTime.plusSeconds(1))) { - Timber.i("Dialog $name was shown less than a second ago. Skip") - return false - } - lastDialogOpenTime[name] = Instant.now() - return true - } - - companion object { - private const val DIALOG_ERROR_BAD_CREDENTIALS = "dialog_error_bad_credentials" - private const val DIALOG_ERROR_DECRYPTION_FAILED = "dialog_error_decryption_failed" - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseDialogFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseDialogFragment.kt index e63887b8..1c31976e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BaseDialogFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseDialogFragment.kt @@ -1,13 +1,8 @@ package io.github.wulkanowy.ui.base -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.DialogFragment import androidx.viewbinding.ViewBinding -import com.google.android.material.elevation.SurfaceColors import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.lifecycleAwareVariable import javax.inject.Inject @@ -27,45 +22,18 @@ abstract class BaseDialogFragment : DialogFragment(), BaseView Toast.makeText(context, text, Toast.LENGTH_LONG).show() } - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() + override fun showExpiredDialog() { + (activity as? BaseActivity<*, *>)?.showExpiredDialog() } override fun openClearLoginView() { (activity as? BaseActivity<*, *>)?.openClearLoginView() } - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - override fun showErrorDetailsDialog(error: Throwable) { ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - view.setBackgroundColor(SurfaceColors.SURFACE_3.getColor(requireContext())) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ) = binding.root - override fun onResume() { super.onResume() analyticsHelper.setCurrentScreen(requireActivity(), this::class.simpleName) diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragment.kt index ba346131..c6a2e1d1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragment.kt @@ -38,27 +38,11 @@ abstract class BaseFragment(@LayoutRes layoutId: Int) : Fragme } } - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() + override fun showExpiredDialog() { + (activity as? BaseActivity<*, *>)?.showExpiredDialog() } override fun openClearLoginView() { (activity as? BaseActivity<*, *>)?.openClearLoginView() } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt index 6bca87f1..5f8bf417 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseFragmentPagerAdapter.kt @@ -2,33 +2,31 @@ package io.github.wulkanowy.ui.base import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Lifecycle -import androidx.viewpager2.adapter.FragmentStateAdapter -import com.google.android.material.tabs.TabLayout -import com.google.android.material.tabs.TabLayoutMediator +import androidx.fragment.app.FragmentPagerAdapter -class BaseFragmentPagerAdapter( - private val fragmentManager: FragmentManager, - private val pagesCount: Int, - lifecycle: Lifecycle, -) : FragmentStateAdapter(fragmentManager, lifecycle), TabLayoutMediator.TabConfigurationStrategy { +class BaseFragmentPagerAdapter(private val fragmentManager: FragmentManager) : + FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { - lateinit var itemFactory: (position: Int) -> Fragment - - var titleFactory: (position: Int) -> String? = { "" } + private val pages = mutableMapOf() var containerId = 0 fun getFragmentInstance(position: Int): Fragment? { require(containerId != 0) { "Container id is 0" } - return fragmentManager.findFragmentByTag("f$position") + return fragmentManager.findFragmentByTag("android:switcher:$containerId:$position") } - override fun createFragment(position: Int): Fragment = itemFactory(position) - - override fun getItemCount() = pagesCount - - override fun onConfigureTab(tab: TabLayout.Tab, position: Int) { - tab.text = titleFactory(position) + fun addFragments(fragments: List) { + fragments.forEach { pages[it] = null } } + + fun addFragmentsWithTitle(pages: Map) { + this.pages.putAll(pages) + } + + override fun getItem(position: Int) = pages.keys.elementAt(position) + + override fun getCount() = pages.size + + override fun getPageTitle(position: Int) = pages.values.elementAt(position) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BasePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BasePresenter.kt index d4cb20ca..ba8bfd85 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BasePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BasePresenter.kt @@ -1,100 +1,84 @@ package io.github.wulkanowy.ui.base -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.utils.flowWithResource import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.onEach import timber.log.Timber +import kotlin.coroutines.CoroutineContext open class BasePresenter( protected val errorHandler: ErrorHandler, protected val studentRepository: StudentRepository -) { - private val job = SupervisorJob() +) : CoroutineScope { - protected val presenterScope = CoroutineScope(job + Dispatchers.Main) + private var job: Job = Job() - private val childrenJobs = mutableMapOf() + private val jobs = mutableMapOf() + + override val coroutineContext: CoroutineContext + get() = Dispatchers.Main + job var view: T? = null open fun onAttachView(view: T) { + job = Job() this.view = view errorHandler.apply { showErrorMessage = view::showError - onExpiredCredentials = view::showExpiredCredentialsDialog - onCaptchaVerificationRequired = view::onCaptchaVerificationRequired - onDecryptionFailed = view::showDecryptionFailedDialog + onSessionExpired = view::showExpiredDialog onNoCurrentStudent = view::openClearLoginView - onPasswordChangeRequired = view::showChangePasswordSnackbar - onAuthorizationRequired = view::showAuthDialog } } - fun onConfirmDecryptionFailedSelected() { - Timber.i("Attempt to clear all data") + fun onExpiredLoginSelected() { + flowWithResource { + val student = studentRepository.getCurrentStudent(false) + studentRepository.logoutStudent(student) - presenterScope.launch { - runCatching { studentRepository.clearAll() } - .onFailure { - Timber.i("Clear data result: An exception occurred") - errorHandler.dispatch(it) - } - .onSuccess { - Timber.i("Clear data result: Open login view") + val students = studentRepository.getSavedStudents(false) + if (students.isNotEmpty()) { + Timber.i("Switching current student") + studentRepository.switchStudent(students[0]) + } + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Attempt to switch the student after the session expires") + Status.SUCCESS -> { + Timber.i("Switch student result: Open login view") view?.openClearLoginView() } - } - } - - fun onConfirmExpiredCredentialsSelected() { - Timber.i("Attempt to delete students associated with the account and switch to new student") - - presenterScope.launch { - runCatching { - val student = studentRepository.getCurrentStudent(false) - studentRepository.deleteStudentsAssociatedWithAccount(student) - - val students = studentRepository.getSavedStudents(false) - if (students.isNotEmpty()) { - Timber.i("Switching current student") - studentRepository.switchStudent(students[0]) + Status.ERROR -> { + Timber.i("Switch student result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onFailure { - Timber.i("Delete students result: An exception occurred") - errorHandler.dispatch(it) - } - .onSuccess { - Timber.i("Delete students result: Open login view") - view?.openClearLoginView() - } - } + }.launch("expired") } fun Flow.launch(individualJobTag: String = "load"): Job { - childrenJobs[individualJobTag]?.cancel() - val job = catch { errorHandler.dispatch(it) }.launchIn(presenterScope) - childrenJobs[individualJobTag] = job + jobs[individualJobTag]?.cancel() + val job = catch { errorHandler.dispatch(it) }.launchIn(this@BasePresenter) + jobs[individualJobTag] = job Timber.d("Job $individualJobTag launched in ${this@BasePresenter.javaClass.simpleName}: $job") return job } fun cancelJobs(vararg names: String) { names.forEach { - childrenJobs[it]?.cancel() + jobs[it]?.cancel() } } open fun onDetachView() { - job.cancelChildren() - errorHandler.clear() view = null + job.cancel() + errorHandler.clear() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/BaseView.kt b/app/src/main/java/io/github/wulkanowy/ui/base/BaseView.kt index 88d5754f..0f4df92c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/BaseView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/BaseView.kt @@ -6,17 +6,9 @@ interface BaseView { fun showMessage(text: String) - fun showExpiredCredentialsDialog() - - fun onCaptchaVerificationRequired(url: String?) - - fun showDecryptionFailedDialog() - - fun showAuthDialog() + fun showExpiredDialog() fun openClearLoginView() fun showErrorDetailsDialog(error: Throwable) - - fun showChangePasswordSnackbar(redirectUrl: String) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt index 679d904a..341ae459 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt @@ -1,84 +1,105 @@ package io.github.wulkanowy.ui.base -import android.app.Dialog import android.content.ClipData import android.content.ClipboardManager import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup +import android.widget.HorizontalScrollView import android.widget.Toast import android.widget.Toast.LENGTH_LONG import androidx.appcompat.app.AlertDialog import androidx.core.content.getSystemService -import androidx.core.os.bundleOf -import androidx.core.view.isGone -import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.databinding.DialogErrorBinding -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException +import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException +import io.github.wulkanowy.sdk.scrapper.exception.ServiceUnavailableException +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.getString +import io.github.wulkanowy.utils.openAppInMarket +import io.github.wulkanowy.utils.openEmailClient +import io.github.wulkanowy.utils.openInternetBrowser +import okhttp3.internal.http2.StreamResetException +import java.io.InterruptedIOException +import java.io.PrintWriter +import java.io.StringWriter +import java.net.ConnectException +import java.net.SocketTimeoutException +import java.net.UnknownHostException import javax.inject.Inject @AndroidEntryPoint class ErrorDialog : BaseDialogFragment() { + private lateinit var error: Throwable + @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - - private lateinit var error: Throwable - companion object { - private const val ARGUMENT_KEY = "error" + private const val ARGUMENT_KEY = "Data" - fun newInstance(error: Throwable) = ErrorDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to error) + fun newInstance(error: Throwable): ErrorDialog { + return ErrorDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, error) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - error = requireArguments().serializable(ARGUMENT_KEY) - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext()).apply { - val errorStacktrace = error.stackTraceToString() - setTitle(R.string.all_details) - setView(DialogErrorBinding.inflate(layoutInflater).apply { binding = this }.root) - setNeutralButton(R.string.about_feedback) { _, _ -> - openConfirmDialog { openEmailClient(errorStacktrace) } - } - setNegativeButton(android.R.string.cancel) { _, _ -> } - setPositiveButton(android.R.string.copy) { _, _ -> copyErrorToClipboard(errorStacktrace) } - }.create().apply { - setOnShowListener { - getButton(AlertDialog.BUTTON_NEUTRAL).isEnabled = error.isShouldBeReported() - } + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + error = getSerializable(ARGUMENT_KEY) as Throwable } } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogErrorBinding.inflate(inflater).apply { binding = this }.root + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + + val stringWriter = StringWriter().apply { + error.printStackTrace(PrintWriter(this)) + } + with(binding) { - errorDialogHumanizedMessage.text = resources.getErrorString(error) - errorDialogErrorMessage.text = error.localizedMessage - errorDialogErrorMessage.isGone = error.localizedMessage.isNullOrBlank() - errorDialogContent.text = error.stackTraceToString() - .replace(": ${error.localizedMessage}", "") - } - } + errorDialogContent.text = stringWriter.toString() + with(errorDialogHorizontalScroll) { + post { fullScroll(HorizontalScrollView.FOCUS_LEFT) } + } + errorDialogCopy.setOnClickListener { + val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString()) + activity?.getSystemService()?.setPrimaryClip(clip) - private fun copyErrorToClipboard(errorStacktrace: String) { - val clip = ClipData.newPlainText("Error details", errorStacktrace) - requireActivity().getSystemService()?.setPrimaryClip(clip) - Toast.makeText(requireContext(), R.string.all_copied, LENGTH_LONG).show() + Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show() + } + errorDialogCancel.setOnClickListener { dismiss() } + errorDialogReport.setOnClickListener { + openConfirmDialog { openEmailClient(stringWriter.toString()) } + } + errorDialogMessage.text = resources.getString(error) + errorDialogReport.isEnabled = when (error) { + is UnknownHostException, + is InterruptedIOException, + is ConnectException, + is StreamResetException, + is SocketTimeoutException, + is ServiceUnavailableException, + is FeatureDisabledException, + is FeatureNotAvailableException -> false + else -> true + } + } } private fun openConfirmDialog(callback: () -> Unit) { - MaterialAlertDialogBuilder(requireContext()) + AlertDialog.Builder(requireContext()) .setTitle(R.string.dialog_error_check_update) .setMessage(R.string.dialog_error_check_update_message) .setNeutralButton(R.string.about_feedback) { _, _ -> callback() } @@ -93,18 +114,11 @@ class ErrorDialog : BaseDialogFragment() { chooserTitle = getString(R.string.about_feedback), email = "wulkanowyinc@gmail.com", subject = "Zgłoszenie błędu", - body = requireContext().getString( - R.string.about_feedback_template, - "${appInfo.systemManufacturer} ${appInfo.systemModel}", - appInfo.systemVersion.toString(), - "${appInfo.versionName}-${appInfo.buildFlavor}", - preferencesRepository.installationId, + body = requireContext().getString(R.string.about_feedback_template, + "${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName ) + "\n" + content, onActivityNotFound = { - requireContext().openInternetBrowser( - "https://github.com/wulkanowy/wulkanowy/issues", - ::showMessage - ) + requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage) } ) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt index 00a2ab22..946e661b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorHandler.kt @@ -1,60 +1,39 @@ package io.github.wulkanowy.ui.base -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext +import android.content.res.Resources +import com.chuckerteam.chucker.api.ChuckerCollector import io.github.wulkanowy.data.exceptions.NoCurrentStudentException -import io.github.wulkanowy.data.repositories.NoAuthorizationException -import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException -import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException -import io.github.wulkanowy.utils.getErrorString +import io.github.wulkanowy.utils.getString import io.github.wulkanowy.utils.security.ScramblerException import timber.log.Timber import javax.inject.Inject -open class ErrorHandler @Inject constructor(@ApplicationContext protected val context: Context) { +open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) { var showErrorMessage: (String, Throwable) -> Unit = { _, _ -> } - var onExpiredCredentials: () -> Unit = {} - - var onDecryptionFailed: () -> Unit = {} + var onSessionExpired: () -> Unit = {} var onNoCurrentStudent: () -> Unit = {} - var onPasswordChangeRequired: (String) -> Unit = {} - - var onAuthorizationRequired: () -> Unit = {} - - var onCaptchaVerificationRequired: (url: String?) -> Unit = {} - fun dispatch(error: Throwable) { + chuckerCollector.onError(error.javaClass.simpleName, error) Timber.e(error, "An exception occurred while the Wulkanowy was running") proceed(error) } protected open fun proceed(error: Throwable) { - showDefaultMessage(error) + showErrorMessage(resources.getString(error), error) when (error) { - is PasswordChangeRequiredException -> onPasswordChangeRequired(error.redirectUrl) - is ScramblerException -> onDecryptionFailed() - is BadCredentialsException -> onExpiredCredentials() + is ScramblerException, is BadCredentialsException -> onSessionExpired() is NoCurrentStudentException -> onNoCurrentStudent() - is NoAuthorizationException -> onAuthorizationRequired() - is CloudflareVerificationException -> onCaptchaVerificationRequired(error.originalUrl) } } - fun showDefaultMessage(error: Throwable) { - showErrorMessage(context.resources.getErrorString(error), error) - } - open fun clear() { showErrorMessage = { _, _ -> } - onExpiredCredentials = {} - onDecryptionFailed = {} + onSessionExpired = {} onNoCurrentStudent = {} - onPasswordChangeRequired = {} - onAuthorizationRequired = {} } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt index f42f315c..50134861 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt @@ -1,19 +1,13 @@ package io.github.wulkanowy.ui.base -import android.content.pm.PackageInfo -import android.content.pm.PackageManager import android.content.pm.PackageManager.GET_ACTIVITIES -import android.os.Build import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate -import com.google.android.material.color.DynamicColors +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO +import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES import io.github.wulkanowy.R -import io.github.wulkanowy.data.enums.AppTheme -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import javax.inject.Inject import javax.inject.Singleton @@ -23,44 +17,24 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer fun applyActivityTheme(activity: AppCompatActivity) { if (isThemeApplicable(activity)) { applyDefaultTheme() - if (preferencesRepository.appTheme == AppTheme.BLACK) { - when (activity) { - is MainActivity -> activity.setTheme(R.style.WulkanowyTheme_Black) - is LoginActivity -> activity.setTheme(R.style.WulkanowyTheme_Login_Black) - } - } - } else if (activity is TimetableWidgetConfigureActivity || activity is LuckyNumberWidgetConfigureActivity) { - DynamicColors.applyToActivityIfAvailable(activity) + if (preferencesRepository.appTheme == "black") activity.setTheme(R.style.WulkanowyTheme_Black) } } fun applyDefaultTheme() { AppCompatDelegate.setDefaultNightMode( - when (preferencesRepository.appTheme) { - AppTheme.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO - AppTheme.DARK, AppTheme.BLACK -> AppCompatDelegate.MODE_NIGHT_YES - AppTheme.SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM + when (val theme = preferencesRepository.appTheme) { + "light" -> MODE_NIGHT_NO + "dark", "black" -> MODE_NIGHT_YES + "system" -> MODE_NIGHT_FOLLOW_SYSTEM + else -> throw IllegalArgumentException("Wrong theme: $theme") } ) } - private fun isThemeApplicable(activity: AppCompatActivity): Boolean = - getPackageInfo(activity) - .activities - .singleOrNull { it.name == activity::class.java.canonicalName } - ?.theme - .let { - it == R.style.WulkanowyTheme_Black || it == R.style.WulkanowyTheme_NoActionBar - || it == R.style.WulkanowyTheme_Login || it == R.style.WulkanowyTheme_Login_Black - } - - @Suppress("DEPRECATION") - private fun getPackageInfo(activity: AppCompatActivity): PackageInfo { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - activity.packageManager.getPackageInfo( - activity.packageName, - PackageManager.PackageInfoFlags.of(GET_ACTIVITIES.toLong()) - ) - } else activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES) + private fun isThemeApplicable(activity: AppCompatActivity): Boolean { + return activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES) + .activities.singleOrNull { it.name == activity::class.java.canonicalName }?.theme + .let { it == R.style.WulkanowyTheme_Black || it == R.style.WulkanowyTheme_NoActionBar } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/WidgetConfigureAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/base/WidgetConfigureAdapter.kt index a43aaffb..cefe6ed7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/WidgetConfigureAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/WidgetConfigureAdapter.kt @@ -1,25 +1,19 @@ package io.github.wulkanowy.ui.base import android.annotation.SuppressLint +import android.graphics.PorterDuff import android.view.LayoutInflater import android.view.ViewGroup -import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.ItemAccountBinding -import io.github.wulkanowy.utils.createNameInitialsDrawable import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.nickOrName import javax.inject.Inject -class WidgetConfigureAdapter @Inject constructor() : - RecyclerView.Adapter() { +class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter() { - var items = emptyList() - - var selectedId = -1L + var items = emptyList>() var onClickListener: (Student) -> Unit = {} @@ -31,33 +25,17 @@ class WidgetConfigureAdapter @Inject constructor() : @SuppressLint("SetTextI18n") override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val (student, semesters) = items[position] - val semester = semesters.maxByOrNull { it.semesterId } - val context = holder.binding.root.context - val checkBackgroundColor = context.getThemeAttrColor(R.attr.colorSurface) - val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor) - val isDuplicatedStudent = items.filter { - val studentToCompare = it.student - - studentToCompare.studentId == student.studentId - && studentToCompare.schoolSymbol == student.schoolSymbol - && studentToCompare.symbol == student.symbol - }.size > 1 + val (student, isCurrent) = items[position] with(holder.binding) { - accountItemName.text = "${student.nickOrName} ${semester?.diaryName.orEmpty()}" + accountItemName.text = "${student.studentName} ${student.className}" accountItemSchool.text = student.schoolName - accountItemImage.setImageDrawable(avatar) - with(accountItemAccountType) { - setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student) - isVisible = isDuplicatedStudent - } + with(accountItemImage) { + val colorImage = if (isCurrent) context.getThemeAttrColor(R.attr.colorPrimary) + else context.getThemeAttrColor(R.attr.colorOnSurface, 153) - with(accountItemCheck) { - isVisible = student.id == selectedId - borderColor = checkBackgroundColor - circleColor = checkBackgroundColor + setColorFilter(colorImage, PorterDuff.Mode.SRC_IN) } root.setOnClickListener { onClickListener(student) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/Destination.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/Destination.kt deleted file mode 100644 index f0969fac..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/Destination.kt +++ /dev/null @@ -1,152 +0,0 @@ -package io.github.wulkanowy.ui.modules - -import androidx.fragment.app.Fragment -import io.github.wulkanowy.data.serializers.LocalDateSerializer -import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment -import io.github.wulkanowy.ui.modules.conference.ConferenceFragment -import io.github.wulkanowy.ui.modules.dashboard.DashboardFragment -import io.github.wulkanowy.ui.modules.exam.ExamFragment -import io.github.wulkanowy.ui.modules.grade.GradeFragment -import io.github.wulkanowy.ui.modules.homework.HomeworkFragment -import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment -import io.github.wulkanowy.ui.modules.luckynumber.history.LuckyNumberHistoryFragment -import io.github.wulkanowy.ui.modules.message.MessageFragment -import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment -import io.github.wulkanowy.ui.modules.more.MoreFragment -import io.github.wulkanowy.ui.modules.note.NoteFragment -import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment -import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment -import io.github.wulkanowy.ui.modules.settings.SettingsFragment -import io.github.wulkanowy.ui.modules.timetable.TimetableFragment -import kotlinx.serialization.Serializable -import java.time.LocalDate - -@Serializable -sealed class Destination { - - /* - Type in children classes have to be as getter to avoid null in enums - https://stackoverflow.com/questions/68866453/kotlin-enum-val-is-returning-null-despite-being-set-at-compile-time - */ - abstract val destinationType: Type - - abstract val destinationFragment: Fragment - - enum class Type(val defaultDestination: Destination) { - DASHBOARD(Dashboard), - GRADE(Grade), - ATTENDANCE(Attendance), - EXAM(Exam), - TIMETABLE(Timetable()), - HOMEWORK(Homework), - NOTE(Note), - CONFERENCE(Conference), - SCHOOL_ANNOUNCEMENT(SchoolAnnouncement), - SCHOOL_AND_TEACHERS(SchoolAndTeachers), - LUCKY_NUMBER(LuckyNumber), - LUCKY_NUMBER_HISTORY(LuckyNumberHistory), - MORE(More), - MESSAGE(Message), - MOBILE_DEVICE(MobileDevice), - SETTINGS(Settings); - } - - @Serializable - object Dashboard : Destination() { - override val destinationType get() = Type.DASHBOARD - override val destinationFragment get() = DashboardFragment.newInstance() - } - - @Serializable - object Grade : Destination() { - override val destinationType get() = Type.GRADE - override val destinationFragment get() = GradeFragment.newInstance() - } - - @Serializable - object Attendance : Destination() { - override val destinationType get() = Type.ATTENDANCE - override val destinationFragment get() = AttendanceFragment.newInstance() - } - - @Serializable - object Exam : Destination() { - override val destinationType get() = Type.EXAM - override val destinationFragment get() = ExamFragment.newInstance() - } - - @Serializable - data class Timetable( - @Serializable(with = LocalDateSerializer::class) - private val date: LocalDate? = null - ) : Destination() { - override val destinationType get() = Type.TIMETABLE - override val destinationFragment get() = TimetableFragment.newInstance(date) - } - - @Serializable - object Homework : Destination() { - override val destinationType get() = Type.HOMEWORK - override val destinationFragment get() = HomeworkFragment.newInstance() - } - - @Serializable - object Note : Destination() { - override val destinationType get() = Type.NOTE - override val destinationFragment get() = NoteFragment.newInstance() - } - - @Serializable - object Conference : Destination() { - override val destinationType get() = Type.CONFERENCE - override val destinationFragment get() = ConferenceFragment.newInstance() - } - - @Serializable - object SchoolAnnouncement : Destination() { - override val destinationType get() = Type.SCHOOL_ANNOUNCEMENT - override val destinationFragment get() = SchoolAnnouncementFragment.newInstance() - } - - @Serializable - object SchoolAndTeachers : Destination() { - override val destinationType get() = Type.SCHOOL_AND_TEACHERS - override val destinationFragment get() = SchoolAndTeachersFragment.newInstance() - } - - @Serializable - object LuckyNumber : Destination() { - override val destinationType get() = Type.LUCKY_NUMBER - override val destinationFragment get() = LuckyNumberFragment.newInstance() - } - - @Serializable - object LuckyNumberHistory : Destination() { - override val destinationType get() = Type.LUCKY_NUMBER_HISTORY - override val destinationFragment get() = LuckyNumberHistoryFragment.newInstance() - } - - @Serializable - object More : Destination() { - override val destinationType get() = Type.MORE - override val destinationFragment get() = MoreFragment.newInstance() - } - - @Serializable - object Message : Destination() { - override val destinationType get() = Type.MESSAGE - override val destinationFragment get() = MessageFragment.newInstance() - } - - @Serializable - object MobileDevice : Destination() { - override val destinationType get() = Type.MOBILE_DEVICE - override val destinationFragment get() = MobileDeviceFragment.newInstance() - } - - @Serializable - object Settings : Destination() { - override val destinationType get() = Type.SETTINGS - override val destinationFragment get() = SettingsFragment.newInstance() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutAdapter.kt index cd2dc210..35dec3b4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutAdapter.kt @@ -3,19 +3,14 @@ package io.github.wulkanowy.ui.modules.about import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.ViewGroup -import android.widget.Toast import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.databinding.ItemAboutBinding import io.github.wulkanowy.databinding.ScrollableHeaderAboutBinding import javax.inject.Inject -class AboutAdapter @Inject constructor( - private val preferencesRepository: PreferencesRepository -) : RecyclerView.Adapter() { +class AboutAdapter @Inject constructor() : RecyclerView.Adapter() { - private var developerModeClicks = 0 private enum class ViewType(val id: Int) { ITEM_HEADER(1), ITEM_ELEMENT(2) @@ -51,19 +46,6 @@ class AboutAdapter @Inject constructor( private fun bindHeaderViewHolder(binding: ScrollableHeaderAboutBinding) { with(binding.aboutScrollableHeaderIcon) { - setOnClickListener { - if (++developerModeClicks == 5 && !preferencesRepository.developerMode) { - preferencesRepository.developerMode = true - developerModeClicks = 0 - - Toast.makeText( - context, - "done!", - Toast.LENGTH_SHORT - ).show() - } - } - setImageDrawable(ResourcesCompat.getDrawableForDensity( context.resources, context.applicationInfo.icon, 640, null) ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt index d7f39e30..0730033f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt @@ -6,16 +6,18 @@ import android.view.View import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.databinding.FragmentAboutBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment -import io.github.wulkanowy.ui.modules.debug.DebugFragment +import io.github.wulkanowy.ui.modules.about.logviewer.LogViewerFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.* -import java.time.Instant +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.getCompatDrawable +import io.github.wulkanowy.utils.openAppInMarket +import io.github.wulkanowy.utils.openEmailClient +import io.github.wulkanowy.utils.openInternetBrowser import javax.inject.Inject @AndroidEntryPoint @@ -31,101 +33,49 @@ class AboutFragment : BaseFragment(R.layout.fragment_about @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - override val versionRes: Triple? get() = context?.run { - val buildTimestamp = - Instant.ofEpochMilli(appInfo.buildTimestamp).toFormattedString("yyyy-MM-dd") - val versionSignature = - "${appInfo.versionName}-${appInfo.buildFlavor} (${appInfo.versionCode}), $buildTimestamp" - Triple( - getString(R.string.about_version), - versionSignature, - getCompatDrawable(R.drawable.ic_all_about) - ) + Triple(getString(R.string.about_version), "${appInfo.versionName} (${appInfo.versionCode})", getCompatDrawable(R.drawable.ic_all_about)) } override val creatorsRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_contributor), - getString(R.string.about_contributor_summary), - getCompatDrawable(R.drawable.ic_about_creator) - ) + Triple(getString(R.string.about_contributor), getString(R.string.about_contributor_summary), getCompatDrawable(R.drawable.ic_about_creator)) } override val feedbackRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_feedback), - getString(R.string.about_feedback_summary), - getCompatDrawable(R.drawable.ic_about_feedback) - ) + Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback)) } override val faqRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_faq), - getString(R.string.about_faq_summary), - getCompatDrawable(R.drawable.ic_about_faq) - ) + Triple(getString(R.string.about_faq), getString(R.string.about_faq_summary), getCompatDrawable(R.drawable.ic_about_faq)) } override val discordRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_discord), - getString(R.string.about_discord_summary), - getCompatDrawable(R.drawable.ic_about_discord) - ) + Triple(getString(R.string.about_discord), getString(R.string.about_discord_summary), getCompatDrawable(R.drawable.ic_about_discord)) } override val facebookRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_facebook), - getString(R.string.about_facebook_summary), - getCompatDrawable(R.drawable.ic_about_facebook) - ) - } - - override val twitterRes: Triple? - get() = context?.run { - Triple( - getString(R.string.about_twitter), - getString(R.string.about_twitter_summary), - getCompatDrawable(R.drawable.ic_about_twitter) - ) + Triple(getString(R.string.about_facebook), getString(R.string.about_facebook_summary), getCompatDrawable(R.drawable.ic_about_facebook)) } override val homepageRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_homepage), - getString(R.string.about_homepage_summary), - getCompatDrawable(R.drawable.ic_all_home) - ) + Triple(getString(R.string.about_homepage), getString(R.string.about_homepage_summary), getCompatDrawable(R.drawable.ic_about_homepage)) } override val licensesRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_licenses), - getString(R.string.about_licenses_summary), - getCompatDrawable(R.drawable.ic_about_licenses) - ) + Triple(getString(R.string.about_licenses), getString(R.string.about_licenses_summary), getCompatDrawable(R.drawable.ic_about_licenses)) } override val privacyRes: Triple? get() = context?.run { - Triple( - getString(R.string.about_privacy), - getString(R.string.about_privacy_summary), - getCompatDrawable(R.drawable.ic_about_privacy) - ) + Triple(getString(R.string.about_privacy), getString(R.string.about_privacy_summary), getCompatDrawable(R.drawable.ic_about_privacy)) } override val titleStringId get() = R.string.about_title @@ -160,8 +110,8 @@ class AboutFragment : BaseFragment(R.layout.fragment_about context?.openAppInMarket(::showMessage) } - override fun openDebugScreen() { - (activity as? MainActivity)?.pushView(DebugFragment.newInstance()) + override fun openLogViewer() { + (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance()) } override fun openDiscordInvite() { @@ -172,10 +122,6 @@ class AboutFragment : BaseFragment(R.layout.fragment_about context?.openInternetBrowser("https://www.facebook.com/wulkanowy", ::showMessage) } - override fun openTwitterPage() { - context?.openInternetBrowser("https://twitter.com/wulkanowy", ::showMessage) - } - override fun openHomepage() { context?.openInternetBrowser("https://wulkanowy.github.io/", ::showMessage) } @@ -185,27 +131,17 @@ class AboutFragment : BaseFragment(R.layout.fragment_about chooserTitle = getString(R.string.about_feedback), email = "wulkanowyinc@gmail.com", subject = "Zgłoszenie błędu", - body = getString( - R.string.about_feedback_template, - "${appInfo.systemManufacturer} ${appInfo.systemModel}", - appInfo.systemVersion.toString(), - "${appInfo.versionName}-${appInfo.buildFlavor}", - preferencesRepository.installationId, + body = getString(R.string.about_feedback_template, + "${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName ), onActivityNotFound = { - requireContext().openInternetBrowser( - "https://github.com/wulkanowy/wulkanowy/issues", - ::showMessage - ) + requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage) } ) } override fun openFaqPage() { - context?.openInternetBrowser( - "https://wulkanowy.github.io/czesto-zadawane-pytania", - ::showMessage - ) + context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania", ::showMessage) } override fun openLicenses() { @@ -217,10 +153,7 @@ class AboutFragment : BaseFragment(R.layout.fragment_about } override fun openPrivacyPolicy() { - context?.openInternetBrowser( - "https://wulkanowy.github.io/polityka-prywatnosci.html", - ::showMessage - ) + context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index 55274934..76ba8212 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -1,6 +1,6 @@ package io.github.wulkanowy.ui.modules.about -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper @@ -26,10 +26,10 @@ class AboutPresenter @Inject constructor( view?.run { when (name) { versionRes?.first -> { - Timber.i("Opening debug screen") - if (appInfo.isDebug) openDebugScreen() + Timber.i("Opening log viewer") + if (appInfo.isDebug) openLogViewer() else openAppInMarket() - analytics.logEvent("about_open", "name" to "debug_screen") + analytics.logEvent("about_open", "name" to "log_viewer") } feedbackRes?.first -> { Timber.i("Opening email client") @@ -51,11 +51,6 @@ class AboutPresenter @Inject constructor( openFacebookPage() analytics.logEvent("about_open", "name" to "facebook") } - twitterRes?.first -> { - Timber.i("Opening twitter") - openTwitterPage() - analytics.logEvent("about_open", "name" to "twitter") - } homepageRes?.first -> { Timber.i("Opening homepage") openHomepage() @@ -82,20 +77,17 @@ class AboutPresenter @Inject constructor( private fun loadData() { view?.run { - updateData( - listOfNotNull( - versionRes, - creatorsRes, - feedbackRes, - faqRes, - discordRes, - facebookRes, - twitterRes, - homepageRes, - licensesRes, - privacyRes - ) - ) + updateData(listOfNotNull( + versionRes, + creatorsRes, + feedbackRes, + faqRes, + discordRes, + facebookRes, + homepageRes, + licensesRes, + privacyRes + )) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt index 5c286828..54882b30 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt @@ -15,8 +15,6 @@ interface AboutView : BaseView { val discordRes: Triple? - val twitterRes: Triple? - val facebookRes: Triple? val homepageRes: Triple? @@ -31,14 +29,12 @@ interface AboutView : BaseView { fun openAppInMarket() - fun openDebugScreen() + fun openLogViewer() fun openDiscordInvite() fun openFacebookPage() - fun openTwitterPage() - fun openEmailClient() fun openFaqPage() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/contributor/ContributorPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/contributor/ContributorPresenter.kt index 126bb2b4..78fdb43a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/contributor/ContributorPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/contributor/ContributorPresenter.kt @@ -1,11 +1,13 @@ package io.github.wulkanowy.ui.modules.about.contributor -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.pojos.Contributor -import io.github.wulkanowy.data.repositories.AppCreatorRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.appcreator.AppCreatorRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach import javax.inject.Inject class ContributorPresenter @Inject constructor( @@ -29,11 +31,15 @@ class ContributorPresenter @Inject constructor( } private fun loadData() { - resourceFlow { appCreatorRepository.getAppCreators() } - .onResourceLoading { view?.showProgress(true) } - .onResourceSuccess { view?.updateData(it) } - .onResourceNotLoading { view?.showProgress(false) } - .onResourceError { errorHandler.dispatch(it) } - .launch() + flowWithResource { appCreatorRepository.getAppCreators() }.onEach { + when (it.status) { + Status.LOADING -> view?.showProgress(true) + Status.SUCCESS -> view?.run { + showProgress(false) + updateData(it.data!!) + } + Status.ERROR -> errorHandler.dispatch(it.error!!) + } + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseAdapter.kt index adf4ca74..6ae06bbe 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseAdapter.kt @@ -23,9 +23,8 @@ class LicenseAdapter @Inject constructor() : RecyclerView.Adapter(R.layout.fragment_l @Inject lateinit var licenseAdapter: LicenseAdapter + private val libs by lazy { Libs(requireContext()) } + override val titleStringId get() = R.string.license_title - override val appLibraries by lazy { - Libs.Builder().withContext(requireContext()).build().libraries - } + override val appLibraries: ArrayList? + get() = context?.let { + libs.prepareLibraries(it, emptyArray(), emptyArray(), autoDetect = true, checkCachedDetection = true, sort = true) + } companion object { fun newInstance() = LicenseFragment() @@ -61,7 +63,7 @@ class LicenseFragment : BaseFragment(R.layout.fragment_l override fun openLicense(licenseHtml: String) { context?.let { - MaterialAlertDialogBuilder(it).apply { + AlertDialog.Builder(it).apply { setTitle(R.string.license_dialog_title) setMessage(licenseHtml.parseAsHtml()) setPositiveButton(android.R.string.ok) { _, _ -> } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicensePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicensePresenter.kt index ddcd5918..18d257ee 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicensePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicensePresenter.kt @@ -1,12 +1,16 @@ package io.github.wulkanowy.ui.modules.about.license import com.mikepenz.aboutlibraries.entity.Library -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.DispatchersProvider -import kotlinx.coroutines.launch +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.withContext +import timber.log.Timber import javax.inject.Inject class LicensePresenter @Inject constructor( @@ -22,20 +26,22 @@ class LicensePresenter @Inject constructor( } fun onItemSelected(library: Library) { - view?.run { library.licenses.firstOrNull()?.licenseContent?.let { openLicense(it) } } + view?.run { library.licenses?.firstOrNull()?.licenseDescription?.let { openLicense(it) } } } private fun loadData() { - presenterScope.launch { - runCatching { - withContext(dispatchers.io) { - view?.appLibraries.orEmpty() - } + flowWithResource { + withContext(dispatchers.backgroundThread) { + view?.appLibraries.orEmpty() } - .onFailure { errorHandler.dispatch(it) } - .onSuccess { view?.updateData(it) } - + }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("License data load started") + Status.SUCCESS -> view?.updateData(it.data!!) + Status.ERROR -> errorHandler.dispatch(it.error!!) + } + }.afterLoading { view?.showProgress(false) - } + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseView.kt index 6c97d875..0680dbb7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/license/LicenseView.kt @@ -5,7 +5,7 @@ import io.github.wulkanowy.ui.base.BaseView interface LicenseView : BaseView { - val appLibraries: List + val appLibraries: ArrayList? fun initView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt similarity index 91% rename from app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt index 5a0e2104..45c304aa 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.debug.logviewer +package io.github.wulkanowy.ui.modules.about.logviewer import android.view.ViewGroup import android.widget.TextView diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt similarity index 85% rename from app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt index 929e7264..cf40975e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt @@ -1,7 +1,12 @@ -package io.github.wulkanowy.ui.modules.debug.logviewer +package io.github.wulkanowy.ui.modules.about.logviewer import android.content.Intent -import android.content.Intent.* +import android.content.Intent.EXTRA_EMAIL +import android.content.Intent.EXTRA_STREAM +import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION +import android.net.Uri +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP import android.os.Bundle import android.view.Menu import android.view.MenuInflater @@ -34,7 +39,6 @@ class LogViewerFragment : BaseFragment(R.layout.fragme fun newInstance() = LogViewerFragment() } - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -77,7 +81,8 @@ class LogViewerFragment : BaseFragment(R.layout.fragme putExtra(EXTRA_EMAIL, arrayOf("wulkanowyinc@gmail.com")) addFlags(FLAG_GRANT_READ_URI_PERMISSION) putParcelableArrayListExtra(EXTRA_STREAM, ArrayList(files.map { - FileProvider.getUriForFile(requireContext(), "$APPLICATION_ID.fileprovider", it) + if (SDK_INT < LOLLIPOP) Uri.fromFile(it) + else FileProvider.getUriForFile(requireContext(), "$APPLICATION_ID.fileprovider", it) })) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt new file mode 100644 index 00000000..85eae8e6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt @@ -0,0 +1,61 @@ +package io.github.wulkanowy.ui.modules.about.logviewer + +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.logger.LoggerRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import javax.inject.Inject + +class LogViewerPresenter @Inject constructor( + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val loggerRepository: LoggerRepository +) : BasePresenter(errorHandler, studentRepository) { + + override fun onAttachView(view: LogViewerView) { + super.onAttachView(view) + view.initView() + loadLogFile() + } + + fun onShareLogsSelected(): Boolean { + flowWithResource { loggerRepository.getLogFiles() }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Loading logs files started") + Status.SUCCESS -> { + Timber.i("Loading logs files result: ${it.data!!.joinToString { file -> file.name }}") + view?.shareLogs(it.data) + } + Status.ERROR -> { + Timber.i("Loading logs files result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.launch("share") + return true + } + + fun onRefreshClick() { + loadLogFile() + } + + private fun loadLogFile() { + flowWithResource { loggerRepository.getLastLogLines() }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Loading last log file started") + Status.SUCCESS -> { + Timber.i("Loading last log file result: load ${it.data!!.size} lines") + view?.setLines(it.data) + } + Status.ERROR -> { + Timber.i("Loading last log file result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.launch("file") + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt similarity index 78% rename from app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt index 3d138ece..bd98c24f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.modules.debug.logviewer +package io.github.wulkanowy.ui.modules.about.logviewer import io.github.wulkanowy.ui.base.BaseView import java.io.File diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt index 523fbbd7..7ecb4139 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt @@ -1,25 +1,23 @@ package io.github.wulkanowy.ui.modules.account import android.annotation.SuppressLint +import android.graphics.PorterDuff import android.view.LayoutInflater import android.view.View.GONE import android.view.View.VISIBLE import android.view.ViewGroup -import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.HeaderAccountBinding import io.github.wulkanowy.databinding.ItemAccountBinding -import io.github.wulkanowy.utils.createNameInitialsDrawable +import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.nickOrName import javax.inject.Inject class AccountAdapter @Inject constructor() : RecyclerView.Adapter() { - var isAccountQuickDialogMode = false - var items = emptyList>() var onClickListener: (StudentWithSemesters) -> Unit = {} @@ -32,76 +30,56 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter HeaderViewHolder( - HeaderAccountBinding.inflate(inflater, parent, false) - ) - AccountItem.ViewType.ITEM.id -> ItemViewHolder( - ItemAccountBinding.inflate(inflater, parent, false) - ) + AccountItem.ViewType.HEADER.id -> HeaderViewHolder(HeaderAccountBinding.inflate(inflater, parent, false)) + AccountItem.ViewType.ITEM.id -> ItemViewHolder(ItemAccountBinding.inflate(inflater, parent, false)) else -> throw IllegalStateException() } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { - is HeaderViewHolder -> bindHeaderViewHolder( - holder.binding, - items[position].value as Account, - position - ) - is ItemViewHolder -> bindItemViewHolder( - holder.binding, - items[position].value as StudentWithSemesters - ) + is HeaderViewHolder -> bindHeaderViewHolder(holder.binding, items[position].value as Account) + is ItemViewHolder -> bindItemViewHolder(holder.binding, items[position].value as StudentWithSemesters) } } - private fun bindHeaderViewHolder( - binding: HeaderAccountBinding, - account: Account, - position: Int - ) { + private fun bindHeaderViewHolder(binding: HeaderAccountBinding, account: Account) { with(binding) { - accountHeaderDivider.visibility = if (position == 0) GONE else VISIBLE accountHeaderEmail.text = account.email accountHeaderType.setText(if (account.isParent) R.string.account_type_parent else R.string.account_type_student) } } @SuppressLint("SetTextI18n") - private fun bindItemViewHolder( - binding: ItemAccountBinding, - studentWithSemesters: StudentWithSemesters - ) { - val context = binding.root.context - val (student, semesters) = studentWithSemesters - val semester = semesters.maxByOrNull { it.semesterId } - val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor) - val checkBackgroundColor = - context.getThemeAttrColor(if (isAccountQuickDialogMode) R.attr.colorBackgroundFloating else R.attr.colorSurface) - val isDuplicatedStudent = items.filter { - if (it.value !is StudentWithSemesters) return@filter false - val studentToCompare = it.value.student - - studentToCompare.studentId == student.studentId - && studentToCompare.schoolSymbol == student.schoolSymbol - && studentToCompare.symbol == student.symbol - }.size > 1 && isAccountQuickDialogMode + private fun bindItemViewHolder(binding: ItemAccountBinding, studentWithSemesters: StudentWithSemesters) { + val student = studentWithSemesters.student + val semesters = studentWithSemesters.semesters + val diary = semesters.maxByOrNull { it.semesterId } with(binding) { - accountItemName.text = "${student.nickOrName} ${semester?.diaryName.orEmpty()}" + accountItemName.text = "${student.studentName} ${diary?.diaryName.orEmpty()}" accountItemSchool.text = studentWithSemesters.student.schoolName - accountItemImage.setImageDrawable(avatar) - - with(accountItemAccountType) { - setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student) - isVisible = isDuplicatedStudent + with(accountItemLoginMode) { + visibility = when (Sdk.Mode.valueOf(student.loginMode)) { + Sdk.Mode.API -> { + setText(R.string.account_login_mobile_api) + VISIBLE + } + Sdk.Mode.HYBRID -> { + setText(R.string.account_login_hybrid) + VISIBLE + } + Sdk.Mode.SCRAPPER -> { + GONE + } + } } - with(accountItemCheck) { - isVisible = student.isCurrent - borderColor = checkBackgroundColor - circleColor = checkBackgroundColor + with(accountItemImage) { + val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary) + else context.getThemeAttrColor(R.attr.colorOnSurface, 153) + + setColorFilter(colorImage, PorterDuff.Mode.SRC_IN) } root.setOnClickListener { onClickListener(studentWithSemesters) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt new file mode 100644 index 00000000..1fa87268 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountDialog.kt @@ -0,0 +1,102 @@ +package io.github.wulkanowy.ui.modules.account + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import android.widget.Toast.LENGTH_LONG +import androidx.appcompat.app.AlertDialog +import androidx.recyclerview.widget.LinearLayoutManager +import dagger.hilt.android.AndroidEntryPoint +import io.github.wulkanowy.R +import io.github.wulkanowy.databinding.DialogAccountBinding +import io.github.wulkanowy.ui.base.BaseDialogFragment +import io.github.wulkanowy.ui.modules.login.LoginActivity +import javax.inject.Inject + +@AndroidEntryPoint +class AccountDialog : BaseDialogFragment(), AccountView { + + @Inject + lateinit var presenter: AccountPresenter + + @Inject + lateinit var accountAdapter: AccountAdapter + + companion object { + fun newInstance() = AccountDialog() + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_TITLE, 0) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogAccountBinding.inflate(inflater).apply { binding = this }.root + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } + + override fun initView() { + accountAdapter.onClickListener = presenter::onItemSelected + + with(binding) { + accountDialogAdd.setOnClickListener { presenter.onAddSelected() } + accountDialogRemove.setOnClickListener { presenter.onRemoveSelected() } + accountDialogRecycler.apply { + layoutManager = LinearLayoutManager(context) + adapter = accountAdapter + } + } + } + + override fun updateData(data: List>) { + with(accountAdapter) { + items = data + notifyDataSetChanged() + } + } + + override fun showError(text: String, error: Throwable) { + showMessage(text) + } + + override fun showMessage(text: String) { + Toast.makeText(context, text, LENGTH_LONG).show() + } + + override fun dismissView() { + dismiss() + } + + override fun openLoginView() { + activity?.let { + startActivity(LoginActivity.getStartIntent(it)) + } + } + + override fun showConfirmDialog() { + context?.let { + AlertDialog.Builder(it) + .setTitle(R.string.account_logout_student) + .setMessage(R.string.account_confirm) + .setPositiveButton(R.string.account_logout) { _, _ -> presenter.onLogoutConfirm() } + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .show() + } + } + + override fun recreateMainView() { + activity?.recreate() + } + + override fun onDestroy() { + presenter.onDetachView() + super.onDestroy() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt deleted file mode 100644 index f115372a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt +++ /dev/null @@ -1,82 +0,0 @@ -package io.github.wulkanowy.ui.modules.account - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.View -import androidx.core.view.get -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.databinding.FragmentAccountBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsFragment -import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import javax.inject.Inject - -@AndroidEntryPoint -class AccountFragment : BaseFragment(R.layout.fragment_account), - AccountView, MainView.TitledView { - - @Inject - lateinit var presenter: AccountPresenter - - @Inject - lateinit var accountAdapter: AccountAdapter - - companion object { - - fun newInstance() = AccountFragment() - } - - override val titleStringId = R.string.account_title - - @Suppress("DEPRECATION") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - @Suppress("UNCHECKED_CAST") - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding = FragmentAccountBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - binding.accountRecycler.apply { - layoutManager = LinearLayoutManager(context) - adapter = accountAdapter - } - - accountAdapter.onClickListener = presenter::onItemSelected - - binding.accountAdd.setOnClickListener { presenter.onAddSelected() } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu[0].isVisible = false - } - - override fun updateData(data: List>) { - with(accountAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun openLoginView() { - activity?.let { - startActivity(LoginActivity.getStartIntent(it)) - } - } - - override fun openAccountDetailsView(student: Student) { - (activity as? MainActivity)?.pushView(AccountDetailsFragment.newInstance(student)) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt index 77c1ffe6..4eaee429 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt @@ -1,25 +1,27 @@ package io.github.wulkanowy.ui.modules.account +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject class AccountPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, + private val syncManager: SyncManager ) : BasePresenter(errorHandler, studentRepository) { override fun onAttachView(view: AccountView) { super.onAttachView(view) view.initView() - Timber.i("Account view was initialized") + Timber.i("Account dialog view was initialized") loadData() } @@ -28,29 +30,86 @@ class AccountPresenter @Inject constructor( view?.openLoginView() } - fun onItemSelected(studentWithSemesters: StudentWithSemesters) { - view?.openAccountDetailsView(studentWithSemesters.student) + fun onRemoveSelected() { + Timber.i("Select remove account") + view?.showConfirmDialog() } - private fun loadData() { - resourceFlow { studentRepository.getSavedStudents(false) } - .logResourceStatus("load account data") - .onResourceSuccess { view?.updateData(createAccountItems(it)) } - .onResourceError(errorHandler::dispatch) - .launch("load") + fun onLogoutConfirm() { + flowWithResource { + val student = studentRepository.getCurrentStudent(false) + studentRepository.logoutStudent(student) + + val students = studentRepository.getSavedStudents(false) + if (students.isNotEmpty()) { + studentRepository.switchStudent(students[0]) + } + students + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Attempt to logout current user ") + Status.SUCCESS -> view?.run { + if (it.data!!.isEmpty()) { + Timber.i("Logout result: Open login view") + syncManager.stopSyncWorker() + openClearLoginView() + } else { + Timber.i("Logout result: Switch to another student") + recreateMainView() + } + } + Status.ERROR -> { + Timber.i("Logout result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.afterLoading { + view?.dismissView() + }.launch("logout") + } + + fun onItemSelected(studentWithSemesters: StudentWithSemesters) { + Timber.i("Select student item ${studentWithSemesters.student.id}") + if (studentWithSemesters.student.isCurrent) { + view?.dismissView() + } else flowWithResource { studentRepository.switchStudent(studentWithSemesters) }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Attempt to change a student") + Status.SUCCESS -> { + Timber.i("Change a student result: Success") + view?.recreateMainView() + } + Status.ERROR -> { + Timber.i("Change a student result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.afterLoading { + view?.dismissView() + }.launch("switch") } private fun createAccountItems(items: List): List> { - return items.groupBy { - Account("${it.student.userName} (${it.student.email})", it.student.isParent) - } - .map { (account, students) -> - listOf( - AccountItem(account, AccountItem.ViewType.HEADER) - ) + students.map { student -> - AccountItem(student, AccountItem.ViewType.ITEM) + return items.groupBy { Account(it.student.email, it.student.isParent) }.map { (account, students) -> + listOf(AccountItem(account, AccountItem.ViewType.HEADER)) + students.map { student -> + AccountItem(student, AccountItem.ViewType.ITEM) + } + }.flatten() + } + + private fun loadData() { + flowWithResource { studentRepository.getSavedStudents(false) }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading account data started") + Status.SUCCESS -> { + Timber.i("Loading account result: Success") + view?.updateData(createAccountItems(it.data!!)) + } + Status.ERROR -> { + Timber.i("Loading account result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .flatten() + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt index 56fcb0a3..a1f8086c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt @@ -1,6 +1,5 @@ package io.github.wulkanowy.ui.modules.account -import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseView interface AccountView : BaseView { @@ -9,7 +8,12 @@ interface AccountView : BaseView { fun updateData(data: List>) + fun dismissView() + + fun showConfirmDialog() + fun openLoginView() - fun openAccountDetailsView(student: Student) + fun recreateMainView() } + diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt deleted file mode 100644 index d6bc6154..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt +++ /dev/null @@ -1,171 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountdetails - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.appcompat.app.AlertDialog -import androidx.core.os.bundleOf -import androidx.core.view.get -import androidx.core.view.isVisible -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.databinding.FragmentAccountDetailsBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.account.accountedit.AccountEditDialog -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoFragment -import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView -import io.github.wulkanowy.utils.createNameInitialsDrawable -import io.github.wulkanowy.utils.nickOrName -import io.github.wulkanowy.utils.serializable -import javax.inject.Inject - -@AndroidEntryPoint -class AccountDetailsFragment : - BaseFragment(R.layout.fragment_account_details), - AccountDetailsView, MainView.TitledView { - - @Inject - lateinit var presenter: AccountDetailsPresenter - - override val titleStringId = R.string.account_details_title - - companion object { - - private const val ARGUMENT_KEY = "Data" - - fun newInstance(student: Student) = AccountDetailsFragment().apply { - arguments = bundleOf(ARGUMENT_KEY to student) - } - } - - @Suppress("DEPRECATION") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentAccountDetailsBinding.bind(view) - presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY)) - } - - override fun initView() { - binding.accountDetailsErrorRetry.setOnClickListener { presenter.onRetry() } - binding.accountDetailsErrorDetails.setOnClickListener { presenter.onDetailsClick() } - binding.accountDetailsLogout.setOnClickListener { presenter.onRemoveSelected() } - binding.accountDetailsSelect.setOnClickListener { presenter.onStudentSelect() } - - binding.accountDetailsPersonalData.setOnClickListener { - presenter.onStudentInfoSelected(StudentInfoView.Type.PERSONAL) - } - binding.accountDetailsAddressData.setOnClickListener { - presenter.onStudentInfoSelected(StudentInfoView.Type.ADDRESS) - } - binding.accountDetailsContactData.setOnClickListener { - presenter.onStudentInfoSelected(StudentInfoView.Type.CONTACT) - } - binding.accountDetailsFamilyData.setOnClickListener { - presenter.onStudentInfoSelected(StudentInfoView.Type.FAMILY) - } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu[0].isVisible = false - inflater.inflate(R.menu.action_menu_account_details, menu) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return if (item.itemId == R.id.accountDetailsMenuEdit) { - presenter.onAccountEditSelected() - true - } else false - } - - override fun showAccountData(student: Student) { - with(binding) { - accountDetailsCheck.isVisible = student.isCurrent - accountDetailsName.text = student.nickOrName - accountDetailsSchool.text = student.schoolName - accountDetailsAvatar.setImageDrawable( - requireContext().createNameInitialsDrawable( - student.nickOrName, - student.avatarColor - ) - ) - } - } - - override fun enableSelectStudentButton(enable: Boolean) { - binding.accountDetailsSelect.isEnabled = enable - } - - override fun showAccountEditDetailsDialog(student: Student) { - (requireActivity() as MainActivity).showDialogFragment( - AccountEditDialog.newInstance(student) - ) - } - - override fun showLogoutConfirmDialog() { - context?.let { - MaterialAlertDialogBuilder(it) - .setTitle(R.string.account_logout_student) - .setMessage(R.string.account_confirm) - .setPositiveButton(R.string.account_logout) { _, _ -> presenter.onLogoutConfirm() } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() - } - } - - override fun popViewToMain() { - (requireActivity() as MainActivity).popView(2) - } - - override fun popViewToAccounts() { - (requireActivity() as MainActivity).popView(1) - } - - override fun recreateMainView() { - requireActivity().recreate() - } - - override fun openStudentInfoView( - infoType: StudentInfoView.Type, - studentWithSemesters: StudentWithSemesters - ) { - (requireActivity() as MainActivity).pushView( - StudentInfoFragment.newInstance( - infoType, - studentWithSemesters - ) - ) - } - - override fun showErrorView(show: Boolean) { - binding.accountDetailsError.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun setErrorDetails(message: String) { - binding.accountDetailsErrorMessage.text = message - } - - override fun showProgress(show: Boolean) { - binding.accountDetailsProgress.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showContent(show: Boolean) { - binding.accountDetailsContent.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsPresenter.kt deleted file mode 100644 index 5d68ff2e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsPresenter.kt +++ /dev/null @@ -1,156 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountdetails - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.services.sync.SyncManager -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView -import timber.log.Timber -import javax.inject.Inject - -class AccountDetailsPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val syncManager: SyncManager -) : BasePresenter(errorHandler, studentRepository) { - - private var studentWithSemesters: StudentWithSemesters? = null - - private lateinit var lastError: Throwable - - private var studentId: Long? = null - - fun onAttachView(view: AccountDetailsView, student: Student) { - super.onAttachView(view) - studentId = student.id - - view.initView() - errorHandler.showErrorMessage = ::showErrorViewOnError - Timber.i("Account details view was initialized") - loadData() - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData() - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - private fun loadData() { - resourceFlow { studentRepository.getSavedStudentById(studentId ?: -1) } - .logResourceStatus("loading account details view") - .onResourceLoading { - view?.run { - showProgress(true) - showContent(false) - } - } - .onResourceSuccess { - studentWithSemesters = it - view?.run { - showAccountData(studentWithSemesters!!.student) - enableSelectStudentButton(!studentWithSemesters!!.student.isCurrent) - showContent(true) - showErrorView(false) - } - } - .onResourceNotLoading { view?.showProgress(false) } - .onResourceError(errorHandler::dispatch) - .launch() - } - - fun onAccountEditSelected() { - studentWithSemesters?.let { - view?.showAccountEditDetailsDialog(it.student) - } - } - - fun onStudentInfoSelected(infoType: StudentInfoView.Type) { - studentWithSemesters?.let { - view?.openStudentInfoView(infoType, it) - } - } - - fun onStudentSelect() { - if (studentWithSemesters == null) return - - Timber.i("Select student ${studentWithSemesters!!.student.id}") - - resourceFlow { studentRepository.switchStudent(studentWithSemesters!!) } - .logResourceStatus("change student") - .onResourceSuccess { view?.recreateMainView() } - .onResourceNotLoading { view?.popViewToMain() } - .onResourceError(errorHandler::dispatch) - .launch("switch") - } - - fun onRemoveSelected() { - Timber.i("Select remove account") - view?.showLogoutConfirmDialog() - } - - fun onLogoutConfirm() { - if (studentWithSemesters == null) return - - resourceFlow { - val studentToLogout = studentWithSemesters!!.student - - studentRepository.logoutStudent(studentToLogout) - val students = studentRepository.getSavedStudents(false) - - if (studentToLogout.isCurrent && students.isNotEmpty()) { - studentRepository.switchStudent(students[0]) - } - - students - } - .logResourceStatus("logout user") - .onResourceSuccess { - view?.run { - when { - it.isEmpty() -> { - Timber.i("Logout result: Open login view") - syncManager.stopSyncWorker() - openClearLoginView() - } - studentWithSemesters?.student?.isCurrent == true -> { - Timber.i("Logout result: Logout student and switch to another") - recreateMainView() - } - else -> { - Timber.i("Logout result: Logout student") - recreateMainView() - } - } - } - } - .onResourceNotLoading { - if (studentWithSemesters?.student?.isCurrent == true) { - view?.popViewToMain() - } else { - view?.popViewToAccounts() - } - } - .onResourceError(errorHandler::dispatch) - .launch("logout") - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - lastError = error - setErrorDetails(message) - showErrorView(true) - showContent(false) - showProgress(false) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsView.kt deleted file mode 100644 index aeb743fa..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsView.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountdetails - -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView - -interface AccountDetailsView : BaseView { - - fun initView() - - fun showAccountData(student: Student) - - fun showAccountEditDetailsDialog(student: Student) - - fun showLogoutConfirmDialog() - - fun popViewToMain() - - fun popViewToAccounts() - - fun recreateMainView() - - fun enableSelectStudentButton(enable: Boolean) - - fun openStudentInfoView( - infoType: StudentInfoView.Type, - studentWithSemesters: StudentWithSemesters - ) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun showProgress(show: Boolean) - - fun showContent(show: Boolean) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditColorAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditColorAdapter.kt deleted file mode 100644 index 66e39fc7..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditColorAdapter.kt +++ /dev/null @@ -1,70 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountedit - -import android.annotation.SuppressLint -import android.content.res.ColorStateList -import android.graphics.Color -import android.graphics.drawable.Drawable -import android.graphics.drawable.GradientDrawable -import android.graphics.drawable.RippleDrawable -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.databinding.ItemAccountEditColorBinding -import javax.inject.Inject - -class AccountEditColorAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = listOf() - - var selectedColor = 0 - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemAccountEditColorBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - @SuppressLint("RestrictedApi", "NewApi") - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - accountEditItemColor.setImageDrawable(GradientDrawable().apply { - shape = GradientDrawable.OVAL - setColor(item) - }) - - accountEditItemColorContainer.foreground = item.createForegroundDrawable() - accountEditCheck.isVisible = selectedColor == item - - root.setOnClickListener { - val oldSelectedPosition = items.indexOf(selectedColor) - selectedColor = item - - notifyItemChanged(oldSelectedPosition) - notifyItemChanged(position) - } - } - } - - private fun Int.createForegroundDrawable(): Drawable { - val mask = GradientDrawable().apply { - shape = GradientDrawable.OVAL - setColor(Color.BLACK) - } - return RippleDrawable(ColorStateList.valueOf(this.rippleColor), null, mask) - } - - private inline val Int.rippleColor: Int - get() { - val hsv = FloatArray(3) - Color.colorToHSV(this, hsv) - hsv[2] = hsv[2] * 0.5f - return Color.HSVToColor(hsv) - } - - class ViewHolder(val binding: ItemAccountEditColorBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt deleted file mode 100644 index 4229579c..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt +++ /dev/null @@ -1,93 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountedit - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.recyclerview.widget.GridLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.databinding.DialogAccountEditBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.serializable -import javax.inject.Inject - -@AndroidEntryPoint -class AccountEditDialog : BaseDialogFragment(), AccountEditView { - - @Inject - lateinit var presenter: AccountEditPresenter - - @Inject - lateinit var accountEditColorAdapter: AccountEditColorAdapter - - companion object { - - private const val ARGUMENT_KEY = "student_with_semesters" - - fun newInstance(student: Student) = AccountEditDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to student) - } - } - - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogAccountEditBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY)) - } - - override fun initView() { - with(binding) { - accountEditDetailsCancel.setOnClickListener { dismiss() } - accountEditDetailsSave.setOnClickListener { - presenter.changeStudentNickAndAvatar( - binding.accountEditDetailsNickText.text.toString(), - accountEditColorAdapter.selectedColor - ) - } - - with(binding.accountEditColors) { - layoutManager = GridLayoutManager(context, 4) - adapter = accountEditColorAdapter - } - } - } - - override fun updateSelectedColorData(color: Int) { - with(accountEditColorAdapter) { - selectedColor = color - notifyDataSetChanged() - } - } - - override fun updateColorsData(colors: List) { - with(accountEditColorAdapter) { - items = colors - notifyDataSetChanged() - } - } - - override fun showCurrentNick(nick: String) { - binding.accountEditDetailsNickText.setText(nick) - } - - override fun popView() { - dismiss() - } - - override fun recreateMainView() { - activity?.recreate() - } - - override fun onDestroyView() { - super.onDestroyView() - presenter.onDetachView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditPresenter.kt deleted file mode 100644 index c401158e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditPresenter.kt +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountedit - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AppInfo -import timber.log.Timber -import javax.inject.Inject - -class AccountEditPresenter @Inject constructor( - appInfo: AppInfo, - errorHandler: ErrorHandler, - studentRepository: StudentRepository -) : BasePresenter(errorHandler, studentRepository) { - - lateinit var student: Student - - private val colors = appInfo.defaultColorsForAvatar.map { it.toInt() } - - fun onAttachView(view: AccountEditView, student: Student) { - super.onAttachView(view) - this.student = student - - with(view) { - initView() - showCurrentNick(student.nick.trim()) - } - Timber.i("Account edit dialog view was initialized") - loadData() - - view.updateColorsData(colors) - } - - private fun loadData() { - resourceFlow { studentRepository.getStudentById(student.id, false).avatarColor } - .logResourceStatus("load student") - .onResourceSuccess { view?.updateSelectedColorData(it.toInt()) } - .onResourceError(errorHandler::dispatch) - .launch("load_data") - } - - fun changeStudentNickAndAvatar(nick: String, avatarColor: Int) { - resourceFlow { - val studentNick = StudentNickAndAvatar( - nick = nick.trim(), - avatarColor = avatarColor.toLong() - ).apply { id = student.id } - - studentRepository.updateStudentNickAndAvatar(studentNick) - } - .logResourceStatus("change student nick and avatar") - .onResourceSuccess { view?.recreateMainView() } - .onResourceNotLoading { view?.popView() } - .onResourceError(errorHandler::dispatch) - .launch("update_student") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditView.kt deleted file mode 100644 index 517492de..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditView.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountedit - -import io.github.wulkanowy.ui.base.BaseView - -interface AccountEditView : BaseView { - - fun initView() - - fun popView() - - fun recreateMainView() - - fun showCurrentNick(nick: String) - - fun updateSelectedColorData(color: Int) - - fun updateColorsData(colors: List) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt deleted file mode 100644 index 2d2dccec..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt +++ /dev/null @@ -1,93 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountquick - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.databinding.DialogAccountQuickBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.ui.modules.account.AccountAdapter -import io.github.wulkanowy.ui.modules.account.AccountFragment -import io.github.wulkanowy.ui.modules.account.AccountItem -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.utils.serializable -import javax.inject.Inject - -@AndroidEntryPoint -class AccountQuickDialog : BaseDialogFragment(), AccountQuickView { - - @Inject - lateinit var accountAdapter: AccountAdapter - - @Inject - lateinit var presenter: AccountQuickPresenter - - companion object { - - private const val STUDENTS_ARGUMENT_KEY = "students" - - fun newInstance(studentsWithSemesters: List) = - AccountQuickDialog().apply { - arguments = bundleOf(STUDENTS_ARGUMENT_KEY to studentsWithSemesters.toTypedArray()) - } - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogAccountQuickBinding.inflate(layoutInflater) - .apply { binding = this }.root - ) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - val studentsWithSemesters = requireArguments() - .serializable>(STUDENTS_ARGUMENT_KEY).toList() - - presenter.onAttachView(this, studentsWithSemesters) - } - - override fun initView() { - binding.accountQuickDialogManger.setOnClickListener { presenter.onManagerSelected() } - - with(accountAdapter) { - isAccountQuickDialogMode = true - onClickListener = presenter::onStudentSelect - } - - with(binding.accountQuickDialogRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = accountAdapter - } - } - - override fun updateData(data: List>) { - with(accountAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun popView() { - dismiss() - } - - override fun recreateMainView() { - activity?.recreate() - } - - override fun openAccountView() { - (requireActivity() as MainActivity).pushView(AccountFragment.newInstance()) - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickPresenter.kt deleted file mode 100644 index 32c07f80..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickPresenter.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountquick - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.account.AccountItem -import timber.log.Timber -import javax.inject.Inject - -class AccountQuickPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var studentsWithSemesters: List - - fun onAttachView(view: AccountQuickView, studentsWithSemesters: List) { - super.onAttachView(view) - this.studentsWithSemesters = studentsWithSemesters - - view.initView() - Timber.i("Account quick dialog view was initialized") - view.updateData(createAccountItems(studentsWithSemesters)) - } - - fun onManagerSelected() { - view?.run { - openAccountView() - popView() - } - } - - fun onStudentSelect(studentWithSemesters: StudentWithSemesters) { - Timber.i("Select student ${studentWithSemesters.student.id}") - - if (studentWithSemesters.student.isCurrent) { - view?.popView() - return - } - - resourceFlow { studentRepository.switchStudent(studentWithSemesters) } - .logResourceStatus("change student") - .onResourceSuccess { view?.recreateMainView() } - .onResourceNotLoading { view?.popView() } - .onResourceError(errorHandler::dispatch) - .launch("switch") - } - - private fun createAccountItems(items: List) = items.map { - AccountItem(it, AccountItem.ViewType.ITEM) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickView.kt deleted file mode 100644 index 4a9420d9..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickView.kt +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.wulkanowy.ui.modules.account.accountquick - -import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.account.AccountItem - -interface AccountQuickView : BaseView { - - fun initView() - - fun updateData(data: List>) - - fun recreateMainView() - - fun popView() - - fun openAccountView() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt index f5689ec8..8e8a6149 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceAdapter.kt @@ -1,7 +1,5 @@ package io.github.wulkanowy.ui.modules.attendance -import android.content.res.ColorStateList -import android.graphics.Typeface import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -9,11 +7,9 @@ import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.data.enums.SentExcuseStatus +import io.github.wulkanowy.data.repositories.attendance.SentExcuseStatus import io.github.wulkanowy.databinding.ItemAttendanceBinding -import io.github.wulkanowy.utils.descriptionRes -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.isExcusableOrNotExcused +import io.github.wulkanowy.utils.description import javax.inject.Inject class AttendanceAdapter @Inject constructor() : @@ -34,43 +30,13 @@ class AttendanceAdapter @Inject constructor() : ) override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val context = holder.binding.root.context val item = items[position] with(holder.binding) { attendanceItemNumber.text = item.number.toString() attendanceItemSubject.text = item.subject - .ifBlank { context.getString(R.string.all_no_data) } - attendanceItemDescription.setText(item.descriptionRes) - - attendanceItemDescription.setTextColor( - context.getThemeAttrColor( - when { - item.absence && !item.excused -> R.attr.colorAttendanceAbsence - item.lateness && !item.excused -> R.attr.colorAttendanceLateness - else -> android.R.attr.textColorSecondary - } - ) - ) - - if (item.exemption || item.excused) { - attendanceItemDescription.setTypeface(null, Typeface.BOLD) - } else { - attendanceItemDescription.setTypeface(null, Typeface.NORMAL) - } - - attendanceItemAlert.isVisible = - item.let { (it.absence && !it.excused) || (it.lateness && !it.excused) } - - attendanceItemAlert.imageTintList = ColorStateList.valueOf( - context.getThemeAttrColor( - when { - item.absence && !item.excused -> R.attr.colorAttendanceAbsence - item.lateness && !item.excused -> R.attr.colorAttendanceLateness - else -> android.R.attr.colorPrimary - } - ) - ) + attendanceItemDescription.setText(item.description) + attendanceItemAlert.visibility = item.run { if (absence && !excused) View.VISIBLE else View.INVISIBLE } attendanceItemNumber.visibility = View.GONE attendanceItemExcuseInfo.visibility = View.GONE attendanceItemExcuseCheckbox.visibility = View.GONE @@ -79,20 +45,18 @@ class AttendanceAdapter @Inject constructor() : onExcuseCheckboxSelect(item, checked) } - when (item.excuseStatus?.let { SentExcuseStatus.valueOf(it) }) { + when (if (item.excuseStatus != null) SentExcuseStatus.valueOf(item.excuseStatus) else null) { SentExcuseStatus.WAITING -> { attendanceItemExcuseInfo.setImageResource(R.drawable.ic_excuse_waiting) attendanceItemExcuseInfo.visibility = View.VISIBLE attendanceItemAlert.visibility = View.INVISIBLE } - SentExcuseStatus.DENIED -> { attendanceItemExcuseInfo.setImageResource(R.drawable.ic_excuse_denied) attendanceItemExcuseInfo.visibility = View.VISIBLE } - else -> { - if (item.isExcusableOrNotExcused && excuseActionMode) { + if (item.excusable && excuseActionMode) { attendanceItemNumber.visibility = View.GONE attendanceItemExcuseCheckbox.visibility = View.VISIBLE } else { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt index 63503313..d5e2fe12 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt @@ -1,63 +1,52 @@ package io.github.wulkanowy.ui.modules.attendance -import android.app.Dialog import android.os.Bundle +import android.view.LayoutInflater import android.view.View -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.databinding.DialogAttendanceBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.descriptionRes -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.serializable +import io.github.wulkanowy.utils.description +import io.github.wulkanowy.utils.lifecycleAwareVariable import io.github.wulkanowy.utils.toFormattedString -@AndroidEntryPoint -class AttendanceDialog : BaseDialogFragment() { +class AttendanceDialog : DialogFragment() { + + private var binding: DialogAttendanceBinding by lifecycleAwareVariable() private lateinit var attendance: Attendance companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(exam: Attendance) = AttendanceDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to exam) + fun newInstance(exam: Attendance): AttendanceDialog { + return AttendanceDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - attendance = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + attendance = getSerializable(ARGUMENT_KEY) as Attendance + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogAttendanceBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogAttendanceBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(binding) { - attendanceDialogSubjectValue.text = attendance.subject - attendanceDialogDescriptionValue.setText(attendance.descriptionRes) - attendanceDialogDescriptionValue.setTextColor( - root.context.getThemeAttrColor( - when { - attendance.absence && !attendance.excused -> R.attr.colorAttendanceAbsence - attendance.lateness && !attendance.excused -> R.attr.colorAttendanceLateness - else -> android.R.attr.textColorSecondary - } - ) - ) - - attendanceDialogDateValue.text = attendance.date.toFormattedString() - attendanceDialogNumberValue.text = attendance.number.toString() + attendanceDialogSubject.text = attendance.subject + attendanceDialogDescription.setText(attendance.description) + attendanceDialogDate.text = attendance.date.toFormattedString() + attendanceDialogNumber.text = attendance.number.toString() attendanceDialogClose.setOnClickListener { dismiss() } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt index 07649e43..c7caef06 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt @@ -2,34 +2,35 @@ package io.github.wulkanowy.ui.modules.attendance import android.content.DialogInterface.BUTTON_POSITIVE import android.os.Bundle -import android.view.* -import android.view.View.* +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE +import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ActionMode -import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.databinding.DialogExcuseBinding import io.github.wulkanowy.databinding.FragmentAttendanceBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.attendance.calculator.AttendanceCalculatorFragment import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.widgets.DividerItemDecoration +import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.openMaterialDatePicker import java.time.LocalDate import javax.inject.Inject @AndroidEntryPoint -class AttendanceFragment : BaseFragment(R.layout.fragment_attendance), - AttendanceView, MainView.MainChildView, +class AttendanceFragment : BaseFragment(R.layout.fragment_attendance), AttendanceView, MainView.MainChildView, MainView.TitledView { @Inject @@ -59,11 +60,10 @@ class AttendanceFragment : BaseFragment(R.layout.frag override val excuseActionMode: Boolean get() = attendanceAdapter.excuseActionMode private var actionMode: ActionMode? = null - private val actionModeCallback = object : ActionMode.Callback { override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { val inflater = mode.menuInflater - inflater.inflate(R.menu.context_menu_attendance, menu) + inflater.inflate(R.menu.context_menu_excuse, menu) return true } @@ -85,7 +85,6 @@ class AttendanceFragment : BaseFragment(R.layout.frag } } - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -112,10 +111,6 @@ class AttendanceFragment : BaseFragment(R.layout.frag with(binding) { attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - attendanceSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - attendanceSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) attendanceErrorRetry.setOnClickListener { presenter.onRetry() } attendanceErrorDetails.setOnClickListener { presenter.onDetailsClick() } @@ -125,7 +120,7 @@ class AttendanceFragment : BaseFragment(R.layout.frag attendanceExcuseButton.setOnClickListener { presenter.onExcuseButtonClick() } - attendanceNavContainer.elevation = requireContext().dpToPx(3f) + attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } } @@ -135,7 +130,6 @@ class AttendanceFragment : BaseFragment(R.layout.frag override fun onOptionsItemSelected(item: MenuItem): Boolean { return if (item.itemId == R.id.attendanceMenuSummary) presenter.onSummarySwitchSelected() - else if (item.itemId == R.id.attendanceMenuCalculator) presenter.onCalculatorSwitchSelected() else false } @@ -150,10 +144,6 @@ class AttendanceFragment : BaseFragment(R.layout.frag binding.attendanceNavDate.text = date } - override fun showNavigation(show: Boolean) { - binding.attendanceNavContainer.isVisible = show - } - override fun clearData() { with(attendanceAdapter) { items = emptyList() @@ -198,11 +188,11 @@ class AttendanceFragment : BaseFragment(R.layout.frag } override fun showContent(show: Boolean) { - binding.attendanceRecycler.visibility = if (show) VISIBLE else GONE + binding. attendanceRecycler.visibility = if (show) VISIBLE else GONE } - override fun showRefresh(show: Boolean) { - binding.attendanceSwipe.isRefreshing = show + override fun hideRefresh() { + binding.attendanceSwipe.isRefreshing = false } override fun showPreButton(show: Boolean) { @@ -210,43 +200,42 @@ class AttendanceFragment : BaseFragment(R.layout.frag } override fun showNextButton(show: Boolean) { - binding.attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE + binding. attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE } override fun showExcuseButton(show: Boolean) { - binding.attendanceExcuseButton.isVisible = show + binding.attendanceExcuseButton.visibility = if (show) VISIBLE else GONE } override fun showAttendanceDialog(lesson: Attendance) { (activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson)) } - override fun showDatePickerDialog(selectedDate: LocalDate) { - openMaterialDatePicker( - selected = selectedDate, - rangeStart = selectedDate.firstSchoolDayInSchoolYear, - rangeEnd = LocalDate.now().plusWeeks(1), - onDateSelected = { - presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth) - } - ) + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) + + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@AttendanceFragment.parentFragmentManager, null) + } } override fun showExcuseDialog() { val dialogBinding = DialogExcuseBinding.inflate(LayoutInflater.from(context)) - MaterialAlertDialogBuilder(requireContext()) + AlertDialog.Builder(requireContext()) .setTitle(R.string.attendance_excuse_title) .setView(dialogBinding.root) .setNegativeButton(android.R.string.cancel) { _, _ -> } .create() .apply { - setButton( - BUTTON_POSITIVE, - getString(R.string.attendance_excuse_dialog_submit) - ) { _, _ -> - presenter.onExcuseDialogSubmit( - dialogBinding.excuseReason.text?.toString().orEmpty() - ) + setButton(BUTTON_POSITIVE, getString(R.string.attendance_excuse_dialog_submit)) { _, _ -> + presenter.onExcuseDialogSubmit(dialogBinding.excuseReason.text?.toString().orEmpty()) } }.show() } @@ -255,45 +244,24 @@ class AttendanceFragment : BaseFragment(R.layout.frag (activity as? MainActivity)?.pushView(AttendanceSummaryFragment.newInstance()) } - override fun openCalculatorView() { - (activity as? MainActivity)?.pushView(AttendanceCalculatorFragment.newInstance()) - } - override fun startActionMode() { actionMode = (activity as MainActivity?)?.startSupportActionMode(actionModeCallback) } - override fun startSendMessageIntent(date: LocalDate, numbers: String, reason: String) { - val reasonFullText = getString( - R.string.attendance_excuse_formula, - date, - numbers, - if (reason.isNotBlank()) " ${getString(R.string.attendance_excuse_reason)} " else "", - reason.ifBlank { "" } - ) - startActivity(SendMessageActivity.getStartIntent(requireContext(), reasonFullText)) - } - override fun showExcuseCheckboxes(show: Boolean) { - with(attendanceAdapter) { + attendanceAdapter.apply { excuseActionMode = show notifyDataSetChanged() } } - override fun showDayNavigation(show: Boolean) { - binding.attendanceNavContainer.isVisible = show - } - override fun finishActionMode() { actionMode?.finish() } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - presenter.currentDate?.let { - outState.putLong(SAVED_DATE_KEY, it.toEpochDay()) - } + outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt index 586a41ad..19f8523d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt @@ -1,40 +1,28 @@ package io.github.wulkanowy.ui.modules.attendance import android.annotation.SuppressLint -import io.github.wulkanowy.data.Resource +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Attendance -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.mapResourceData -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceIntermediate -import io.github.wulkanowy.data.onResourceLoading -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.AttendanceRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.capitalise +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday -import io.github.wulkanowy.utils.isExcusableOrNotExcused import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousOrSameSchoolDay import io.github.wulkanowy.utils.previousSchoolDay -import io.github.wulkanowy.utils.sunday import io.github.wulkanowy.utils.toFormattedString -import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach import timber.log.Timber -import java.time.DayOfWeek import java.time.LocalDate import java.time.LocalDate.now import java.time.LocalDate.ofEpochDay @@ -49,61 +37,51 @@ class AttendancePresenter @Inject constructor( private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { - private var initialDate: LocalDate? = null - private var isWeekendHasLessons: Boolean = false + private var baseDate: LocalDate = now().previousOrSameSchoolDay - var currentDate: LocalDate? = null + lateinit var currentDate: LocalDate private set private lateinit var lastError: Throwable private val attendanceToExcuseList = mutableListOf() - private var isVulcanExcusedFunctionEnabled = false - fun onAttachView(view: AttendanceView, date: Long?) { super.onAttachView(view) view.initView() Timber.i("Attendance view was initialized") errorHandler.showErrorMessage = ::showErrorViewOnError - currentDate = date?.let(::ofEpochDay) - loadData() + loadData(ofEpochDay(date ?: baseDate.toEpochDay())) + if (currentDate.isHolidays) setBaseDateOnHolidays() + reloadView() } fun onPreviousDay() { - val date = if (isWeekendHasLessons) { - currentDate?.minusDays(1) - } else currentDate?.previousSchoolDay - view?.finishActionMode() attendanceToExcuseList.clear() - reloadView(date ?: return) - loadData() + loadData(currentDate.previousSchoolDay) + reloadView() } fun onNextDay() { - val date = if (isWeekendHasLessons) { - currentDate?.plusDays(1) - } else currentDate?.nextSchoolDay - view?.finishActionMode() attendanceToExcuseList.clear() - reloadView(date ?: return) - loadData() + loadData(currentDate.nextSchoolDay) + reloadView() } fun onPickDate() { - view?.showDatePickerDialog(currentDate ?: return) + view?.showDatePickerDialog(currentDate) } fun onDateSet(year: Int, month: Int, day: Int) { - reloadView(LocalDate.of(year, month, day)) - loadData() + loadData(LocalDate.of(year, month, day)) + reloadView() } fun onSwipeRefresh() { Timber.i("Force refreshing the attendance") - loadData(true) + loadData(currentDate, true) } fun onRetry() { @@ -111,7 +89,7 @@ class AttendancePresenter @Inject constructor( showErrorView(false) showProgress(true) } - loadData(true) + loadData(currentDate, true) } fun onDetailsClick() { @@ -120,17 +98,15 @@ class AttendancePresenter @Inject constructor( fun onViewReselected() { Timber.i("Attendance view is reselected") - view?.let { view -> + view?.also { view -> if (view.currentStackSize == 1) { - if (currentDate != initialDate) { - reloadView(initialDate ?: return) - loadData() - } else if (!view.isViewEmpty) { - view.resetView() + baseDate.also { + if (currentDate != it) { + loadData(it) + reloadView() + } else if (!view.isViewEmpty) view.resetView() } - } else { - view.popView() - } + } else view.popView() } } @@ -171,31 +147,13 @@ class AttendancePresenter @Inject constructor( fun onExcuseDialogSubmit(reason: String) { view?.finishActionMode() - - if (attendanceToExcuseList.isEmpty()) return - - if (isVulcanExcusedFunctionEnabled) { - excuseAbsence( - reason = reason.takeIf { it.isNotBlank() }, - toExcuseList = attendanceToExcuseList.toList() - ) - } else { - val attendanceToExcuseNumbers = attendanceToExcuseList.map { it.number } - - view?.startSendMessageIntent( - date = attendanceToExcuseList[0].date, - numbers = attendanceToExcuseNumbers.joinToString(", "), - reason = reason - ) - } + excuseAbsence(if (reason != "") reason else null, attendanceToExcuseList.toList()) } fun onPrepareActionMode(): Boolean { view?.apply { showExcuseCheckboxes(true) showExcuseButton(false) - enableSwipe(false) - showDayNavigation(false) } attendanceToExcuseList.clear() return true @@ -205,8 +163,6 @@ class AttendancePresenter @Inject constructor( view?.apply { showExcuseCheckboxes(false) showExcuseButton(true) - enableSwipe(true) - showDayNavigation(true) } } @@ -215,128 +171,76 @@ class AttendancePresenter @Inject constructor( return true } - fun onCalculatorSwitchSelected(): Boolean { - view?.openCalculatorView() - return true - } - - private fun loadData(forceRefresh: Boolean = false) { - Timber.i("Loading attendance data started") - - var isParent = false - - flatResourceFlow { + private fun setBaseDateOnHolidays() { + flow { val student = studentRepository.getCurrentStudent() - isParent = student.isParent + emit(semesterRepository.getCurrentSemester(student)) + }.catch { + Timber.i("Loading semester result: An exception occurred") + }.onEach { + baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) + currentDate = baseDate + reloadNavigation() + }.launch("holidays") + } + private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { + Timber.i("Loading attendance data started") + currentDate = date + + flowWithResourceIn { + val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - - checkInitialAndCurrentDate(semester) - attendanceRepository.getAttendance( - student = student, - semester = semester, - start = currentDate ?: now(), - end = currentDate ?: now(), - forceRefresh = forceRefresh - ) - } - .logResourceStatus("load attendance") - .onResourceLoading { - view?.showExcuseButton(false) - } - .mapResourceData { - if (prefRepository.isShowPresent) { - it - } else { - it.filter { item -> !item.presence } - }.sortedBy { item -> item.number } - } - .onResourceData { - isWeekendHasLessons = isWeekendHasLessons || isWeekendHasLessons(it) - - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showEmpty(it.isEmpty()) - showContent(it.isNotEmpty()) - updateData(it) - reloadNavigation() + attendanceRepository.getAttendance(student, semester, date, date, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> view?.showExcuseButton(false) + Status.SUCCESS -> { + Timber.i("Loading attendance result: Success") + view?.apply { + updateData(it.data!!.let { items -> + if (prefRepository.isShowPresent) items + else items.filter { item -> !item.presence } + }.sortedBy { item -> item.number }) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) + showExcuseButton(it.data.any { item -> item.excusable }) + } + analytics.logEvent( + "load_data", + "type" to "attendance", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading attendance result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - isVulcanExcusedFunctionEnabled = it.any { item -> item.excusable } - val anyExcusables = it.any { it.isExcusableOrNotExcused } - view?.showExcuseButton(anyExcusables && (isParent || isVulcanExcusedFunctionEnabled)) - - analytics.logEvent( - "load_data", - "type" to "attendance", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - showRefresh(false) - showProgress(false) - enableSwipe(true) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private suspend fun checkInitialAndCurrentDate(semester: Semester) { - if (initialDate == null) { - val lessons = attendanceRepository.getAttendanceFromDatabase( - semester = semester, - start = now().monday, - end = now().sunday, - ).firstOrNull().orEmpty() - isWeekendHasLessons = isWeekendHasLessons(lessons) - initialDate = getInitialDate(semester) - } - - if (currentDate == null) { - currentDate = initialDate - } - } - - private fun isWeekendHasLessons( - lessons: List, - ): Boolean = lessons.any { - it.date.dayOfWeek in listOf( - DayOfWeek.SATURDAY, - DayOfWeek.SUNDAY, - ) - } - - private fun getInitialDate(semester: Semester): LocalDate { - val now = now() - - return when { - now.isHolidays -> now.getLastSchoolDayIfHoliday(semester.schoolYear) - isWeekendHasLessons -> now - else -> now.previousOrSameSchoolDay - } + }.launch() } private fun excuseAbsence(reason: String?, toExcuseList: List) { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) attendanceRepository.excuseForAbsence(student, semester, toExcuseList, reason) }.onEach { - when (it) { - is Resource.Loading -> view?.run { + when (it.status) { + Status.LOADING -> view?.run { Timber.i("Excusing absence started") showProgress(true) showContent(false) showExcuseButton(false) } - - is Resource.Success -> { + Status.SUCCESS -> { Timber.i("Excusing for absence result: Success") analytics.logEvent("excuse_absence", "items" to attendanceToExcuseList.size) attendanceToExcuseList.clear() @@ -346,13 +250,12 @@ class AttendancePresenter @Inject constructor( showContent(true) showProgress(false) } - loadData(forceRefresh = true) + loadData(currentDate, forceRefresh = true) } - - is Resource.Error -> { + Status.ERROR -> { Timber.i("Excusing for absence result: An exception occurred") - errorHandler.dispatch(it.error) - loadData() + errorHandler.dispatch(it.error!!) + loadData(currentDate) } } }.launch("excuse") @@ -369,14 +272,11 @@ class AttendancePresenter @Inject constructor( } } - private fun reloadView(date: LocalDate) { - currentDate = date - - Timber.i("Reload attendance view with the date ${currentDate?.toFormattedString()}") + private fun reloadView() { + Timber.i("Reload attendance view with the date ${currentDate.toFormattedString()}") view?.apply { showProgress(true) enableSwipe(false) - showRefresh(false) showContent(false) showEmpty(false) showErrorView(false) @@ -387,13 +287,10 @@ class AttendancePresenter @Inject constructor( @SuppressLint("DefaultLocale") private fun reloadNavigation() { - val currentDate = currentDate ?: return - view?.apply { showPreButton(!currentDate.minusDays(1).isHolidays) showNextButton(!currentDate.plusDays(1).isHolidays) - updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalise()) - showNavigation(true) + updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalize()) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt index f51ce7c7..d54fb8bf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt @@ -24,7 +24,7 @@ interface AttendanceView : BaseView { fun clearData() - fun showRefresh(show: Boolean) + fun hideRefresh() fun resetView() @@ -40,8 +40,6 @@ interface AttendanceView : BaseView { fun showContent(show: Boolean) - fun showNavigation(show: Boolean) - fun showPreButton(show: Boolean) fun showNextButton(show: Boolean) @@ -50,22 +48,16 @@ interface AttendanceView : BaseView { fun showAttendanceDialog(lesson: Attendance) - fun showDatePickerDialog(selectedDate: LocalDate) + fun showDatePickerDialog(currentDate: LocalDate) fun showExcuseDialog() fun openSummaryView() - fun openCalculatorView() - - fun startSendMessageIntent(date: LocalDate, numbers: String, reason: String) - fun startActionMode() fun showExcuseCheckboxes(show: Boolean) - fun showDayNavigation(show: Boolean) - fun finishActionMode() fun popView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorAdapter.kt deleted file mode 100644 index 4b908bba..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorAdapter.kt +++ /dev/null @@ -1,67 +0,0 @@ -package io.github.wulkanowy.ui.modules.attendance.calculator - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.pojos.AttendanceData -import io.github.wulkanowy.databinding.ItemAttendanceCalculatorHeaderBinding -import javax.inject.Inject -import kotlin.math.abs -import kotlin.math.roundToInt - -class AttendanceCalculatorAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemAttendanceCalculatorHeaderBinding.inflate( - LayoutInflater.from(parent.context), parent, false - ) - ) - - override fun onBindViewHolder(parent: ViewHolder, position: Int) { - val context = parent.binding.root.context - val item = items[position] - - with(parent.binding) { - attendanceCalculatorPercentage.text = "${item.presencePercentage.roundToInt()}" - - attendanceCalculatorSummaryBalance.text = when { - item.lessonBalance > 0 -> { - context.getString( - R.string.attendance_calculator_summary_balance_positive, - item.lessonBalance - ) - } - - item.lessonBalance < 0 -> { - context.getString( - R.string.attendance_calculator_summary_balance_negative, - abs(item.lessonBalance) - ) - } - - else -> context.getString(R.string.attendance_calculator_summary_balance_neutral) - } - attendanceCalculatorWarning.isVisible = item.lessonBalance < 0 - attendanceCalculatorTitle.text = item.subjectName - attendanceCalculatorSummaryValues.text = if (item.total == 0) { - context.getString(R.string.attendance_calculator_summary_values_empty) - } else { - context.getString( - R.string.attendance_calculator_summary_values, - item.presences, - item.total - ) - } - } - } - - class ViewHolder(val binding: ItemAttendanceCalculatorHeaderBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorFragment.kt deleted file mode 100644 index 63d1d8be..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorFragment.kt +++ /dev/null @@ -1,133 +0,0 @@ -package io.github.wulkanowy.ui.modules.attendance.calculator - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.core.view.isVisible -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.pojos.AttendanceData -import io.github.wulkanowy.databinding.FragmentAttendanceCalculatorBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.settings.appearance.AppearanceFragment -import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor -import javax.inject.Inject - -@AndroidEntryPoint -class AttendanceCalculatorFragment : - BaseFragment(R.layout.fragment_attendance_calculator), - AttendanceCalculatorView, MainView.TitledView { - - @Inject - lateinit var presenter: AttendanceCalculatorPresenter - - @Inject - lateinit var attendanceCalculatorAdapter: AttendanceCalculatorAdapter - - override val titleStringId get() = R.string.attendance_title - - companion object { - fun newInstance() = AttendanceCalculatorFragment() - } - - override val isViewEmpty get() = attendanceCalculatorAdapter.items.isEmpty() - - @Suppress("DEPRECATION") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentAttendanceCalculatorBinding.bind(view) - messageContainer = binding.attendanceCalculatorRecycler - presenter.onAttachView(this) - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.action_menu_attendance_calculator, menu) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return if (item.itemId == R.id.attendance_calculator_menu_settings) presenter.onSettingsSelected() - else false - } - - override fun openSettingsView() { - (activity as? MainActivity)?.pushView(AppearanceFragment.withFocusedPreference(getString(R.string.pref_key_attendance_target))) - } - - override fun initView() { - with(binding.attendanceCalculatorRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = attendanceCalculatorAdapter - addItemDecoration(DividerItemDecoration(context)) - } - - with(binding) { - attendanceCalculatorSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - attendanceCalculatorSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - attendanceCalculatorSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor( - R.attr.colorSwipeRefresh - ) - ) - attendanceCalculatorErrorRetry.setOnClickListener { presenter.onRetry() } - attendanceCalculatorErrorDetails.setOnClickListener { presenter.onDetailsClick() } - } - } - - override fun updateData(data: List) { - with(attendanceCalculatorAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun clearView() { - with(attendanceCalculatorAdapter) { - items = emptyList() - notifyDataSetChanged() - } - } - - override fun showEmpty(show: Boolean) { - binding.attendanceCalculatorEmpty.isVisible = show - } - - override fun showErrorView(show: Boolean) { - binding.attendanceCalculatorError.isVisible = show - } - - override fun setErrorDetails(message: String) { - binding.attendanceCalculatorErrorMessage.text = message - } - - override fun showProgress(show: Boolean) { - binding.attendanceCalculatorProgress.isVisible = show - } - - override fun enableSwipe(enable: Boolean) { - binding.attendanceCalculatorSwipe.isEnabled = enable - } - - override fun showContent(show: Boolean) { - binding.attendanceCalculatorRecycler.isVisible = show - } - - override fun showRefresh(show: Boolean) { - binding.attendanceCalculatorSwipe.isRefreshing = show - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorPresenter.kt deleted file mode 100644 index 29cb2197..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorPresenter.kt +++ /dev/null @@ -1,94 +0,0 @@ -package io.github.wulkanowy.ui.modules.attendance.calculator - -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceIntermediate -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.domain.attendance.GetAttendanceCalculatorDataUseCase -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import timber.log.Timber -import javax.inject.Inject - -class AttendanceCalculatorPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository, - private val getAttendanceCalculatorData: GetAttendanceCalculatorDataUseCase, -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var lastError: Throwable - - override fun onAttachView(view: AttendanceCalculatorView) { - super.onAttachView(view) - view.initView() - Timber.i("Attendance calculator view was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData() - } - - fun onSwipeRefresh() { - Timber.i("Force refreshing the attendance calculator") - loadData(forceRefresh = true) - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData() - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { - val student = studentRepository.getCurrentStudent() - val semester = semesterRepository.getCurrentSemester(student) - getAttendanceCalculatorData(student, semester, forceRefresh) - } - .logResourceStatus("load attendance calculator") - .onResourceData { - view?.run { - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) - } - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showRefresh(false) - showProgress(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - } else showError(message, error) - } - } - - fun onSettingsSelected(): Boolean { - view?.openSettingsView() - return true - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorView.kt deleted file mode 100644 index 21afe532..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/calculator/AttendanceCalculatorView.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.wulkanowy.ui.modules.attendance.calculator - -import io.github.wulkanowy.data.pojos.AttendanceData -import io.github.wulkanowy.ui.base.BaseView - -interface AttendanceCalculatorView : BaseView { - - val isViewEmpty: Boolean - - fun initView() - - fun showRefresh(show: Boolean) - - fun showContent(show: Boolean) - - fun showProgress(show: Boolean) - - fun enableSwipe(enable: Boolean) - - fun showEmpty(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun updateData(data: List) - - fun clearView() - - fun openSettingsView() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryAdapter.kt index 4e9f68c9..4250a910 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryAdapter.kt @@ -5,7 +5,6 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.AttendanceSummary -import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.databinding.ItemAttendanceSummaryBinding import io.github.wulkanowy.databinding.ScrollableHeaderAttendanceSummaryBinding import io.github.wulkanowy.utils.calculatePercentage @@ -14,13 +13,9 @@ import java.time.Month import java.util.Locale import javax.inject.Inject -class AttendanceSummaryAdapter @Inject constructor( - private val preferencesRepository: PreferencesRepository -) : +class AttendanceSummaryAdapter @Inject constructor() : RecyclerView.Adapter() { - private val attendancePercentage = preferencesRepository.attendancePercentage - private enum class ViewType(val id: Int) { HEADER(1), ITEM(2) @@ -53,10 +48,7 @@ class AttendanceSummaryAdapter @Inject constructor( } private fun bindHeaderViewHolder(binding: ScrollableHeaderAttendanceSummaryBinding) { - binding.attendanceSummaryScrollableHeaderPercentage.text = formatPercentage( - attendancePercentage ?: - items.calculatePercentage() - ) + binding.attendanceSummaryScrollableHeaderPercentage.text = formatPercentage(items.calculatePercentage()) } private fun bindItemViewHolder(binding: ItemAttendanceSummaryBinding, position: Int) { @@ -68,8 +60,8 @@ class AttendanceSummaryAdapter @Inject constructor( else -> item.month.getFormattedName() } attendanceSummaryPercentage.text = when (position) { - -1 -> formatPercentage(attendancePercentage ?: item.calculatePercentage()) - else -> formatPercentage(attendancePercentage ?: item.calculatePercentage()) + -1 -> formatPercentage(items.calculatePercentage()) + else -> formatPercentage(item.calculatePercentage()) } attendanceSummaryPresent.text = item.presence.toString() @@ -84,13 +76,13 @@ class AttendanceSummaryAdapter @Inject constructor( private fun getTotalItem() = AttendanceSummary( month = Month.APRIL, - presence = items.sumOf { it.presence }, - absence = items.sumOf { it.absence }, - absenceExcused = items.sumOf { it.absenceExcused }, - absenceForSchoolReasons = items.sumOf { it.absenceForSchoolReasons }, - exemption = items.sumOf { it.exemption }, - lateness = items.sumOf { it.lateness }, - latenessExcused = items.sumOf { it.latenessExcused }, + presence = items.sumBy { it.presence }, + absence = items.sumBy { it.absence }, + absenceExcused = items.sumBy { it.absenceExcused }, + absenceForSchoolReasons = items.sumBy { it.absenceForSchoolReasons }, + exemption = items.sumBy { it.exemption }, + lateness = items.sumBy { it.lateness }, + latenessExcused = items.sumBy { it.latenessExcused }, diaryId = -1, studentId = -1, subjectId = -1 diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt index e750b8d5..2f862237 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryFragment.kt @@ -15,7 +15,6 @@ import io.github.wulkanowy.databinding.FragmentAttendanceSummaryBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.setOnItemSelectedListener import javax.inject.Inject @@ -57,8 +56,6 @@ class AttendanceSummaryFragment : with(binding) { attendanceSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh) - attendanceSummarySwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - attendanceSummarySwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) attendanceSummaryErrorRetry.setOnClickListener { presenter.onRetry() } attendanceSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() } } @@ -71,10 +68,10 @@ class AttendanceSummaryFragment : setOnItemSelectedListener { presenter.onSubjectSelected(it?.text?.toString()) } } - binding.attendanceSummarySubjectsContainer.elevation = requireContext().dpToPx(1f) + binding.attendanceSummarySubjectsContainer.setElevationCompat(requireContext().dpToPx(1f)) } - override fun updateSubjects(data: Collection) { + override fun updateSubjects(data: ArrayList) { with(subjectsAdapter) { clear() addAll(data) @@ -124,8 +121,8 @@ class AttendanceSummaryFragment : binding.attendanceSummarySubjectsContainer.visibility = if (show) VISIBLE else INVISIBLE } - override fun showRefresh(show: Boolean) { - binding.attendanceSummarySwipe.isRefreshing = show + override fun hideRefresh() { + binding.attendanceSummarySwipe.isRefreshing = false } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt index 28199917..4ce49d96 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryPresenter.kt @@ -1,15 +1,17 @@ package io.github.wulkanowy.ui.modules.attendance.summary -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.AttendanceSummary +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Subject -import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.SubjectRepository +import io.github.wulkanowy.data.repositories.attendancesummary.AttendanceSummaryRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.subject.SubjectRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.time.Month import javax.inject.Inject @@ -74,51 +76,41 @@ class AttendanceSummaryPresenter @Inject constructor( private fun loadData(subjectId: Int, forceRefresh: Boolean = false) { currentSubjectId = subjectId - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - - attendanceSummaryRepository.getAttendanceSummary( - student = student, - semester = semester, - subjectId = subjectId, - forceRefresh = forceRefresh - ) - } - .logResourceStatus("load attendance summary") - .mapResourceData(this::sortItems) - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateDataSet(it) + attendanceSummaryRepository.getAttendanceSummary(student, semester, subjectId, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading attendance summary data started") + Status.SUCCESS -> { + Timber.i("Loading attendance summary result: Success") + view?.apply { + showEmpty(it.data!!.isEmpty()) + showContent(it.data.isNotEmpty()) + updateDataSet(it.data.sortedByDescending { item -> + if (item.month.value <= Month.JUNE.value) item.month.value + 12 else item.month.value + }) + } + analytics.logEvent( + "load_data", + "type" to "attendance_summary", + "items" to it.data!!.size, + "item_id" to subjectId + ) + } + Status.ERROR -> { + Timber.i("Loading attendance summary result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "attendance_summary", - "items" to it.size, - "item_id" to subjectId - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - showProgress(false) - showRefresh(false) - enableSwipe(true) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private fun sortItems(items: List) = items.sortedByDescending { item -> - if (item.month.value <= Month.JUNE.value) item.month.value + 12 else item.month.value + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -133,20 +125,27 @@ class AttendanceSummaryPresenter @Inject constructor( } private fun loadSubjects() { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) subjectRepository.getSubjects(student, semester) - } - .logResourceStatus("load attendance summary subjects") - .onResourceData { - subjects = it - view?.run { - view?.updateSubjects(it.map { subject -> subject.name }.toList()) - showSubjects(true) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading attendance summary subjects started") + Status.SUCCESS -> { + subjects = it.data!! + + Timber.i("Loading attendance summary subjects result: Success") + view?.run { + view?.updateSubjects(ArrayList(it.data.map { subject -> subject.name })) + showSubjects(true) + } + } + Status.ERROR -> { + Timber.i("Loading attendance summary subjects result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch("subjects") + }.launch("subjects") } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryView.kt index 99192f18..dd4053c7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/summary/AttendanceSummaryView.kt @@ -9,7 +9,7 @@ interface AttendanceSummaryView : BaseView { fun initView() - fun showRefresh(show: Boolean) + fun hideRefresh() fun showContent(show: Boolean) @@ -25,7 +25,7 @@ interface AttendanceSummaryView : BaseView { fun updateDataSet(data: List) - fun updateSubjects(data: Collection) + fun updateSubjects(data: ArrayList) fun showSubjects(show: Boolean) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthDialog.kt deleted file mode 100644 index 0f7c4234..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthDialog.kt +++ /dev/null @@ -1,86 +0,0 @@ -package io.github.wulkanowy.ui.modules.auth - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.text.parseAsHtml -import androidx.core.view.isVisible -import androidx.core.widget.doOnTextChanged -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.DialogAuthBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import javax.inject.Inject - -@AndroidEntryPoint -class AuthDialog : BaseDialogFragment(), AuthView { - - @Inject - lateinit var presenter: AuthPresenter - - companion object { - fun newInstance() = AuthDialog() - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setStyle(STYLE_NO_TITLE, R.style.FullScreenDialogStyle) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return DialogAuthBinding.inflate(inflater).apply { binding = this }.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - presenter.onAttachView(this) - - binding.authInput.doOnTextChanged { text, _, _, _ -> - presenter.onPeselChange(text?.toString()) - } - - binding.authButton.setOnClickListener { presenter.authorize() } - binding.authSuccessButton.setOnClickListener { - activity?.recreate() - dismiss() - } - binding.authButtonSkip.setOnClickListener { dismiss() } - } - - override fun enableAuthButton(isEnabled: Boolean) { - binding.authButton.isEnabled = isEnabled - } - - override fun showProgress(show: Boolean) { - binding.authProgress.isVisible = show - } - - override fun showPeselError(show: Boolean) { - binding.authInputLayout.error = getString(R.string.auth_api_error).takeIf { show } - } - - override fun showInvalidPeselError(show: Boolean) { - binding.authInputLayout.error = getString(R.string.auth_invalid_error).takeIf { show } - } - - override fun showSuccess(show: Boolean) { - binding.authSuccess.isVisible = show - } - - override fun showContent(show: Boolean) { - binding.authForm.isVisible = show - } - - override fun showDescriptionWithName(name: String) { - binding.authDescription.text = getString(R.string.auth_description, name).parseAsHtml() - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthPresenter.kt deleted file mode 100644 index 0be086b6..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthPresenter.kt +++ /dev/null @@ -1,111 +0,0 @@ -package io.github.wulkanowy.ui.modules.auth - -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import kotlinx.coroutines.launch -import timber.log.Timber -import javax.inject.Inject - -class AuthPresenter @Inject constructor( - private val semesterRepository: SemesterRepository, - errorHandler: ErrorHandler, - studentRepository: StudentRepository -) : BasePresenter(errorHandler, studentRepository) { - - private var pesel: String = "" - - override fun onAttachView(view: AuthView) { - super.onAttachView(view) - view.enableAuthButton(pesel.length == 11) - view.showSuccess(false) - view.showProgress(false) - - loadName() - } - - private fun loadName() { - presenterScope.launch { - runCatching { - studentRepository.getCurrentStudent(false) - .studentName - .replace(" ", "\u00A0") - } - .onSuccess { view?.showDescriptionWithName(it) } - .onFailure { errorHandler.dispatch(it) } - } - } - - fun onPeselChange(newPesel: String?) { - pesel = newPesel.orEmpty() - - view?.enableAuthButton(pesel.length == 11) - view?.showPeselError(false) - view?.showInvalidPeselError(false) - } - - fun authorize() { - presenterScope.launch { - view?.showProgress(true) - view?.showContent(false) - - if (!isValidPESEL(pesel)) { - view?.showInvalidPeselError(true) - view?.showProgress(false) - view?.showContent(true) - return@launch - } - - runCatching { - val student = studentRepository.getCurrentStudent() - val semester = semesterRepository.getCurrentSemester(student) - - val isSuccess = studentRepository.authorizePermission(student, semester, pesel) - Timber.d("Auth succeed: $isSuccess") - if (isSuccess) { - studentRepository.refreshStudentAfterAuthorize(student, semester) - } - isSuccess - } - .onFailure { - errorHandler.dispatch(it) - view?.showProgress(false) - view?.showContent(true) - } - .onSuccess { - Timber.d("Auth fully succeed: $it") - if (it) { - view?.showSuccess(true) - view?.showContent(false) - view?.showPeselError(false) - } else { - view?.showSuccess(false) - view?.showContent(true) - view?.showPeselError(true) - } - } - - view?.showProgress(false) - } - } - - private fun isValidPESEL(peselString: String): Boolean { - if (peselString.length != 11) { - return false - } - - val weights = intArrayOf(1, 3, 7, 9, 1, 3, 7, 9, 1, 3) - var sum = 0 - - for (i in 0 until 10) { - sum += weights[i] * Character.getNumericValue(peselString[i]) - } - - sum %= 10 - sum = 10 - sum - sum %= 10 - - return sum == Character.getNumericValue(peselString[10]) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthView.kt deleted file mode 100644 index d7e1917c..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/auth/AuthView.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.wulkanowy.ui.modules.auth - -import io.github.wulkanowy.ui.base.BaseView - -interface AuthView : BaseView { - - fun enableAuthButton(isEnabled: Boolean) - - fun showProgress(show: Boolean) - - fun showPeselError(show: Boolean) - - fun showInvalidPeselError(show: Boolean) - - fun showSuccess(show: Boolean) - - fun showContent(show: Boolean) - - fun showDescriptionWithName(name: String) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt deleted file mode 100644 index 922b652b..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/captcha/CaptchaDialog.kt +++ /dev/null @@ -1,91 +0,0 @@ -package io.github.wulkanowy.ui.modules.captcha - -import android.annotation.SuppressLint -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.webkit.WebView -import android.webkit.WebViewClient -import androidx.core.os.bundleOf -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.WulkanowySdkFactory -import io.github.wulkanowy.databinding.DialogCaptchaBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.WebkitCookieManagerProxy -import timber.log.Timber -import javax.inject.Inject - -@AndroidEntryPoint -class CaptchaDialog : BaseDialogFragment() { - - @Inject - lateinit var wulkanowySdkFactory: WulkanowySdkFactory - - @Inject - lateinit var webkitCookieManagerProxy: WebkitCookieManagerProxy - - private var webView: WebView? = null - - companion object { - const val CAPTCHA_SUCCESS = "captcha_success" - private const val CAPTCHA_URL = "captcha_url" - private const val CAPTCHA_CHECK_JS = "document.getElementById('challenge-running') == null" - - fun newInstance(url: String?): CaptchaDialog { - return CaptchaDialog().apply { - arguments = bundleOf(CAPTCHA_URL to url) - } - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View = DialogCaptchaBinding.inflate(inflater).apply { binding = this }.root - - @SuppressLint("SetJavaScriptEnabled") - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - isCancelable = false - binding.captchaRefresh.setOnClickListener { - binding.captchaWebview.loadUrl(arguments?.getString(CAPTCHA_URL).orEmpty()) - } - binding.captchaClose.setOnClickListener { dismiss() } - - with(binding.captchaWebview) { - webView = this - with(settings) { - javaScriptEnabled = true - userAgentString = wulkanowySdkFactory.createBase().userAgent - } - - webViewClient = object : WebViewClient() { - override fun onPageFinished(view: WebView?, url: String?) { - view?.evaluateJavascript(CAPTCHA_CHECK_JS) { - if (it == "true") { - onChallengeAccepted() - } - } - } - } - - loadUrl(arguments?.getString(CAPTCHA_URL).orEmpty()) - } - } - - private fun onChallengeAccepted() { - runCatching { parentFragmentManager.setFragmentResult(CAPTCHA_SUCCESS, bundleOf()) } - .onFailure { Timber.e(it) } - showMessage(getString(R.string.captcha_verified_message)) - dismissAllowingStateLoss() - } - - override fun onDestroy() { - webkitCookieManagerProxy.webkitCookieManager?.flush() - webView?.destroy() - super.onDestroy() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceAdapter.kt index f63b293c..c8728614 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceAdapter.kt @@ -14,8 +14,6 @@ class ConferenceAdapter @Inject constructor() : var items = emptyList() - var onItemClickListener: (Conference) -> Unit = {} - override fun getItemCount() = items.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( @@ -30,10 +28,7 @@ class ConferenceAdapter @Inject constructor() : conferenceItemTitle.text = item.title conferenceItemSubject.text = item.subject conferenceItemContent.text = item.agenda - conferenceItemContent.visibility = - if (item.agenda.isBlank()) View.GONE else View.VISIBLE - - root.setOnClickListener { onItemClickListener(item) } + conferenceItemContent.visibility = if (item.agenda.isBlank()) View.GONE else View.VISIBLE } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt deleted file mode 100644 index c532377e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.github.wulkanowy.ui.modules.conference - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.core.view.isVisible -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.databinding.DialogConferenceBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.serializable -import io.github.wulkanowy.utils.toFormattedString - -@AndroidEntryPoint -class ConferenceDialog : BaseDialogFragment() { - - private lateinit var conference: Conference - - companion object { - - private const val ARGUMENT_KEY = "item" - - fun newInstance(conference: Conference) = ConferenceDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to conference) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - conference = requireArguments().serializable(ARGUMENT_KEY) - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogConferenceBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - with(binding) { - conferenceDialogClose.setOnClickListener { dismiss() } - - conferenceDialogSubjectValue.text = conference.subject - conferenceDialogDateValue.text = conference.date.toFormattedString("dd.MM.yyyy HH:mm") - conferenceDialogHeaderValue.text = conference.title - conferenceDialogAgendaValue.text = conference.agenda - conferenceDialogPresentValue.text = conference.presentOnConference - conferenceDialogPresentValue.isVisible = conference.presentOnConference.isNotBlank() - conferenceDialogPresentTitle.isVisible = conference.presentOnConference.isNotBlank() - conferenceDialogAgendaValue.isVisible = conference.agenda.isNotBlank() - conferenceDialogAgendaTitle.isVisible = conference.agenda.isNotBlank() - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceFragment.kt index 0cd3150c..74d93897 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceFragment.kt @@ -8,15 +8,13 @@ import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Conference import io.github.wulkanowy.databinding.FragmentConferenceBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint class ConferenceFragment : BaseFragment(R.layout.fragment_conference), - ConferenceView, MainView.TitledView, MainView.MainChildView { + ConferenceView, MainView.TitledView { @Inject lateinit var presenter: ConferencePresenter @@ -42,8 +40,6 @@ class ConferenceFragment : BaseFragment(R.layout.frag } override fun initView() { - conferencesAdapter.onItemClickListener = presenter::onItemSelected - with(binding.conferenceRecycler) { layoutManager = LinearLayoutManager(context) adapter = conferencesAdapter @@ -51,13 +47,7 @@ class ConferenceFragment : BaseFragment(R.layout.frag } with(binding) { - conferenceSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - conferenceSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - conferenceSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor( - R.attr.colorSwipeRefresh - ) - ) + conferenceSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } conferenceErrorRetry.setOnClickListener { presenter.onRetry() } conferenceErrorDetails.setOnClickListener { presenter.onDetailsClick() } } @@ -77,8 +67,8 @@ class ConferenceFragment : BaseFragment(R.layout.frag } } - override fun showRefresh(show: Boolean) { - binding.conferenceSwipe.isRefreshing = show + override fun hideRefresh() { + binding.conferenceSwipe.isRefreshing = false } override fun showProgress(show: Boolean) { @@ -105,18 +95,6 @@ class ConferenceFragment : BaseFragment(R.layout.frag binding.conferenceRecycler.visibility = if (show) View.VISIBLE else View.GONE } - override fun openConferenceDialog(conference: Conference) { - (activity as? MainActivity)?.showDialogFragment(ConferenceDialog.newInstance(conference)) - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onFragmentReselected() - } - - override fun resetView() { - binding.conferenceRecycler.smoothScrollToPosition(0) - } - override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferencePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferencePresenter.kt index 1178c720..71b412da 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferencePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferencePresenter.kt @@ -1,13 +1,15 @@ package io.github.wulkanowy.ui.modules.conference -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.data.repositories.ConferenceRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.conference.ConferenceRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -41,10 +43,6 @@ class ConferencePresenter @Inject constructor( loadData(true) } - fun onItemSelected(conference: Conference) { - view?.openConferenceDialog(conference) - } - fun onDetailsClick() { view?.showErrorDetailsDialog(lastError) } @@ -61,46 +59,38 @@ class ConferencePresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) conferenceRepository.getConferences(student, semester, forceRefresh) - } - .logResourceStatus("load conference data") - .mapResourceData { it.sortedByDescending { conference -> conference.date } } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading conference data started") + Status.SUCCESS -> { + Timber.i("Loading conference result: Success") + view?.run { + updateData(it.data!!.sortedByDescending { conference -> conference.date }) + showContent(it.data.isNotEmpty()) + showEmpty(it.data.isEmpty()) + showErrorView(false) + } + analytics.logEvent( + "load_data", + "type" to "conferences", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading conference result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "conferences", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - fun onFragmentReselected() { - Timber.i("Conference is reselected") - if (view?.isViewEmpty == false) { - view?.resetView() - } + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceView.kt index 3299a1f0..37845a6f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceView.kt @@ -13,7 +13,7 @@ interface ConferenceView : BaseView { fun clearData() - fun showRefresh(show: Boolean) + fun hideRefresh() fun showEmpty(show: Boolean) @@ -26,8 +26,4 @@ interface ConferenceView : BaseView { fun enableSwipe(enable: Boolean) fun showContent(show: Boolean) - - fun openConferenceDialog(conference: Conference) - - fun resetView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt deleted file mode 100644 index b7a0796c..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt +++ /dev/null @@ -1,244 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.appcompat.app.AlertDialog -import androidx.core.view.isVisible -import androidx.recyclerview.widget.DefaultItemAnimator -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.FragmentDashboardBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsFragment -import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment -import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog.Companion.CAPTCHA_SUCCESS -import io.github.wulkanowy.ui.modules.conference.ConferenceFragment -import io.github.wulkanowy.ui.modules.dashboard.adapters.DashboardAdapter -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder -import io.github.wulkanowy.ui.modules.exam.ExamFragment -import io.github.wulkanowy.ui.modules.grade.GradeFragment -import io.github.wulkanowy.ui.modules.homework.HomeworkFragment -import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.message.MessageFragment -import io.github.wulkanowy.ui.modules.notificationscenter.NotificationsCenterFragment -import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment -import io.github.wulkanowy.ui.modules.timetable.TimetableFragment -import io.github.wulkanowy.utils.capitalise -import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.getErrorString -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate -import javax.inject.Inject - -@AndroidEntryPoint -class DashboardFragment : BaseFragment(R.layout.fragment_dashboard), - DashboardView, MainView.TitledView, MainView.MainChildView { - - @Inject - lateinit var presenter: DashboardPresenter - - @Inject - lateinit var dashboardAdapter: DashboardAdapter - - override val titleStringId get() = R.string.dashboard_title - - override var subtitleString = - LocalDate.now().toFormattedString("EEEE, d MMMM yyyy").capitalise() - - override val tileWidth: Int - get() { - val recyclerWidth = binding.dashboardRecycler.width - val margin = requireContext().dpToPx(24f).toInt() - - return ((recyclerWidth - margin) / resources.displayMetrics.density).toInt() - } - - override val isViewEmpty - get() = dashboardAdapter.itemCount == 0 - - companion object { - - fun newInstance() = DashboardFragment() - } - - @Suppress("DEPRECATION") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentDashboardBinding.bind(view) - presenter.onAttachView(this) - initializeCaptchaResultObserver() - } - - private fun initializeCaptchaResultObserver() { - childFragmentManager.setFragmentResultListener(CAPTCHA_SUCCESS, this) { _, _ -> - presenter.onRetryAfterCaptcha() - } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.action_menu_dashboard, menu) - } - - override fun initView() { - val mainActivity = requireActivity() as MainActivity - val itemTouchHelper = ItemTouchHelper( - DashboardItemMoveCallback(dashboardAdapter, presenter::onDragAndDropEnd) - ) - - dashboardAdapter.apply { - onAccountTileClickListener = { - mainActivity.pushView(AccountDetailsFragment.newInstance(it)) - } - onLuckyNumberTileClickListener = { - mainActivity.pushView(LuckyNumberFragment.newInstance()) - } - onMessageTileClickListener = { mainActivity.pushView(MessageFragment.newInstance()) } - onAttendanceTileClickListener = { - mainActivity.pushView(AttendanceSummaryFragment.newInstance()) - } - onLessonsTileClickListener = { - mainActivity.pushView(TimetableFragment.newInstance(it)) - } - onGradeTileClickListener = { mainActivity.pushView(GradeFragment.newInstance()) } - onHomeworkTileClickListener = { mainActivity.pushView(HomeworkFragment.newInstance()) } - onAnnouncementsTileClickListener = { - mainActivity.pushView(SchoolAnnouncementFragment.newInstance()) - } - onExamsTileClickListener = { mainActivity.pushView(ExamFragment.newInstance()) } - onConferencesTileClickListener = { - mainActivity.pushView(ConferenceFragment.newInstance()) - } - onAdminMessageClickListener = presenter::onAdminMessageSelected - onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed - - registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { - override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { - binding.dashboardRecycler.scrollToPosition(0) - } - }) - } - - with(binding) { - dashboardErrorRetry.setOnClickListener { presenter.onRetry() } - dashboardErrorDetails.setOnClickListener { presenter.onDetailsClick() } - dashboardSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - dashboardSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - dashboardSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) - - with(dashboardRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = dashboardAdapter - (itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false - } - - itemTouchHelper.attachToRecyclerView(dashboardRecycler) - } - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.dashboard_menu_tiles -> presenter.onDashboardTileSettingsSelected() - R.id.dashboard_menu_notifaction_list -> presenter.onNotificationsCenterSelected() - else -> false - } - } - - override fun showDashboardTileSettings(selectedItems: List) { - val entries = requireContext().resources.getStringArray(R.array.dashboard_tile_entries) - val values = requireContext().resources.getStringArray(R.array.dashboard_tile_values) - val selectedItemsState = values.map { value -> selectedItems.any { it.name == value } } - - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.pref_dashboard_appearance_tiles_title) - .setMultiChoiceItems(entries, selectedItemsState.toBooleanArray()) { _, _, _ -> } - .setPositiveButton(android.R.string.ok) { dialog, _ -> - val selectedState = (dialog as AlertDialog).listView.checkedItemPositions - val selectedValues = values.filterIndexed { index, _ -> selectedState[index] } - - presenter.onDashboardTileSettingSelected(selectedValues) - } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() - } - - override fun updateData(data: List) { - dashboardAdapter.submitList(data.toMutableList()) - } - - override fun showMessage(text: String) { - //Empty function to avoid message flood - } - - override fun showRefresh(show: Boolean) { - binding.dashboardSwipe.isRefreshing = show - } - - override fun showProgress(show: Boolean) { - binding.dashboardProgress.isVisible = show - } - - override fun showContent(show: Boolean) { - binding.dashboardRecycler.isVisible = show - } - - override fun showErrorView(show: Boolean, adminMessageItem: DashboardItem.AdminMessages?) { - binding.dashboardErrorContainer.isVisible = show - binding.dashboardErrorAdminMessage.root.isVisible = adminMessageItem != null - - if (adminMessageItem != null) { - AdminMessageViewHolder( - binding = binding.dashboardErrorAdminMessage, - onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, - onAdminMessageClickListener = presenter::onAdminMessageSelected, - ).bind(adminMessageItem.adminMessage) - } - } - - override fun setErrorDetails(error: Throwable) { - binding.dashboardErrorMessage.text = requireContext().resources.getErrorString(error) - } - - override fun resetView() { - binding.dashboardRecycler.smoothScrollToPosition(0) - } - - override fun popViewToRoot() { - (requireActivity() as MainActivity).popView(20) - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onViewReselected() - } - - override fun openNotificationsCenterView() { - (requireActivity() as MainActivity).pushView(NotificationsCenterFragment.newInstance()) - } - - override fun openInternetBrowser(url: String) { - requireContext().openInternetBrowser(url) - } - - override fun onDestroyView() { - dashboardAdapter.clearTimers() - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt deleted file mode 100644 index 506f6124..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt +++ /dev/null @@ -1,176 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard - -import io.github.wulkanowy.data.db.entities.* -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.pojos.TimetableFull -import io.github.wulkanowy.utils.AdBanner -import io.github.wulkanowy.data.db.entities.Homework as EntitiesHomework - -sealed class DashboardItem(val type: Type) { - - abstract val error: Throwable? - - abstract val isLoading: Boolean - - abstract val isDataLoaded: Boolean - - data class AdminMessages( - val adminMessage: AdminMessage? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.ADMIN_MESSAGE) { - - override val isDataLoaded get() = adminMessage != null - } - - data class Account( - val student: Student? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.ACCOUNT) { - - override val isDataLoaded get() = student != null - } - - data class HorizontalGroup( - val unreadMessagesCount: Cell? = null, - val attendancePercentage: Cell? = null, - val luckyNumber: Cell? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.HORIZONTAL_GROUP) { - - data class Cell( - val data: T?, - val error: Boolean, - val isLoading: Boolean, - ) { - val isHidden: Boolean - get() = data == null && !error && !isLoading - } - - override val isDataLoaded - get() = unreadMessagesCount?.isLoading == false || attendancePercentage?.isLoading == false || luckyNumber?.isLoading == false - - val isFullDataLoaded - get() = luckyNumber?.isLoading != true && attendancePercentage?.isLoading != true && unreadMessagesCount?.isLoading != true - } - - data class Grades( - val subjectWithGrades: Map>? = null, - val gradeTheme: GradeColorTheme? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.GRADES) { - - override val isDataLoaded get() = subjectWithGrades != null - } - - data class Lessons( - val lessons: TimetableFull? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.LESSONS) { - - override val isDataLoaded get() = lessons != null - } - - data class Homework( - val homework: List? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.HOMEWORK) { - - override val isDataLoaded get() = homework != null - } - - data class Announcements( - val announcement: List? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.ANNOUNCEMENTS) { - - override val isDataLoaded get() = announcement != null - } - - data class Exams( - val exams: List? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.EXAMS) { - - override val isDataLoaded get() = exams != null - } - - data class Conferences( - val conferences: List? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.CONFERENCES) { - - override val isDataLoaded get() = conferences != null - } - - data class Ads( - val adBanner: AdBanner? = null, - override val error: Throwable? = null, - override val isLoading: Boolean = false - ) : DashboardItem(Type.ADS) { - - override val isDataLoaded get() = adBanner != null - } - - enum class Type { - ADMIN_MESSAGE, - ACCOUNT, - HORIZONTAL_GROUP, - LESSONS, - ADS, - GRADES, - HOMEWORK, - ANNOUNCEMENTS, - EXAMS, - CONFERENCES, - } - - enum class Tile { - ADMIN_MESSAGE, - ACCOUNT, - LUCKY_NUMBER, - MESSAGES, - ATTENDANCE, - LESSONS, - ADS, - GRADES, - HOMEWORK, - ANNOUNCEMENTS, - EXAMS, - CONFERENCES, - } - - enum class HiddenAttendanceTile { - UNEXCUSED_ABSENCE, - EXEMPTION, - EXCUSED_LATENESS, - UNEXCUSED_LATENESS, - PRESENT, - DELETED, - EXCUSED_ABSENCE, - UNKNOWN, - } -} - -fun DashboardItem.Tile.toDashboardItemType() = when (this) { - DashboardItem.Tile.ADMIN_MESSAGE -> DashboardItem.Type.ADMIN_MESSAGE - DashboardItem.Tile.ACCOUNT -> DashboardItem.Type.ACCOUNT - DashboardItem.Tile.LUCKY_NUMBER -> DashboardItem.Type.HORIZONTAL_GROUP - DashboardItem.Tile.MESSAGES -> DashboardItem.Type.HORIZONTAL_GROUP - DashboardItem.Tile.ATTENDANCE -> DashboardItem.Type.HORIZONTAL_GROUP - DashboardItem.Tile.LESSONS -> DashboardItem.Type.LESSONS - DashboardItem.Tile.GRADES -> DashboardItem.Type.GRADES - DashboardItem.Tile.HOMEWORK -> DashboardItem.Type.HOMEWORK - DashboardItem.Tile.ANNOUNCEMENTS -> DashboardItem.Type.ANNOUNCEMENTS - DashboardItem.Tile.EXAMS -> DashboardItem.Type.EXAMS - DashboardItem.Tile.CONFERENCES -> DashboardItem.Type.CONFERENCES - DashboardItem.Tile.ADS -> DashboardItem.Type.ADS -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItemMoveCallback.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItemMoveCallback.kt deleted file mode 100644 index f033b594..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItemMoveCallback.kt +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard - -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.ui.modules.dashboard.adapters.DashboardAdapter -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder -import java.util.* - -class DashboardItemMoveCallback( - private val dashboardAdapter: DashboardAdapter, - private var onUserInteractionEndListener: (List) -> Unit = {} -) : ItemTouchHelper.Callback() { - - override fun isLongPressDragEnabled() = true - - override fun isItemViewSwipeEnabled() = false - - override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - //Not implemented - } - - override fun getMovementFlags( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder - ): Int { - val dragFlags = if (!viewHolder.isAdminMessageOrAccountItem) { - ItemTouchHelper.UP or ItemTouchHelper.DOWN - } else 0 - - return makeMovementFlags(dragFlags, 0) - } - - override fun canDropOver( - recyclerView: RecyclerView, - current: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ) = !target.isAdminMessageOrAccountItem - - override fun onMove( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ): Boolean { - val list = dashboardAdapter.items.toMutableList() - - Collections.swap(list, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition) - - dashboardAdapter.submitList(list) - return true - } - - override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { - super.clearView(recyclerView, viewHolder) - - onUserInteractionEndListener(dashboardAdapter.items.toList()) - } - - private val RecyclerView.ViewHolder.isAdminMessageOrAccountItem: Boolean - get() = this is AdminMessageViewHolder || this is DashboardAdapter.AccountViewHolder -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt deleted file mode 100644 index 9ba71937..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt +++ /dev/null @@ -1,904 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard - -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.dataOrNull -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.enums.MessageFolder -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.errorOrNull -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.mapResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository -import io.github.wulkanowy.data.repositories.ConferenceRepository -import io.github.wulkanowy.data.repositories.ExamRepository -import io.github.wulkanowy.data.repositories.GradeRepository -import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.repositories.LuckyNumberRepository -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase -import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AdsHelper -import io.github.wulkanowy.utils.calculatePercentage -import io.github.wulkanowy.utils.nextOrSameSchoolDay -import io.github.wulkanowy.utils.sunday -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.filterNot -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.merge -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import timber.log.Timber -import java.time.Instant -import java.time.LocalDate -import javax.inject.Inject - -class DashboardPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val luckyNumberRepository: LuckyNumberRepository, - private val gradeRepository: GradeRepository, - private val semesterRepository: SemesterRepository, - private val messageRepository: MessageRepository, - private val attendanceSummaryRepository: AttendanceSummaryRepository, - private val timetableRepository: TimetableRepository, - private val isStudentHasLessonsOnWeekendUseCase: IsStudentHasLessonsOnWeekendUseCase, - private val homeworkRepository: HomeworkRepository, - private val examRepository: ExamRepository, - private val conferenceRepository: ConferenceRepository, - private val preferencesRepository: PreferencesRepository, - private val schoolAnnouncementRepository: SchoolAnnouncementRepository, - private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase, - private val adsHelper: AdsHelper -) : BasePresenter(errorHandler, studentRepository) { - - private val dashboardItemLoadedList = mutableListOf() - - private val dashboardItemRefreshLoadedList = mutableListOf() - - private var dashboardItemsToLoad = emptySet() - - private var dashboardTileLoadedList = emptySet() - - private val firstLoadedItemList = mutableListOf() - - private val selectedDashboardTiles - get() = preferencesRepository.selectedDashboardTiles - .filterNot { it == DashboardItem.Tile.ADS && !adsHelper.canShowAd } - .toSet() - - private lateinit var lastError: Throwable - - override fun onAttachView(view: DashboardView) { - super.onAttachView(view) - - with(view) { - initView() - showProgress(true) - showContent(false) - } - - val selectedDashboardTilesFlow = preferencesRepository.selectedDashboardTilesFlow - .map { selectedDashboardTiles } - val isAdsEnabledFlow = preferencesRepository.isAdsEnabledFlow - .filter { (adsHelper.canShowAd && it) || !it } - .map { selectedDashboardTiles } - val isMobileAdsSdkInitializedFlow = adsHelper.isMobileAdsSdkInitialized - .filter { it } - .map { selectedDashboardTiles } - - merge( - selectedDashboardTilesFlow, - isAdsEnabledFlow, - isMobileAdsSdkInitializedFlow - ) - .onEach { loadData(tilesToLoad = it) } - .launch("dashboard_pref") - } - - fun onAdminMessageDismissed(adminMessage: AdminMessage) { - preferencesRepository.dismissedAdminMessageIds += adminMessage.id - - loadData(selectedDashboardTiles) - } - - fun onDragAndDropEnd(list: List) { - with(dashboardItemLoadedList) { - clear() - addAll(list) - } - - val positionList = - list.mapIndexed { index, dashboardItem -> Pair(dashboardItem.type, index) }.toMap() - - preferencesRepository.dashboardItemsPosition = positionList - } - - fun loadData( - tilesToLoad: Set, - forceRefresh: Boolean = false, - ) { - val oldDashboardTileLoadedList = dashboardTileLoadedList - dashboardItemsToLoad = tilesToLoad.map { it.toDashboardItemType() }.toSet() - dashboardTileLoadedList = tilesToLoad - - val itemsToLoad = generateDashboardTileListToLoad( - dashboardTilesToLoad = tilesToLoad, - dashboardLoadedTiles = oldDashboardTileLoadedList, - forceRefresh = forceRefresh - ).map { it.toDashboardItemType() } - - removeUnselectedTiles(tilesToLoad.toList()) - loadTiles(tileList = itemsToLoad, forceRefresh = forceRefresh) - } - - private fun generateDashboardTileListToLoad( - dashboardTilesToLoad: Set, - dashboardLoadedTiles: Set, - forceRefresh: Boolean - ) = dashboardTilesToLoad.filter { newItemToLoad -> - dashboardLoadedTiles.none { it == newItemToLoad } || forceRefresh - || newItemToLoad == DashboardItem.Tile.ADMIN_MESSAGE - } - - private fun removeUnselectedTiles(tilesToLoad: List) { - dashboardItemLoadedList.removeAll { loadedTile -> dashboardItemsToLoad.none { it == loadedTile.type } } - - val horizontalGroup = - dashboardItemLoadedList.find { it is DashboardItem.HorizontalGroup } as DashboardItem.HorizontalGroup? - - if (horizontalGroup != null) { - val isLuckyNumberToLoad = DashboardItem.Tile.LUCKY_NUMBER in tilesToLoad - val isMessagesToLoad = DashboardItem.Tile.MESSAGES in tilesToLoad - val isAttendanceToLoad = DashboardItem.Tile.ATTENDANCE in tilesToLoad - - val horizontalGroupIndex = dashboardItemLoadedList.indexOf(horizontalGroup) - - val newHorizontalGroup = horizontalGroup.copy( - attendancePercentage = horizontalGroup.attendancePercentage.takeIf { isAttendanceToLoad }, - unreadMessagesCount = horizontalGroup.unreadMessagesCount.takeIf { isMessagesToLoad }, - luckyNumber = horizontalGroup.luckyNumber.takeIf { isLuckyNumberToLoad } - ) - - with(dashboardItemLoadedList) { - removeAt(horizontalGroupIndex) - add(horizontalGroupIndex, newHorizontalGroup) - } - } - - view?.updateData(dashboardItemLoadedList) - } - - private fun loadTiles( - tileList: List, - forceRefresh: Boolean - ) { - presenterScope.launch { - Timber.i("Loading dashboard account data started") - val student = runCatching { studentRepository.getCurrentStudent(true) } - .onFailure { - Timber.i("Loading dashboard account result: An exception occurred") - errorHandler.dispatch(it) - updateData(DashboardItem.Account(error = it), forceRefresh) - } - .onSuccess { Timber.i("Loading dashboard account result: Success") } - .getOrNull() ?: return@launch - - tileList.forEach { - when (it) { - DashboardItem.Type.ACCOUNT -> { - updateData(DashboardItem.Account(student), forceRefresh) - } - - DashboardItem.Type.HORIZONTAL_GROUP -> { - loadHorizontalGroup(student, forceRefresh) - } - - DashboardItem.Type.LESSONS -> loadLessons(student, forceRefresh) - DashboardItem.Type.GRADES -> loadGrades(student, forceRefresh) - DashboardItem.Type.HOMEWORK -> loadHomework(student, forceRefresh) - DashboardItem.Type.ANNOUNCEMENTS -> { - loadSchoolAnnouncements(student, forceRefresh) - } - - DashboardItem.Type.EXAMS -> loadExams(student, forceRefresh) - DashboardItem.Type.CONFERENCES -> { - loadConferences(student, forceRefresh) - } - - DashboardItem.Type.ADS -> loadAds(forceRefresh) - DashboardItem.Type.ADMIN_MESSAGE -> loadAdminMessage(student, forceRefresh) - } - } - } - } - - fun onSwipeRefresh() { - Timber.i("Force refreshing the dashboard") - loadData(selectedDashboardTiles, forceRefresh = true) - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData(selectedDashboardTiles, forceRefresh = true) - } - - fun onRetryAfterCaptcha() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData(selectedDashboardTiles, forceRefresh = true) - } - - fun onViewReselected() { - Timber.i("Dashboard view is reselected") - view?.run { - resetView() - popViewToRoot() - } - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - fun onNotificationsCenterSelected(): Boolean { - view?.openNotificationsCenterView() - return true - } - - fun onDashboardTileSettingsSelected(): Boolean { - view?.showDashboardTileSettings(selectedDashboardTiles.toList()) - return true - } - - fun onDashboardTileSettingSelected(selectedItems: List) { - preferencesRepository.selectedDashboardTiles = selectedItems.map { - DashboardItem.Tile.valueOf(it) - }.toSet() - } - - fun onAdminMessageSelected(url: String?) { - url?.let { view?.openInternetBrowser(it) } - } - - private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) { - flow { - val attendancePercentage = preferencesRepository.attendancePercentage - - val selectedTiles = selectedDashboardTiles - val flowSuccess = flowOf(Resource.Success(null)) - - val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh) - .mapResourceData { - it ?: LuckyNumber(0, LocalDate.now(), 0) - } - .onResourceError { errorHandler.dispatch(it) } - .takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess - - val messageFLow = flatResourceFlow { - val mailbox = messageRepository.getMailboxByStudent(student) - - messageRepository.getMessages( - student = student, - mailbox = mailbox, - folder = MessageFolder.RECEIVED, - forceRefresh = forceRefresh - ) - } - .mapResourceData { it.map { messageWithAuthor -> messageWithAuthor.message } } - .onResourceError { errorHandler.dispatch(it) } - .takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess - - val attendanceFlow = flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - attendanceSummaryRepository.getAttendanceSummary( - student = student, - semester = semester, - subjectId = -1, - forceRefresh = forceRefresh - ) - } - .onResourceError { errorHandler.dispatch(it) } - .takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess - - emitAll( - combine( - flow = luckyNumberFlow, - flow2 = messageFLow, - flow3 = attendanceFlow, - ) { luckyNumberResource, messageResource, attendanceResource -> - val resList = listOf(luckyNumberResource, messageResource, attendanceResource) - - resList to DashboardItem.HorizontalGroup( - isLoading = resList.any { it is Resource.Loading }, - error = resList.map { it.errorOrNull }.let { errors -> - if (errors.all { it != null }) { - errors.firstOrNull() - } else null - }, - attendancePercentage = DashboardItem.HorizontalGroup.Cell( - data = attendancePercentage ?: attendanceResource.dataOrNull?.calculatePercentage(), - error = attendanceResource.errorOrNull != null, - isLoading = attendanceResource is Resource.Loading, - ), - unreadMessagesCount = DashboardItem.HorizontalGroup.Cell( - data = messageResource.dataOrNull?.count { it.unread }, - error = messageResource.errorOrNull != null, - isLoading = messageResource is Resource.Loading, - ), - luckyNumber = DashboardItem.HorizontalGroup.Cell( - data = luckyNumberResource.dataOrNull?.luckyNumber, - error = luckyNumberResource.errorOrNull != null, - isLoading = luckyNumberResource is Resource.Loading, - ) - ) - }) - } - .filterNot { (_, it) -> it.isLoading && forceRefresh } - .distinctUntilChanged() - .onEach { (_, it) -> - updateData(it, forceRefresh) - - if (it.isLoading) { - Timber.i("Loading horizontal group data started") - } else { - firstLoadedItemList += DashboardItem.Type.HORIZONTAL_GROUP - Timber.i("Loading horizontal group result: Success") - } - } - .catch { - Timber.i("Loading horizontal group result: An exception occurred") - updateData( - DashboardItem.HorizontalGroup(error = it), - forceRefresh, - ) - errorHandler.dispatch(it) - } - .launchWithUniqueRefreshJob("horizontal_group", forceRefresh) - } - - private fun loadGrades(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - - gradeRepository.getGrades(student, semester, forceRefresh) - } - .mapResourceData { (details, _) -> - val filteredSubjectWithGrades = details - .filter { it.date >= LocalDate.now().minusDays(7) } - .groupBy { it.subject } - .mapValues { entry -> - entry.value - .take(5) - .sortedByDescending { it.date } - } - .toList() - .sortedByDescending { (_, grades) -> grades[0].date } - .toMap() - - filteredSubjectWithGrades - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard grades data started") - if (forceRefresh) return@onEach - updateData( - DashboardItem.Grades( - subjectWithGrades = it.dataOrNull, - gradeTheme = preferencesRepository.gradeColorTheme, - isLoading = true - ), false - ) - - if (!it.dataOrNull.isNullOrEmpty()) { - firstLoadedItemList += DashboardItem.Type.GRADES - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard grades result: Success") - updateData( - DashboardItem.Grades( - subjectWithGrades = it.data, - gradeTheme = preferencesRepository.gradeColorTheme - ), - forceRefresh - ) - } - - is Resource.Error -> { - Timber.i("Loading dashboard grades result: An exception occurred") - errorHandler.dispatch(it.error) - updateData(DashboardItem.Grades(error = it.error), forceRefresh) - } - } - } - .launchWithUniqueRefreshJob("dashboard_grades", forceRefresh) - } - - private fun loadLessons(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - val date = when (isStudentHasLessonsOnWeekendUseCase(semester)) { - true -> LocalDate.now() - else -> LocalDate.now().nextOrSameSchoolDay - } - - timetableRepository.getTimetable( - student = student, - semester = semester, - start = date, - end = date.sunday, - forceRefresh = forceRefresh, - ) - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard lessons data started") - if (forceRefresh) return@onEach - updateData( - DashboardItem.Lessons(it.dataOrNull, isLoading = true), - false - ) - - if (!it.dataOrNull?.lessons.isNullOrEmpty()) { - firstLoadedItemList += DashboardItem.Type.LESSONS - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard lessons result: Success") - updateData( - DashboardItem.Lessons(it.data), forceRefresh - ) - } - - is Resource.Error -> { - Timber.i("Loading dashboard lessons result: An exception occurred") - errorHandler.dispatch(it.error) - updateData( - DashboardItem.Lessons(error = it.error), forceRefresh - ) - } - } - } - .launchWithUniqueRefreshJob("dashboard_lessons", forceRefresh) - } - - private fun loadHomework(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - val date = LocalDate.now().nextOrSameSchoolDay - - homeworkRepository.getHomework( - student = student, - semester = semester, - start = date, - end = date, - forceRefresh = forceRefresh - ) - } - .mapResourceData { homework -> - val currentDate = LocalDate.now() - - val filteredHomework = homework.filter { - (it.date.isAfter(currentDate) || it.date == currentDate) && !it.isDone - }.sortedBy { it.date } - - filteredHomework - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard homework data started") - if (forceRefresh) return@onEach - val data = it.dataOrNull.orEmpty() - updateData( - DashboardItem.Homework(data, isLoading = true), - false - ) - - if (data.isNotEmpty()) { - firstLoadedItemList += DashboardItem.Type.HOMEWORK - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard homework result: Success") - updateData(DashboardItem.Homework(it.data), forceRefresh) - } - - is Resource.Error -> { - Timber.i("Loading dashboard homework result: An exception occurred") - errorHandler.dispatch(it.error) - updateData(DashboardItem.Homework(error = it.error), forceRefresh) - } - } - } - .launchWithUniqueRefreshJob("dashboard_homework", forceRefresh) - } - - private fun loadSchoolAnnouncements(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh) - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard announcements data started") - if (forceRefresh) return@onEach - updateData( - DashboardItem.Announcements(it.dataOrNull.orEmpty(), isLoading = true), - false - ) - - if (!it.dataOrNull.isNullOrEmpty()) { - firstLoadedItemList += DashboardItem.Type.ANNOUNCEMENTS - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard announcements result: Success") - updateData(DashboardItem.Announcements(it.data), forceRefresh) - } - - is Resource.Error -> { - Timber.i("Loading dashboard announcements result: An exception occurred") - errorHandler.dispatch(it.error) - updateData(DashboardItem.Announcements(error = it.error), forceRefresh) - } - } - } - .launchWithUniqueRefreshJob("dashboard_announcements", forceRefresh) - } - - private fun loadExams(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - - examRepository.getExams( - student = student, - semester = semester, - start = LocalDate.now(), - end = LocalDate.now().plusDays(7), - forceRefresh = forceRefresh - ) - } - .mapResourceData { exams -> exams.sortedBy { exam -> exam.date } } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard exams data started") - if (forceRefresh) return@onEach - updateData( - DashboardItem.Exams(it.dataOrNull.orEmpty(), isLoading = true), - false - ) - - if (!it.dataOrNull.isNullOrEmpty()) { - firstLoadedItemList += DashboardItem.Type.EXAMS - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard exams result: Success") - updateData(DashboardItem.Exams(it.data), forceRefresh) - } - - is Resource.Error -> { - Timber.i("Loading dashboard exams result: An exception occurred") - errorHandler.dispatch(it.error) - updateData(DashboardItem.Exams(error = it.error), forceRefresh) - } - } - } - .launchWithUniqueRefreshJob("dashboard_exams", forceRefresh) - } - - private fun loadConferences(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - val semester = semesterRepository.getCurrentSemester(student) - - conferenceRepository.getConferences( - student = student, - semester = semester, - forceRefresh = forceRefresh, - startDate = Instant.now(), - ) - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard conferences data started") - if (forceRefresh) return@onEach - updateData( - DashboardItem.Conferences(it.dataOrNull.orEmpty(), isLoading = true), - false - ) - - if (!it.dataOrNull.isNullOrEmpty()) { - firstLoadedItemList += DashboardItem.Type.CONFERENCES - } - } - - is Resource.Success -> { - Timber.i("Loading dashboard conferences result: Success") - updateData(DashboardItem.Conferences(it.data), forceRefresh) - } - - is Resource.Error -> { - Timber.i("Loading dashboard conferences result: An exception occurred") - errorHandler.dispatch(it.error) - updateData(DashboardItem.Conferences(error = it.error), forceRefresh) - } - } - } - .launchWithUniqueRefreshJob("dashboard_conferences", forceRefresh) - } - - private fun loadAdminMessage(student: Student, forceRefresh: Boolean) { - flatResourceFlow { - getAppropriateAdminMessageUseCase( - student = student, - type = MessageType.DASHBOARD_MESSAGE, - ) - } - .onEach { - when (it) { - is Resource.Loading -> { - Timber.i("Loading dashboard admin message data started") - if (forceRefresh) return@onEach - updateData(DashboardItem.AdminMessages(), false) - } - - is Resource.Success -> { - Timber.i("Loading dashboard admin message result: Success") - updateData( - dashboardItem = DashboardItem.AdminMessages(adminMessage = it.data), - forceRefresh = forceRefresh - ) - } - - is Resource.Error -> { - Timber.i("Loading dashboard admin message result: An exception occurred") - Timber.e(it.error) - updateData( - dashboardItem = DashboardItem.AdminMessages( - adminMessage = null, - error = it.error - ), - forceRefresh = forceRefresh - ) - } - } - } - .launchWithUniqueRefreshJob("dashboard_admin_messages", forceRefresh) - } - - private fun loadAds(forceRefresh: Boolean) { - presenterScope.launch { - if (!forceRefresh) { - updateData(DashboardItem.Ads(), false) - } - - val dashboardAdItem = - runCatching { - DashboardItem.Ads(adsHelper.getDashboardTileAdBanner(view!!.tileWidth)) - } - .onFailure { Timber.e(it) } - .getOrElse { DashboardItem.Ads(error = it) } - - updateData(dashboardAdItem, forceRefresh) - } - } - - private fun updateData(dashboardItem: DashboardItem, forceRefresh: Boolean) { - val isForceRefreshError = forceRefresh && dashboardItem.error != null - val isFirstRunDataLoadedError = - dashboardItem.type in firstLoadedItemList && dashboardItem.error != null - - with(dashboardItemLoadedList) { - removeAll { it.type == dashboardItem.type && !isForceRefreshError && !isFirstRunDataLoadedError } - if (!isForceRefreshError && !isFirstRunDataLoadedError) add(dashboardItem) - } - - sortDashboardItems() - - if (dashboardItem is DashboardItem.AdminMessages) { - if (!dashboardItem.isDataLoaded) { - dashboardItemsToLoad = dashboardItemsToLoad - DashboardItem.Type.ADMIN_MESSAGE - dashboardTileLoadedList = dashboardTileLoadedList - DashboardItem.Tile.ADMIN_MESSAGE - - dashboardItemLoadedList.removeAll { it.type == DashboardItem.Type.ADMIN_MESSAGE } - } else { - dashboardItemsToLoad = dashboardItemsToLoad + DashboardItem.Type.ADMIN_MESSAGE - dashboardTileLoadedList = dashboardTileLoadedList + DashboardItem.Tile.ADMIN_MESSAGE - } - } - - if (dashboardItem is DashboardItem.Ads) { - if (!dashboardItem.isDataLoaded) { - dashboardItemsToLoad = dashboardItemsToLoad - DashboardItem.Type.ADS - dashboardTileLoadedList = dashboardTileLoadedList - DashboardItem.Tile.ADS - - dashboardItemLoadedList.removeAll { it.type == DashboardItem.Type.ADS } - } else { - dashboardItemsToLoad = dashboardItemsToLoad + DashboardItem.Type.ADS - dashboardTileLoadedList = dashboardTileLoadedList + DashboardItem.Tile.ADS - } - } - - if (forceRefresh) { - updateForceRefreshData(dashboardItem) - } else { - updateNormalData() - } - } - - private fun updateNormalData() { - val isItemsLoaded = - dashboardItemsToLoad.all { type -> dashboardItemLoadedList.any { it.type == type } } - val isItemsDataLoaded = isItemsLoaded && dashboardItemLoadedList.all { - it.isDataLoaded || it.error != null - } - - if (isItemsDataLoaded) { - view?.run { - showProgress(false) - showErrorView(false) - showContent(true) - updateData(dashboardItemLoadedList.toList()) - } - } - - showErrorIfExists( - isItemsLoaded = isItemsLoaded, - itemsLoadedList = dashboardItemLoadedList, - forceRefresh = false - ) - } - - private fun updateForceRefreshData(dashboardItem: DashboardItem) { - val isNotLoadedAdminMessage = - dashboardItem is DashboardItem.AdminMessages && !dashboardItem.isDataLoaded - - with(dashboardItemRefreshLoadedList) { - removeAll { it.type == dashboardItem.type } - if (!isNotLoadedAdminMessage) add(dashboardItem) - } - - val isRefreshItemLoaded = - dashboardItemsToLoad.all { type -> dashboardItemRefreshLoadedList.any { it.type == type } } - val isRefreshItemsDataLoaded = isRefreshItemLoaded && dashboardItemRefreshLoadedList.all { - it.isDataLoaded || it.error != null - } - - if (isRefreshItemsDataLoaded) { - view?.run { - showRefresh(false) - showErrorView(false) - showContent(true) - updateData(dashboardItemLoadedList.toList()) - } - } - - showErrorIfExists( - isItemsLoaded = isRefreshItemLoaded, - itemsLoadedList = dashboardItemRefreshLoadedList, - forceRefresh = true - ) - - if (isRefreshItemsDataLoaded) dashboardItemRefreshLoadedList.clear() - } - - private fun showErrorIfExists( - isItemsLoaded: Boolean, - itemsLoadedList: List, - forceRefresh: Boolean - ) { - val filteredItems = itemsLoadedList.filterNot { - it.type == DashboardItem.Type.ACCOUNT || it.type == DashboardItem.Type.ADMIN_MESSAGE - } - val dataLoadedAdminMessageItem = - itemsLoadedList.find { it.type == DashboardItem.Type.ADMIN_MESSAGE && it.isDataLoaded } as DashboardItem.AdminMessages? - val isAccountItemError = - itemsLoadedList.find { it.type == DashboardItem.Type.ACCOUNT }?.error != null - val isGeneralError = - filteredItems.none { it.error == null } && filteredItems.isNotEmpty() || isAccountItemError - val firstError = itemsLoadedList.firstNotNullOfOrNull { it.error } - - val filteredOriginalLoadedList = - dashboardItemLoadedList.filterNot { it.type == DashboardItem.Type.ACCOUNT } - val wasAccountItemError = - dashboardItemLoadedList.find { it.type == DashboardItem.Type.ACCOUNT }?.error != null - val wasGeneralError = - filteredOriginalLoadedList.none { it.error == null } && filteredOriginalLoadedList.isNotEmpty() || wasAccountItemError - - if (isGeneralError && isItemsLoaded) { - lastError = requireNotNull(firstError) - - view?.run { - showProgress(false) - showRefresh(false) - if ((forceRefresh && wasGeneralError) || !forceRefresh) { - showContent(false) - showErrorView(true, dataLoadedAdminMessageItem) - setErrorDetails(lastError) - } - } - } - } - - private fun sortDashboardItems() { - val dashboardItemsPosition = preferencesRepository.dashboardItemsPosition - - dashboardItemLoadedList.sortBy { tile -> - val defaultPosition = if (tile is DashboardItem.AdminMessages) { - -1 - } else { - tile.type.ordinal + 100 - } - - dashboardItemsPosition?.getOrDefault(tile.type, defaultPosition) ?: tile.type.ordinal - } - } - - private fun Flow>.launchWithUniqueRefreshJob(name: String, forceRefresh: Boolean) { - val jobName = if (forceRefresh) "$name-forceRefresh" else name - - if (forceRefresh) { - onEach { - if (it is Resource.Success) { - cancelJobs(jobName) - } else if (it is Resource.Error) { - cancelJobs(jobName) - } - }.launch(jobName) - } else { - launch(jobName) - } - } - - @JvmName("launchWithUniqueRefreshJobHorizontalGroup") - private fun Flow>, *>>.launchWithUniqueRefreshJob( - name: String, - forceRefresh: Boolean - ) { - val jobName = if (forceRefresh) "$name-forceRefresh" else name - - if (forceRefresh) { - onEach { (resources, _) -> - if (resources.all { it is Resource.Success<*> }) { - cancelJobs(jobName) - } else if (resources.any { it is Resource.Error<*> }) { - cancelJobs(jobName) - } - }.launch(jobName) - } else { - launch(jobName) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt deleted file mode 100644 index 56a0a773..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardView.kt +++ /dev/null @@ -1,34 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard - -import io.github.wulkanowy.ui.base.BaseView - -interface DashboardView : BaseView { - - val tileWidth: Int - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun showDashboardTileSettings(selectedItems: List) - - fun showProgress(show: Boolean) - - fun showContent(show: Boolean) - - fun showRefresh(show: Boolean) - - fun showErrorView(show: Boolean, adminMessageItem: DashboardItem.AdminMessages? = null) - - fun setErrorDetails(error: Throwable) - - fun resetView() - - fun popViewToRoot() - - fun openNotificationsCenterView() - - fun openInternetBrowser(url: String) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt deleted file mode 100644 index 7c74cae8..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt +++ /dev/null @@ -1,819 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.annotation.SuppressLint -import android.graphics.Typeface -import android.os.Handler -import android.os.Looper -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.constraintlayout.widget.ConstraintLayout -import androidx.core.text.parseAsHtml -import androidx.core.view.isVisible -import androidx.core.view.updateLayoutParams -import androidx.core.view.updateMarginsRelative -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableHeader -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.databinding.* -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder -import io.github.wulkanowy.utils.* -import timber.log.Timber -import java.time.Duration -import java.time.Instant -import java.time.LocalDate -import java.time.LocalDateTime -import java.util.* -import javax.inject.Inject -import kotlin.concurrent.timer - -class DashboardAdapter @Inject constructor() : RecyclerView.Adapter() { - - private var lessonsTimer: Timer? = null - - var onAccountTileClickListener: (Student) -> Unit = {} - - var onLuckyNumberTileClickListener: () -> Unit = {} - - var onMessageTileClickListener: () -> Unit = {} - - var onGradeTileClickListener: () -> Unit = {} - - var onAttendanceTileClickListener: () -> Unit = {} - - var onLessonsTileClickListener: (LocalDate) -> Unit = {} - - var onHomeworkTileClickListener: () -> Unit = {} - - var onAnnouncementsTileClickListener: () -> Unit = {} - - var onExamsTileClickListener: () -> Unit = {} - - var onConferencesTileClickListener: () -> Unit = {} - - var onAdminMessageClickListener: (String?) -> Unit = {} - - var onAdminMessageDismissClickListener: (AdminMessage) -> Unit = {} - - val items = mutableListOf() - - fun submitList(newItems: List) { - val diffResult = - DiffUtil.calculateDiff(DiffCallback(newItems, items.toMutableList())) - - with(items) { - clear() - addAll(newItems) - } - - diffResult.dispatchUpdatesTo(this) - } - - override fun getItemCount() = items.size - - override fun getItemViewType(position: Int) = items[position].type.ordinal - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val inflater = LayoutInflater.from(parent.context) - - return when (viewType) { - DashboardItem.Type.ACCOUNT.ordinal -> AccountViewHolder( - ItemDashboardAccountBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.HORIZONTAL_GROUP.ordinal -> HorizontalGroupViewHolder( - ItemDashboardHorizontalGroupBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.GRADES.ordinal -> GradesViewHolder( - ItemDashboardGradesBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.LESSONS.ordinal -> LessonsViewHolder( - ItemDashboardLessonsBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.HOMEWORK.ordinal -> HomeworkViewHolder( - ItemDashboardHomeworkBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.ANNOUNCEMENTS.ordinal -> AnnouncementsViewHolder( - ItemDashboardAnnouncementsBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.EXAMS.ordinal -> ExamsViewHolder( - ItemDashboardExamsBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.CONFERENCES.ordinal -> ConferencesViewHolder( - ItemDashboardConferencesBinding.inflate(inflater, parent, false) - ) - DashboardItem.Type.ADMIN_MESSAGE.ordinal -> AdminMessageViewHolder( - ItemDashboardAdminMessageBinding.inflate(inflater, parent, false), - onAdminMessageDismissClickListener = onAdminMessageDismissClickListener, - onAdminMessageClickListener = onAdminMessageClickListener, - ) - DashboardItem.Type.ADS.ordinal -> AdsViewHolder( - ItemDashboardAdsBinding.inflate(inflater, parent, false) - ) - else -> throw IllegalArgumentException() - } - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - when (holder) { - is AccountViewHolder -> bindAccountViewHolder(holder, position) - is HorizontalGroupViewHolder -> bindHorizontalGroupViewHolder(holder, position) - is GradesViewHolder -> bindGradesViewHolder(holder, position) - is LessonsViewHolder -> bindLessonsViewHolder(holder, position) - is HomeworkViewHolder -> bindHomeworkViewHolder(holder, position) - is AnnouncementsViewHolder -> bindAnnouncementsViewHolder(holder, position) - is ExamsViewHolder -> bindExamsViewHolder(holder, position) - is ConferencesViewHolder -> bindConferencesViewHolder(holder, position) - is AdminMessageViewHolder -> holder.bind((items[position] as DashboardItem.AdminMessages).adminMessage) - is AdsViewHolder -> bindAdsViewHolder(holder, position) - } - } - - fun clearTimers() { - lessonsTimer?.let { - it.cancel() - it.purge() - } - lessonsTimer = null - } - - private fun bindAccountViewHolder(accountViewHolder: AccountViewHolder, position: Int) { - val item = items[position] as DashboardItem.Account - val student = item.student - val isLoading = item.isLoading - - val avatar = student?.let { - accountViewHolder.binding.root.context.createNameInitialsDrawable( - text = it.nickOrName, - backgroundColor = it.avatarColor - ) - } - - with(accountViewHolder.binding) { - dashboardAccountItemContent.isVisible = !isLoading - dashboardAccountItemProgress.isVisible = isLoading - - dashboardAccountItemAvatar.setImageDrawable(avatar) - dashboardAccountItemName.text = student?.nickOrName.orEmpty() - dashboardAccountItemSchoolName.text = student?.schoolName.orEmpty() - - root.setOnClickListener { student?.let(onAccountTileClickListener) } - } - } - - @SuppressLint("SetTextI18n") - private fun bindHorizontalGroupViewHolder( - horizontalGroupViewHolder: HorizontalGroupViewHolder, - position: Int - ) { - val item = items[position] as DashboardItem.HorizontalGroup - val isLoadingVisible = - (item.isLoading && !item.isDataLoaded) || (item.isLoading && !item.isFullDataLoaded) - val isWideErrorShow = isLoadingVisible || item.error != null - - with(horizontalGroupViewHolder.binding) { - dashboardHorizontalGroupItemInfoContainer.isVisible = isWideErrorShow - dashboardHorizontalGroupItemInfoProgress.isVisible = isLoadingVisible - dashboardHorizontalGroupItemInfoErrorText.isVisible = item.error != null - - bindLuckyNumber(item, isWideErrorShow) - bindMessages(item, isWideErrorShow) - bindAttendance(item, isWideErrorShow) - } - } - - private fun ItemDashboardHorizontalGroupBinding.bindLuckyNumber( - item: DashboardItem.HorizontalGroup, - isWideErrorShow: Boolean - ) { - with(dashboardHorizontalGroupItemLuckyValue) { - isVisible = item.luckyNumber?.error != true - text = if (item.luckyNumber?.data == 0) { - context.getString(R.string.dashboard_horizontal_group_no_data) - } else item.luckyNumber?.data?.toString() - } - dashboardHorizontalGroupItemLuckyError.isVisible = item.luckyNumber?.error == true - with(dashboardHorizontalGroupItemLuckyContainer) { - isVisible = item.luckyNumber?.isHidden == false && !isWideErrorShow - setOnClickListener { onLuckyNumberTileClickListener() } - - val isAttendanceHidden = item.attendancePercentage?.isHidden == true - val isMessagesHidden = item.unreadMessagesCount?.isHidden == true - val isLuckyNumberHidden = item.luckyNumber?.isHidden == true - - updateLayoutParams { - updateMarginsRelative( - end = if (isAttendanceHidden && isMessagesHidden && !isLuckyNumberHidden) { - 0 - } else context.dpToPx(8f).toInt() - ) - } - } - } - - private fun ItemDashboardHorizontalGroupBinding.bindMessages( - item: DashboardItem.HorizontalGroup, - isWideErrorShow: Boolean - ) { - dashboardHorizontalGroupItemMessageError.isVisible = item.unreadMessagesCount?.error == true - with(dashboardHorizontalGroupItemMessageValue) { - isVisible = item.unreadMessagesCount?.error != true - text = item.unreadMessagesCount?.data.toString() - } - with(dashboardHorizontalGroupItemMessageContainer) { - isVisible = item.unreadMessagesCount?.isHidden == false && !isWideErrorShow - setOnClickListener { onMessageTileClickListener() } - } - } - - private fun ItemDashboardHorizontalGroupBinding.bindAttendance( - item: DashboardItem.HorizontalGroup, - isWideErrorShow: Boolean - ) { - val attendancePercentage = item.attendancePercentage?.data - val attendanceColor = when { - attendancePercentage == null || attendancePercentage == .0 -> { - root.context.getThemeAttrColor(R.attr.colorOnSurface) - } - attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> { - root.context.getThemeAttrColor(R.attr.colorPrimary) - } - attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> { - root.context.getThemeAttrColor(R.attr.colorTimetableChange) - } - else -> root.context.getThemeAttrColor(R.attr.colorOnSurface) - } - val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) { - root.context.getString(R.string.dashboard_horizontal_group_no_data) - } else { - "%.2f%%".format(attendancePercentage) - } - - dashboardHorizontalGroupItemAttendanceError.isVisible = - item.attendancePercentage?.error == true - with(dashboardHorizontalGroupItemAttendanceValue) { - isVisible = item.attendancePercentage?.error != true - text = attendanceString - setTextColor(attendanceColor) - } - with(dashboardHorizontalGroupItemAttendanceContainer) { - isVisible = item.attendancePercentage?.isHidden == false && !isWideErrorShow - setOnClickListener { onAttendanceTileClickListener() } - updateLayoutParams { - matchConstraintPercentWidth = when { - item.luckyNumber?.isHidden == true && item.unreadMessagesCount?.isHidden == true -> 1.0f - item.luckyNumber?.isHidden == true || item.unreadMessagesCount?.isHidden == true -> 0.5f - else -> 0.4f - } - } - } - } - - private fun bindGradesViewHolder(gradesViewHolder: GradesViewHolder, position: Int) { - val item = items[position] as DashboardItem.Grades - val subjectWithGrades = item.subjectWithGrades.orEmpty() - val gradeTheme = item.gradeTheme - val error = item.error - val isLoading = item.isLoading - val dashboardGradesAdapter = gradesViewHolder.adapter.apply { - this.items = subjectWithGrades.toList() - this.gradeColorTheme = gradeTheme ?: GradeColorTheme.VULCAN - } - - with(gradesViewHolder.binding) { - dashboardGradesItemEmpty.isVisible = - subjectWithGrades.isEmpty() && error == null && !isLoading - dashboardGradesItemError.isVisible = error != null && !isLoading - dashboardGradesItemProgress.isVisible = - isLoading && error == null && subjectWithGrades.isEmpty() - - with(dashboardGradesItemRecycler) { - adapter = dashboardGradesAdapter - layoutManager = LinearLayoutManager(context) - isVisible = subjectWithGrades.isNotEmpty() && error == null - suppressLayout(true) - } - - root.setOnClickListener { onGradeTileClickListener() } - } - } - - private fun bindLessonsViewHolder(lessonsViewHolder: LessonsViewHolder, position: Int) { - val item = items[position] as DashboardItem.Lessons - val timetableFull = item.lessons - val binding = lessonsViewHolder.binding - var dateToNavigate = LocalDate.now() - - fun updateLessonState() { - val currentDateTime = Instant.now() - val currentDate = LocalDate.now() - val tomorrowDate = currentDate.plusDays(1) - - val currentTimetable = timetableFull?.lessons - .orEmpty() - .filter { it.date == currentDate } - .filter { it.end.isAfter(currentDateTime) } - .filterNot { it.canceled } - val currentDayHeader = - timetableFull?.headers.orEmpty().singleOrNull { it.date == currentDate } - - val tomorrowTimetable = timetableFull?.lessons - .orEmpty() - .filter { it.date == currentDate.plusDays(1) } - .filterNot { it.canceled } - val tomorrowDayHeader = - timetableFull?.headers.orEmpty().singleOrNull { it.date == currentDate.plusDays(1) } - - when { - currentTimetable.isNotEmpty() -> { - dateToNavigate = currentDate - updateLessonView(item, currentTimetable, binding) - binding.dashboardLessonsItemTitleTomorrow.isVisible = false - binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false - } - tomorrowTimetable.isNotEmpty() -> { - dateToNavigate = tomorrowDate - updateLessonView(item, tomorrowTimetable, binding) - binding.dashboardLessonsItemTitleTomorrow.isVisible = true - binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false - } - currentDayHeader != null && currentDayHeader.content.isNotBlank() -> { - dateToNavigate = currentDate - updateLessonView(item, emptyList(), binding, currentDayHeader) - binding.dashboardLessonsItemTitleTomorrow.isVisible = false - binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false - } - tomorrowDayHeader != null && tomorrowDayHeader.content.isNotBlank() -> { - dateToNavigate = tomorrowDate - updateLessonView(item, emptyList(), binding, tomorrowDayHeader) - binding.dashboardLessonsItemTitleTomorrow.isVisible = true - binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = false - } - else -> { - dateToNavigate = currentDate - updateLessonView(item, emptyList(), binding) - binding.dashboardLessonsItemTitleTomorrow.isVisible = false - binding.dashboardLessonsItemTitleTodayAndTomorrow.isVisible = - !(item.isLoading && item.error == null) - } - } - } - - updateLessonState() - - lessonsTimer?.cancel() - lessonsTimer = timer(period = 1000) { - Handler(Looper.getMainLooper()).post { updateLessonState() } - } - - binding.root.setOnClickListener { onLessonsTileClickListener(dateToNavigate) } - } - - private fun updateLessonView( - item: DashboardItem.Lessons, - timetableToShow: List, - binding: ItemDashboardLessonsBinding, - header: TimetableHeader? = null, - ) { - val currentDateTime = Instant.now() - val nextLessons = timetableToShow.filter { it.end.isAfter(currentDateTime) } - .sortedBy { it.start } - - with(binding) { - dashboardLessonsItemEmpty.isVisible = - (timetableToShow.isEmpty() || nextLessons.isEmpty()) && item.error == null && header == null && !item.isLoading - dashboardLessonsItemError.isVisible = item.error != null && !item.isLoading - dashboardLessonsItemProgress.isVisible = - item.isLoading && (timetableToShow.isEmpty() || nextLessons.isEmpty()) && item.error == null && header == null - - val secondLesson = nextLessons.getOrNull(1) - val firstLesson = nextLessons.getOrNull(0) - - updateFirstLessonView(binding, firstLesson, currentDateTime) - updateSecondLesson(binding, firstLesson, secondLesson) - updateLessonSummary(binding, nextLessons) - updateLessonHeader(binding, header) - } - } - - @SuppressLint("SetTextI18n") - private fun updateFirstLessonView( - binding: ItemDashboardLessonsBinding, - firstLesson: Timetable?, - currentDateTime: Instant - ) { - val context = binding.root.context - val sansSerifFont = Typeface.create("sans-serif", Typeface.NORMAL) - val sansSerifMediumFont = Typeface.create("sans-serif-medium", Typeface.NORMAL) - - with(binding) { - dashboardLessonsItemFirstTitle.isVisible = firstLesson != null - dashboardLessonsItemFirstTime.isVisible = firstLesson != null - dashboardLessonsItemFirstTimeRange.isVisible = firstLesson != null - dashboardLessonsItemFirstValue.isVisible = firstLesson != null - } - - firstLesson ?: return - - val minutesToStartLesson = - Duration.between(currentDateTime, firstLesson.start).toMinutes() + 1 - val isFirstTimeVisible: Boolean - val isFirstTimeRangeVisible: Boolean - val firstTimeText: String - val firstTimeRangeText: String - val firstTitleText: String - val firstTitleAndValueTextColor: Int - val firstTitleAndValueTextFont: Typeface - - if (currentDateTime < firstLesson.start) { - if (minutesToStartLesson > 60) { - val formattedStartTime = firstLesson.start.toFormattedString("HH:mm") - val formattedEndTime = firstLesson.end.toFormattedString("HH:mm") - - firstTimeRangeText = "$formattedStartTime - $formattedEndTime" - firstTimeText = "" - - isFirstTimeRangeVisible = true - isFirstTimeVisible = false - } else { - firstTimeText = context.getString( - R.string.timetable_time_until, - context.getString( - R.string.timetable_minutes, - minutesToStartLesson.toString() - ) - ) - firstTimeRangeText = "" - - isFirstTimeRangeVisible = false - isFirstTimeVisible = true - } - - when { - minutesToStartLesson < 60 -> { - firstTitleAndValueTextColor = context.getThemeAttrColor(R.attr.colorPrimary) - firstTitleAndValueTextFont = sansSerifMediumFont - firstTitleText = - context.getString(R.string.dashboard_timetable_first_lesson_title_moment) - } - minutesToStartLesson < 240 -> { - firstTitleAndValueTextColor = - context.getThemeAttrColor(R.attr.colorOnSurface) - firstTitleAndValueTextFont = sansSerifFont - firstTitleText = - context.getString(R.string.dashboard_timetable_first_lesson_title_soon) - } - else -> { - firstTitleAndValueTextColor = - context.getThemeAttrColor(R.attr.colorOnSurface) - firstTitleAndValueTextFont = sansSerifFont - firstTitleText = - context.getString(R.string.dashboard_timetable_first_lesson_title_first) - } - } - } else { - val minutesToEndLesson = firstLesson.left?.toMinutes()?.plus(1) ?: run { - Timber.e(IllegalArgumentException("Lesson left is null. START ${firstLesson.start} ; END ${firstLesson.end} ; CURRENT ${LocalDateTime.now()}")) - 0 - } - - firstTimeText = context.getString( - R.string.timetable_time_left, - context.getString( - R.string.timetable_minutes, - minutesToEndLesson.toString() - ) - ) - firstTimeRangeText = "" - - isFirstTimeRangeVisible = false - isFirstTimeVisible = true - - firstTitleAndValueTextColor = context.getThemeAttrColor(R.attr.colorPrimary) - firstTitleAndValueTextFont = sansSerifMediumFont - firstTitleText = context.getString(R.string.dashboard_timetable_first_lesson_title_now) - } - - with(binding.dashboardLessonsItemFirstTime) { - isVisible = isFirstTimeVisible - text = firstTimeText - } - with(binding.dashboardLessonsItemFirstTimeRange) { - isVisible = isFirstTimeRangeVisible - text = firstTimeRangeText - } - with(binding.dashboardLessonsItemFirstTitle) { - setTextColor(firstTitleAndValueTextColor) - typeface = firstTitleAndValueTextFont - text = firstTitleText - } - with(binding.dashboardLessonsItemFirstValue) { - setTextColor(firstTitleAndValueTextColor) - typeface = firstTitleAndValueTextFont - text = - "${firstLesson.subject} ${if (firstLesson.room.isNotBlank()) "(${firstLesson.room})" else ""}" - } - } - - private fun updateSecondLesson( - binding: ItemDashboardLessonsBinding, - firstLesson: Timetable?, - secondLesson: Timetable? - ) { - val context = binding.root.context - - val formattedStartTime = secondLesson?.start?.toFormattedString("HH:mm") - val formattedEndTime = secondLesson?.end?.toFormattedString("HH:mm") - - val secondTimeText = "$formattedStartTime - $formattedEndTime" - val secondValueText = if (secondLesson != null) { - val roomString = if (secondLesson.room.isNotBlank()) "(${secondLesson.room})" else "" - - "${secondLesson.subject} $roomString" - } else { - context.getString(R.string.dashboard_timetable_second_lesson_value_end) - } - - with(binding.dashboardLessonsItemSecondTime) { - isVisible = secondLesson != null - text = secondTimeText - } - with(binding.dashboardLessonsItemSecondValue) { - isVisible = !(secondLesson == null && firstLesson == null) - text = secondValueText - } - binding.dashboardLessonsItemSecondTitle.isVisible = - !(secondLesson == null && firstLesson == null) - } - - private fun updateLessonSummary( - binding: ItemDashboardLessonsBinding, - nextLessons: List - ) { - val context = binding.root.context - val formattedEndTime = nextLessons.lastOrNull()?.end?.toFormattedString("HH:mm") - - with(binding) { - dashboardLessonsItemThirdTime.isVisible = - nextLessons.size > LESSON_SUMMARY_VISIBILITY_THRESHOLD - dashboardLessonsItemThirdTitle.isVisible = - nextLessons.size > LESSON_SUMMARY_VISIBILITY_THRESHOLD - dashboardLessonsItemThirdValue.isVisible = - nextLessons.size > LESSON_SUMMARY_VISIBILITY_THRESHOLD - dashboardLessonsItemDivider.isVisible = - nextLessons.size > LESSON_SUMMARY_VISIBILITY_THRESHOLD - - dashboardLessonsItemThirdValue.text = context.resources.getQuantityString( - R.plurals.dashboard_timetable_third_value, - nextLessons.size - LESSON_SUMMARY_VISIBILITY_THRESHOLD, - nextLessons.size - LESSON_SUMMARY_VISIBILITY_THRESHOLD - ) - dashboardLessonsItemThirdTime.text = - context.getString(R.string.dashboard_timetable_third_time, formattedEndTime) - } - } - - private fun updateLessonHeader( - binding: ItemDashboardLessonsBinding, - header: TimetableHeader? - ) { - with(binding.dashboardLessonsItemDayHeader) { - isVisible = header != null - text = header?.content?.parseAsHtml() - } - } - - private fun bindHomeworkViewHolder(homeworkViewHolder: HomeworkViewHolder, position: Int) { - val item = items[position] as DashboardItem.Homework - val homeworkList = item.homework.orEmpty() - val error = item.error - val isLoading = item.isLoading - val context = homeworkViewHolder.binding.root.context - val homeworkAdapter = homeworkViewHolder.adapter.apply { - this.items = homeworkList.take(MAX_VISIBLE_LIST_ITEMS) - } - - with(homeworkViewHolder.binding) { - dashboardHomeworkItemEmpty.isVisible = - homeworkList.isEmpty() && error == null && !isLoading - dashboardHomeworkItemError.isVisible = error != null && !isLoading - dashboardHomeworkItemProgress.isVisible = - isLoading && error == null && homeworkList.isEmpty() - dashboardHomeworkItemDivider.isVisible = homeworkList.size > MAX_VISIBLE_LIST_ITEMS - dashboardHomeworkItemMore.isVisible = homeworkList.size > MAX_VISIBLE_LIST_ITEMS - dashboardHomeworkItemMore.text = context.resources.getQuantityString( - R.plurals.dashboard_homework_more, - homeworkList.size - MAX_VISIBLE_LIST_ITEMS, - homeworkList.size - MAX_VISIBLE_LIST_ITEMS - ) - - with(dashboardHomeworkItemRecycler) { - adapter = homeworkAdapter - layoutManager = LinearLayoutManager(context) - isVisible = homeworkList.isNotEmpty() && error == null - suppressLayout(true) - } - - root.setOnClickListener { onHomeworkTileClickListener() } - } - } - - private fun bindAnnouncementsViewHolder( - announcementsViewHolder: AnnouncementsViewHolder, - position: Int - ) { - val item = items[position] as DashboardItem.Announcements - val schoolAnnouncementList = item.announcement.orEmpty() - val error = item.error - val isLoading = item.isLoading - val context = announcementsViewHolder.binding.root.context - val schoolAnnouncementsAdapter = announcementsViewHolder.adapter.apply { - this.items = schoolAnnouncementList.take(MAX_VISIBLE_LIST_ITEMS) - } - - with(announcementsViewHolder.binding) { - dashboardAnnouncementsItemEmpty.isVisible = - schoolAnnouncementList.isEmpty() && error == null && !isLoading - dashboardAnnouncementsItemError.isVisible = error != null && !isLoading - dashboardAnnouncementsItemProgress.isVisible = - isLoading && error == null && schoolAnnouncementList.isEmpty() - dashboardAnnouncementsItemDivider.isVisible = - schoolAnnouncementList.size > MAX_VISIBLE_LIST_ITEMS - dashboardAnnouncementsItemMore.isVisible = - schoolAnnouncementList.size > MAX_VISIBLE_LIST_ITEMS - dashboardAnnouncementsItemMore.text = context.resources.getQuantityString( - R.plurals.dashboard_announcements_more, - schoolAnnouncementList.size - MAX_VISIBLE_LIST_ITEMS, - schoolAnnouncementList.size - MAX_VISIBLE_LIST_ITEMS - ) - - with(dashboardAnnouncementsItemRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = schoolAnnouncementsAdapter - isVisible = schoolAnnouncementList.isNotEmpty() && error == null - suppressLayout(true) - } - - root.setOnClickListener { onAnnouncementsTileClickListener() } - } - } - - private fun bindExamsViewHolder(examsViewHolder: ExamsViewHolder, position: Int) { - val item = items[position] as DashboardItem.Exams - val exams = item.exams.orEmpty() - val error = item.error - val isLoading = item.isLoading - val context = examsViewHolder.binding.root.context - val examAdapter = examsViewHolder.adapter.apply { - this.items = exams.take(MAX_VISIBLE_LIST_ITEMS) - } - - with(examsViewHolder.binding) { - dashboardExamsItemEmpty.isVisible = exams.isEmpty() && error == null && !isLoading - dashboardExamsItemError.isVisible = error != null && !isLoading - dashboardExamsItemProgress.isVisible = isLoading && error == null && exams.isEmpty() - dashboardExamsItemDivider.isVisible = exams.size > MAX_VISIBLE_LIST_ITEMS - dashboardExamsItemMore.isVisible = exams.size > MAX_VISIBLE_LIST_ITEMS - dashboardExamsItemMore.text = context.resources.getQuantityString( - R.plurals.dashboard_exams_more, - exams.size - MAX_VISIBLE_LIST_ITEMS, - exams.size - MAX_VISIBLE_LIST_ITEMS - ) - - with(dashboardExamsItemRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = examAdapter - isVisible = exams.isNotEmpty() && error == null - suppressLayout(true) - } - - root.setOnClickListener { onExamsTileClickListener() } - } - } - - private fun bindConferencesViewHolder( - conferencesViewHolder: ConferencesViewHolder, - position: Int - ) { - val item = items[position] as DashboardItem.Conferences - val conferences = item.conferences.orEmpty() - val error = item.error - val isLoading = item.isLoading - val context = conferencesViewHolder.binding.root.context - val conferenceAdapter = conferencesViewHolder.adapter.apply { - this.items = conferences.take(MAX_VISIBLE_LIST_ITEMS) - } - - with(conferencesViewHolder.binding) { - dashboardConferencesItemEmpty.isVisible = - conferences.isEmpty() && error == null && !isLoading - dashboardConferencesItemError.isVisible = error != null && !isLoading - dashboardConferencesItemProgress.isVisible = - isLoading && error == null && conferences.isEmpty() - dashboardConferencesItemDivider.isVisible = conferences.size > MAX_VISIBLE_LIST_ITEMS - dashboardConferencesItemMore.isVisible = conferences.size > MAX_VISIBLE_LIST_ITEMS - dashboardConferencesItemMore.text = context.resources.getQuantityString( - R.plurals.dashboard_conference_more, - conferences.size - MAX_VISIBLE_LIST_ITEMS, - conferences.size - MAX_VISIBLE_LIST_ITEMS - ) - - with(dashboardConferencesItemRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = conferenceAdapter - isVisible = conferences.isNotEmpty() && error == null - suppressLayout(true) - } - - root.setOnClickListener { onConferencesTileClickListener() } - } - } - - private fun bindAdsViewHolder(adsViewHolder: AdsViewHolder, position: Int) { - val item = (items[position] as DashboardItem.Ads).adBanner ?: return - val binding = adsViewHolder.binding - - binding.dashboardAdminMessageItemContent.removeAllViews() - binding.dashboardAdminMessageItemContent.addView( - item.view, - ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) - ) - } - - class AccountViewHolder(val binding: ItemDashboardAccountBinding) : - RecyclerView.ViewHolder(binding.root) - - class HorizontalGroupViewHolder(val binding: ItemDashboardHorizontalGroupBinding) : - RecyclerView.ViewHolder(binding.root) - - class GradesViewHolder(val binding: ItemDashboardGradesBinding) : - RecyclerView.ViewHolder(binding.root) { - - val adapter by lazy { DashboardGradesAdapter() } - } - - class LessonsViewHolder(val binding: ItemDashboardLessonsBinding) : - RecyclerView.ViewHolder(binding.root) - - class HomeworkViewHolder(val binding: ItemDashboardHomeworkBinding) : - RecyclerView.ViewHolder(binding.root) { - - val adapter by lazy { DashboardHomeworkAdapter() } - } - - class AnnouncementsViewHolder(val binding: ItemDashboardAnnouncementsBinding) : - RecyclerView.ViewHolder(binding.root) { - - val adapter by lazy { DashboardAnnouncementsAdapter() } - } - - class ExamsViewHolder(val binding: ItemDashboardExamsBinding) : - RecyclerView.ViewHolder(binding.root) { - - val adapter by lazy { DashboardExamsAdapter() } - } - - class ConferencesViewHolder(val binding: ItemDashboardConferencesBinding) : - RecyclerView.ViewHolder(binding.root) { - - val adapter by lazy { DashboardConferencesAdapter() } - } - - class AdsViewHolder(val binding: ItemDashboardAdsBinding) : - RecyclerView.ViewHolder(binding.root) - - private class DiffCallback( - private val newList: List, - private val oldList: List - ) : DiffUtil.Callback() { - - override fun getNewListSize() = newList.size - - override fun getOldListSize() = oldList.size - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = - newList[newItemPosition] == oldList[oldItemPosition] - - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) = - newList[newItemPosition].type == oldList[oldItemPosition].type - } - - private companion object { - - private const val LESSON_SUMMARY_VISIBILITY_THRESHOLD = 2 - - private const val MAX_VISIBLE_LIST_ITEMS = 5 - - private const val ATTENDANCE_FIRST_WARNING_THRESHOLD = 75.0 - - private const val ATTENDANCE_SECOND_WARNING_THRESHOLD = 50.0 - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAnnouncementsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAnnouncementsAdapter.kt deleted file mode 100644 index da588015..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAnnouncementsAdapter.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.databinding.SubitemDashboardAnnouncementsBinding -import io.github.wulkanowy.utils.toFormattedString - -class DashboardAnnouncementsAdapter : - RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - SubitemDashboardAnnouncementsBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - dashboardHomeworkSubitemTime.text = item.date.toFormattedString() - dashboardHomeworkSubitemTitle.text = item.subject - } - } - - class ViewHolder(val binding: SubitemDashboardAnnouncementsBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardConferencesAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardConferencesAdapter.kt deleted file mode 100644 index 1244ff60..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardConferencesAdapter.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.Conference -import io.github.wulkanowy.databinding.SubitemDashboardConferencesBinding -import io.github.wulkanowy.utils.toFormattedString - -class DashboardConferencesAdapter : - RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - SubitemDashboardConferencesBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - dashboardHomeworkSubitemTime.text = item.date.toFormattedString("HH:mm dd.MM.yyyy") - dashboardHomeworkSubitemTitle.text = item.title - } - } - - class ViewHolder(val binding: SubitemDashboardConferencesBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardExamsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardExamsAdapter.kt deleted file mode 100644 index 583bf29d..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardExamsAdapter.kt +++ /dev/null @@ -1,59 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Exam -import io.github.wulkanowy.databinding.SubitemDashboardExamsBinding -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate - -class DashboardExamsAdapter : - RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - SubitemDashboardExamsBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) - ) - - @SuppressLint("SetTextI18n") - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - val context = holder.binding.root.context - val primaryWarningTextColor = context.getThemeAttrColor( - if (item.date == LocalDate.now()) { - R.attr.colorPrimary - } else { - android.R.attr.textColorPrimary - } - ) - val secondaryWarningTextColor = context.getThemeAttrColor( - if (item.date == LocalDate.now()) { - R.attr.colorPrimary - } else { - android.R.attr.textColorSecondary - } - ) - - with(holder.binding) { - dashboardHomeworkSubitemTime.text = item.date.toFormattedString("dd.MM") - dashboardHomeworkSubitemTime.setTextColor(secondaryWarningTextColor) - - dashboardHomeworkSubitemTitle.text = "${item.type} - ${item.subject}" - dashboardHomeworkSubitemTitle.setTextColor(primaryWarningTextColor) - } - } - - class ViewHolder(val binding: SubitemDashboardExamsBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardGradesAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardGradesAdapter.kt deleted file mode 100644 index d821de53..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardGradesAdapter.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.content.res.ColorStateList -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.databinding.SubitemDashboardGradesBinding -import io.github.wulkanowy.databinding.SubitemDashboardSmallGradeBinding -import io.github.wulkanowy.utils.getBackgroundColor -import io.github.wulkanowy.utils.getCompatColor - -class DashboardGradesAdapter : RecyclerView.Adapter() { - - var items = listOf>>() - - lateinit var gradeColorTheme: GradeColorTheme - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - SubitemDashboardGradesBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val (subject, grades) = items[position] - val context = holder.binding.root.context - - with(holder.binding) { - dashboardGradesSubitemTitle.text = subject - - grades.forEach { - val subitemBinding = SubitemDashboardSmallGradeBinding.inflate( - LayoutInflater.from(context), - dashboardGradesSubitemGradeContainer, - false - ) - - with(subitemBinding.dashboardSmallGradeSubitemValue) { - text = it.entry - backgroundTintList = ColorStateList.valueOf( - context.getCompatColor(it.getBackgroundColor(gradeColorTheme)) - ) - } - - dashboardGradesSubitemGradeContainer.addView(subitemBinding.root) - } - } - } - - class ViewHolder(val binding: SubitemDashboardGradesBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardHomeworkAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardHomeworkAdapter.kt deleted file mode 100644 index 8105ff9c..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardHomeworkAdapter.kt +++ /dev/null @@ -1,56 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.adapters - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.databinding.SubitemDashboardHomeworkBinding -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate - -class DashboardHomeworkAdapter : RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - SubitemDashboardHomeworkBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - @SuppressLint("SetTextI18n") - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - val context = holder.binding.root.context - val formattedDate = item.date.toFormattedString("dd.MM") - val primaryWarningTextColor = context.getThemeAttrColor( - if (item.date == LocalDate.now()) { - R.attr.colorPrimary - } else { - android.R.attr.textColorPrimary - } - ) - val secondaryWarningTextColor = context.getThemeAttrColor( - if (item.date == LocalDate.now()) { - R.attr.colorPrimary - } else { - android.R.attr.textColorSecondary - } - ) - - with(holder.binding) { - dashboardHomeworkSubitemTitle.text = "${item.subject} - ${item.content}" - dashboardHomeworkSubitemTitle.setTextColor(primaryWarningTextColor) - - dashboardHomeworkSubitemTime.text = - context.getString(R.string.dashboard_homework_time, formattedDate) - dashboardHomeworkSubitemTime.setTextColor(secondaryWarningTextColor) - } - } - - class ViewHolder(val binding: SubitemDashboardHomeworkBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt deleted file mode 100644 index 1e0f0bdb..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/viewholders/AdminMessageViewHolder.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.github.wulkanowy.ui.modules.dashboard.viewholders - -import android.content.res.ColorStateList -import android.graphics.Color -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.databinding.ItemDashboardAdminMessageBinding -import io.github.wulkanowy.utils.getThemeAttrColor - -class AdminMessageViewHolder( - private val binding: ItemDashboardAdminMessageBinding, - private val onAdminMessageDismissClickListener: (AdminMessage) -> Unit, - private val onAdminMessageClickListener: (String?) -> Unit, -) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: AdminMessage?) { - item ?: return - - val context = binding.root.context - val (backgroundColor, textColor) = when (item.priority) { - "HIGH" -> { - context.getThemeAttrColor(R.attr.colorMessageHigh) to - context.getThemeAttrColor(R.attr.colorOnMessageHigh) - } - - "MEDIUM" -> { - context.getThemeAttrColor(R.attr.colorMessageMedium) to Color.BLACK - } - - else -> null to context.getThemeAttrColor(R.attr.colorOnSurface) - } - - with(binding) { - dashboardAdminMessageItemTitle.text = item.title - dashboardAdminMessageItemTitle.setTextColor(textColor) - dashboardAdminMessageItemDescription.text = item.content - dashboardAdminMessageItemDescription.setTextColor(textColor) - dashboardAdminMessageItemIcon.setColorFilter(textColor) - dashboardAdminMessageItemDismiss.isVisible = item.isOkVisible - dashboardAdminMessageItemClose.isVisible = item.isXVisible - dashboardAdminMessageItemDismiss.setTextColor(textColor) - dashboardAdminMessageItemClose.imageTintList = ColorStateList.valueOf(textColor) - dashboardAdminMessageItemDismiss.setOnClickListener { - onAdminMessageDismissClickListener(item) - } - dashboardAdminMessageItemClose.setOnClickListener { - onAdminMessageDismissClickListener(item) - } - - root.setCardBackgroundColor(backgroundColor?.let { ColorStateList.valueOf(it) }) - item.destinationUrl?.let { url -> - root.setOnClickListener { onAdminMessageClickListener(url) } - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt deleted file mode 100644 index 36f99ca3..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugAdapter.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.databinding.ItemDebugBinding - -class DebugAdapter : RecyclerView.Adapter() { - - var items = emptyList() - - var onItemClickListener: (DebugItem) -> Unit = {} - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( - ItemDebugBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val item = items[position] - with(holder.binding) { - debugItemName.setText(item.title) - - root.setOnClickListener { - onItemClickListener(item) - } - } - } - - class ItemViewHolder(val binding: ItemDebugBinding) : RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt deleted file mode 100644 index 9db01a30..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugFragment.kt +++ /dev/null @@ -1,70 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug - -import android.os.Bundle -import android.view.View -import android.webkit.CookieManager -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.FragmentDebugBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.debug.logviewer.LogViewerFragment -import io.github.wulkanowy.ui.modules.debug.notification.NotificationDebugFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import javax.inject.Inject - -@AndroidEntryPoint -class DebugFragment : BaseFragment(R.layout.fragment_debug), DebugView, - MainView.TitledView { - - @Inject - lateinit var presenter: DebugPresenter - - private val debugAdapter = DebugAdapter() - - override val titleStringId: Int - get() = R.string.debug_title - - companion object { - fun newInstance() = DebugFragment() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentDebugBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - debugAdapter.onItemClickListener = presenter::onItemSelect - with(binding.debugRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = debugAdapter - } - } - - override fun setItems(itemList: List) { - with(debugAdapter) { - items = itemList - notifyDataSetChanged() - } - } - - override fun openLogViewer() { - (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance()) - } - - override fun openNotificationsDebug() { - (activity as? MainActivity)?.pushView(NotificationDebugFragment.newInstance()) - } - - override fun clearWebkitCookies() { - CookieManager.getInstance().removeAllCookies(null) - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt deleted file mode 100644 index 2273294e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugItem.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug - -import androidx.annotation.StringRes - -data class DebugItem( - @StringRes val title: Int, -) \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt deleted file mode 100644 index 816b5985..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugPresenter.kt +++ /dev/null @@ -1,39 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug - -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import timber.log.Timber -import javax.inject.Inject - -class DebugPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, -) : BasePresenter(errorHandler, studentRepository) { - - val items = listOf( - DebugItem(R.string.logviewer_title), - DebugItem(R.string.notification_debug_title), - DebugItem(R.string.debug_cookies_clear), - ) - - override fun onAttachView(view: DebugView) { - super.onAttachView(view) - Timber.i("Debug view was initialized") - - with(view) { - initView() - setItems(items) - } - } - - fun onItemSelect(item: DebugItem) { - when (item.title) { - R.string.logviewer_title -> view?.openLogViewer() - R.string.notification_debug_title -> view?.openNotificationsDebug() - R.string.debug_cookies_clear -> view?.clearWebkitCookies() - else -> Timber.d("Unknown debug item: $item") - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt deleted file mode 100644 index 792d63d9..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/DebugView.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug - -import io.github.wulkanowy.ui.base.BaseView - -interface DebugView : BaseView { - - fun initView() - - fun setItems(itemList: List) - - fun openLogViewer() - - fun openNotificationsDebug() - - fun clearWebkitCookies() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt deleted file mode 100644 index 7adb56b8..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerPresenter.kt +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.logviewer - -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.repositories.LoggerRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import kotlinx.coroutines.flow.onEach -import timber.log.Timber -import javax.inject.Inject - -class LogViewerPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val loggerRepository: LoggerRepository -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: LogViewerView) { - super.onAttachView(view) - view.initView() - loadLogFile() - } - - fun onShareLogsSelected(): Boolean { - resourceFlow { loggerRepository.getLogFiles() } - .onEach { - when (it) { - is Resource.Loading -> Timber.d("Loading logs files started") - is Resource.Success -> { - Timber.i("Loading logs files result: ${it.data.joinToString { file -> file.name }}") - view?.shareLogs(it.data) - } - is Resource.Error -> { - Timber.i("Loading logs files result: An exception occurred") - errorHandler.dispatch(it.error) - } - } - } - .launch("share") - return true - } - - fun onRefreshClick() { - loadLogFile() - } - - private fun loadLogFile() { - resourceFlow { loggerRepository.getLastLogLines() } - .onEach { - when (it) { - is Resource.Loading -> Timber.d("Loading last log file started") - is Resource.Success -> { - Timber.i("Loading last log file result: load ${it.data.size} lines") - view?.setLines(it.data) - } - is Resource.Error -> { - Timber.i("Loading last log file result: An exception occurred") - errorHandler.dispatch(it.error) - } - } - } - .launch("file") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt deleted file mode 100644 index 78107d43..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugAdapter.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.databinding.ItemDebugNotificationsBinding - -class NotificationDebugAdapter : RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( - ItemDebugNotificationsBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - title.setText(item.title) - button1.setOnClickListener { item.onClickCallback(1) } - button2.setOnClickListener { item.onClickCallback(3) } - button3.setOnClickListener { item.onClickCallback(10) } - } - } - - class ItemViewHolder(val binding: ItemDebugNotificationsBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt deleted file mode 100644 index c5c797d0..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugFragment.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification - -import android.os.Bundle -import android.view.View -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.FragmentDebugNotificationsBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainView -import javax.inject.Inject - -@AndroidEntryPoint -class NotificationDebugFragment : - BaseFragment(R.layout.fragment_debug_notifications), - NotificationDebugView, MainView.TitledView { - - @Inject - lateinit var presenter: NotificationDebugPresenter - - private val notificationDebugAdapter = NotificationDebugAdapter() - - override val titleStringId: Int - get() = R.string.notification_debug_title - - companion object { - fun newInstance() = NotificationDebugFragment() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentDebugNotificationsBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - with(binding.recyclerView) { - adapter = notificationDebugAdapter - layoutManager = LinearLayoutManager(requireContext()) - } - } - - override fun setItems(notificationDebugs: List) { - with(notificationDebugAdapter) { - items = notificationDebugs - notifyDataSetChanged() - } - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt deleted file mode 100644 index 5a528787..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugItem.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification - -import androidx.annotation.StringRes - -data class NotificationDebugItem( - @StringRes val title: Int, - val onClickCallback: (numberOfNotifications: Int) -> Unit, -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt deleted file mode 100644 index cdd186b9..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugPresenter.kt +++ /dev/null @@ -1,116 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification - -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.services.sync.notifications.ChangeTimetableNotification -import io.github.wulkanowy.services.sync.notifications.NewAttendanceNotification -import io.github.wulkanowy.services.sync.notifications.NewConferenceNotification -import io.github.wulkanowy.services.sync.notifications.NewExamNotification -import io.github.wulkanowy.services.sync.notifications.NewGradeNotification -import io.github.wulkanowy.services.sync.notifications.NewHomeworkNotification -import io.github.wulkanowy.services.sync.notifications.NewLuckyNumberNotification -import io.github.wulkanowy.services.sync.notifications.NewMessageNotification -import io.github.wulkanowy.services.sync.notifications.NewNoteNotification -import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugAttendanceItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugConferenceItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugExamItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugGradeDescriptiveItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugGradeDetailsItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugGradeSummaryItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugHomeworkItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugLuckyNumber -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugMessageItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugNoteItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugSchoolAnnouncementItems -import io.github.wulkanowy.ui.modules.debug.notification.mock.debugTimetableItems -import kotlinx.coroutines.launch -import timber.log.Timber -import javax.inject.Inject - -class NotificationDebugPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val newGradeNotification: NewGradeNotification, - private val newHomeworkNotification: NewHomeworkNotification, - private val newConferenceNotification: NewConferenceNotification, - private val newExamNotification: NewExamNotification, - private val newMessageNotification: NewMessageNotification, - private val newNoteNotification: NewNoteNotification, - private val newSchoolAnnouncementNotification: NewSchoolAnnouncementNotification, - private val newLuckyNumberNotification: NewLuckyNumberNotification, - private val changeTimetableNotification: ChangeTimetableNotification, - private val newAttendanceNotification: NewAttendanceNotification, -) : BasePresenter(errorHandler, studentRepository) { - - private val items = listOf( - NotificationDebugItem(R.string.grade_title) { n -> - withStudent { newGradeNotification.notifyDetails(debugGradeDetailsItems.take(n), it) } - }, - NotificationDebugItem(R.string.grade_summary_predicted_grade) { n -> - withStudent { newGradeNotification.notifyPredicted(debugGradeSummaryItems.take(n), it) } - }, - NotificationDebugItem(R.string.grade_summary_final_grade) { n -> - withStudent { newGradeNotification.notifyFinal(debugGradeSummaryItems.take(n), it) } - }, - NotificationDebugItem(R.string.grade_summary_descriptive) { n -> - withStudent { - newGradeNotification.notifyDescriptive( - debugGradeDescriptiveItems.take(n), - it - ) - } - }, - NotificationDebugItem(R.string.homework_title) { n -> - withStudent { newHomeworkNotification.notify(debugHomeworkItems.take(n), it) } - }, - NotificationDebugItem(R.string.conferences_title) { n -> - withStudent { newConferenceNotification.notify(debugConferenceItems.take(n), it) } - }, - NotificationDebugItem(R.string.exam_title) { n -> - withStudent { newExamNotification.notify(debugExamItems.take(n), it) } - }, - NotificationDebugItem(R.string.message_title) { n -> - withStudent { newMessageNotification.notify(debugMessageItems.take(n), it) } - }, - NotificationDebugItem(R.string.note_title) { n -> - withStudent { newNoteNotification.notify(debugNoteItems.take(n), it) } - }, - NotificationDebugItem(R.string.attendance_title) { n -> - withStudent { newAttendanceNotification.notify(debugAttendanceItems.take(n), it) } - }, - NotificationDebugItem(R.string.timetable_title) { n -> - withStudent { changeTimetableNotification.notify(debugTimetableItems.take(n), it) } - }, - NotificationDebugItem(R.string.school_announcement_title) { n -> - withStudent { - newSchoolAnnouncementNotification.notify(debugSchoolAnnouncementItems.take(n), it) - } - }, - NotificationDebugItem(R.string.lucky_number_title) { n -> - withStudent { - repeat(n) { _ -> - newLuckyNumberNotification.notify(debugLuckyNumber, it) - } - } - }, - ) - - override fun onAttachView(view: NotificationDebugView) { - super.onAttachView(view) - Timber.i("Notification debug view was initialized") - with(view) { - initView() - setItems(items) - } - } - - private fun withStudent(block: suspend (Student) -> Unit) { - presenterScope.launch { - block(studentRepository.getCurrentStudent(false)) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt deleted file mode 100644 index e2c043c3..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/NotificationDebugView.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification - -import io.github.wulkanowy.ui.base.BaseView - -interface NotificationDebugView : BaseView { - - fun initView() - - fun setItems(notificationDebugs: List) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/attendance.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/attendance.kt deleted file mode 100644 index 042cf07e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/attendance.kt +++ /dev/null @@ -1,35 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Attendance -import java.time.LocalDate - -val debugAttendanceItems = listOf( - generateAttendance("Matematyka", "PRESENCE"), - generateAttendance("Język angielski", "UNEXCUSED_LATENESS"), - generateAttendance("Geografia", "ABSENCE_UNEXCUSED"), - generateAttendance("Sieci komputerowe", "ABSENCE_EXCUSED"), - generateAttendance("Systemy operacyjne", "EXCUSED_LATENESS"), - generateAttendance("Język niemiecki", "ABSENCE_UNEXCUSED"), - generateAttendance("Biologia", "ABSENCE_UNEXCUSED"), - generateAttendance("Chemia", "ABSENCE_EXCUSED"), - generateAttendance("Fizyka", "ABSENCE_UNEXCUSED"), - generateAttendance("Matematyka", "ABSENCE_EXCUSED"), -) - -private fun generateAttendance(subject: String, name: String) = Attendance( - subject = subject, - studentId = 0, - diaryId = 0, - date = LocalDate.now(), - timeId = 0, - number = 1, - name = name, - presence = false, - absence = false, - exemption = false, - lateness = false, - excused = false, - deleted = false, - excusable = false, - excuseStatus = "" -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt deleted file mode 100644 index 625ff4c9..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/conference.kt +++ /dev/null @@ -1,59 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Conference -import java.time.Duration -import java.time.Instant - -val debugConferenceItems = listOf( - generateConference( - title = "Spotkanie z rodzicami/opiekunami", - subject = "Podsumowanie I semestru - średnia klasy, oceny, frekwencja, zachowanie" - ), - generateConference( - title = "ZSW", - subject = "Pierwsze - organizacyjne zebranie z rodzicami klas pierwszych" - ), - generateConference( - title = "Spotkanie z rodzicami w sprawie bójki", - subject = "Pierwsze - i miejmy nadzieję ostatnie - zebranie w takiej sprawie" - ), - generateConference( - title = "Spotkanie z rodzicami w sprawie kolejnej bójki", - subject = "Kolejne - ale miejmy jeszcze nadzieję, że ostatnie - zebranie w takiej sprawie" - ), - generateConference( - title = "Spotkanie z rodzicami w sprawie jeszcze jednej bójki", - subject = "Proszę państwa, proszę uspokoić swoje dzieci" - ), - generateConference( - title = "Spotkanie w sprawie wydalenia części uczniów", - subject = "Proszę państwa, to jest krok ostateczny, którego nikt nie chciał się podjąć, ale ktoś musi" - ), - generateConference( - title = "Spotkanie organizacyjne w drugim semestrze", - subject = "Prezentacja na temat projektu 'Spokojnej szkoły'" - ), - generateConference( - title = "Spotkanie z pierwszakami", - subject = "Mamy sobie do pogadania" - ), - generateConference( - title = "Spotkanie z rodzicami szóstoklaistów", - subject = "Musimy przygotować dzieci do ważnej uroczystości" - ), - generateConference( - title = "Spotkanie podsumowujące pracę w ciągu ostatniego roku szkolnego", - subject = "Proszę państwa, zapraszam serdecznie na spotkanie" - ), -) - -private fun generateConference(title: String, subject: String) = Conference( - title = title, - subject = subject, - studentId = 0, - diaryId = 0, - agenda = "", - conferenceId = 0, - date = Instant.now().plus(Duration.ofMinutes(10)), - presentOnConference = "", -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt deleted file mode 100644 index 45700c29..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/exam.kt +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Exam -import java.time.LocalDate - -val debugExamItems = listOf( - generateExam("Matematyka", "Figury na płaszczyźnie"), - generateExam("Język angielski", "czasowniki nieregularne 1 część"), - generateExam("Geografia", "Opolszczyzna - mapa"), - generateExam("Sieci komputerowe", "Zaciskanie erjotek"), - generateExam("Systemy operacyjne", "Instalacja ubuntu 16.04"), - generateExam("Język niemiecki", "oral exam"), - generateExam("Biologia", "Budowa koniczyny"), - generateExam("Chemia", "synteza płynnego zaliczenia"), - generateExam("Fizyka", "telekineza"), - generateExam("Matematyka", "Liczby zespolone i pochodne piątego rzędu"), -) - -private fun generateExam(subject: String, description: String) = Exam( - subject = subject, - description = description, - studentId = 0, - diaryId = 0, - date = LocalDate.now(), - entryDate = LocalDate.now(), - group = "", - type = "", - teacher = "", - teacherSymbol = "" -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDescriptive.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDescriptive.kt deleted file mode 100644 index d5a0c089..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDescriptive.kt +++ /dev/null @@ -1,48 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.GradeDescriptive - -val debugGradeDescriptiveItems = listOf( - generateGradeDescriptive( - "Matematyka", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive("Fizyka", "Lorem ipsum dolor sit amet, consectetur adipiscing elit."), - generateGradeDescriptive( - "Geografia", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive( - "Sieci komputerowe", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive( - "Systemy operacyjne", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive( - "Język polski", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive( - "Język angielski", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive("Religia", "Lorem ipsum dolor sit amet, consectetur adipiscing elit."), - generateGradeDescriptive( - "Język niemiecki", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), - generateGradeDescriptive( - "Wychowanie fizyczne", - "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - ), -) - -private fun generateGradeDescriptive(subject: String, description: String) = - GradeDescriptive( - semesterId = 0, - studentId = 0, - subject = subject, - description = description - ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt deleted file mode 100644 index 77b60188..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeDetails.kt +++ /dev/null @@ -1,35 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Grade -import java.time.LocalDate - -val debugGradeDetailsItems = listOf( - generateGrade("Matematyka", "+"), - generateGrade("Matematyka", "120", comment = "%"), - generateGrade("Fizyka", "-"), - generateGrade("Geografia", "4+"), - generateGrade("Sieci komputerowe", "1"), - generateGrade("Systemy operacyjne", "3+"), - generateGrade("Język polski", "2-"), - generateGrade("Język angielski", "4+"), - generateGrade("Religia", "6"), - generateGrade("Język niemiecki", "1!"), - generateGrade("Wychowanie fizyczne", "5"), -) - -private fun generateGrade(subject: String, entry: String, comment: String = "") = Grade( - subject = subject, - entry = entry, - semesterId = 0, - studentId = 0, - value = 0.0, - modifier = 0.0, - comment = comment, - color = "", - gradeSymbol = "", - description = "", - weight = "", - weightValue = 0.0, - date = LocalDate.now(), - teacher = "" -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt deleted file mode 100644 index e92d1afb..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/gradeSummary.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.GradeSummary - -val debugGradeSummaryItems = listOf( - generateSummary("Matematyka", "2-", "2"), - generateSummary("Fizyka", "1", "2"), - generateSummary("Geografia", "4+", "5"), - generateSummary("Sieci komputerowe", "2", "5"), - generateSummary("Systemy operacyjne", "3", "4"), - generateSummary("Język polski", "1", "3"), - generateSummary("Język angielski", "4", "3"), - generateSummary("Religia", "5", "6"), - generateSummary("Język niemiecki", "2", "2"), - generateSummary("Wychowanie fizyczne", "5", "5"), - generateSummary("Biologia", "4", "4"), -) - -private fun generateSummary(subject: String, predicted: String, final: String) = GradeSummary( - semesterId = 0, - studentId = 0, - position = 0, - subject = subject, - predictedGrade = predicted, - finalGrade = final, - proposedPoints = "", - finalPoints = "", - pointsSum = "", - average = .0, - pointsSumAllYear = null, - averageAllYear = null, -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt deleted file mode 100644 index 6c7d7fac..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/homework.kt +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Homework -import java.time.LocalDate - -val debugHomeworkItems = listOf( - generateHomework("Chemia", "Test diagnozujący i Rozdział I do 30.10"), - generateHomework("Etyka", "Notatka własna do zajęć o ks. Jerzym Popiełuszko"), - generateHomework("Język angielski", "Zadania egzaminacyjne"), - generateHomework("Metodologia programowania", "Wszystkie instrukcje"), - generateHomework("Język polski", "Notatka własna na temat Wokulskiego z lektury Lalka"), - generateHomework("Systemy operacyjne", "Sprawozdanie z wykonania ćwiczenia nr 21.137"), - generateHomework("Matematyka", "Zadania od strony 1 do 128"), - generateHomework("Język niemiecki", "Opis swoich wakacji - dialog z kolegą"), - generateHomework("Język angielski", "Opis swoich wakacji - dialog z kolegą"), - generateHomework("Wychowanie fizyczne", "Notatka na temat skoku w dald"), - generateHomework("Biologia", "Notatka na temat grzechotnika"), -) - -private fun generateHomework(subject: String, content: String) = Homework( - subject = subject, - content = content, - semesterId = 0, - studentId = 0, - date = LocalDate.now(), - entryDate = LocalDate.now(), - teacher = "", - teacherSymbol = "", - attachments = listOf(), -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt deleted file mode 100644 index e929a090..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/luckyNumber.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.LuckyNumber -import java.time.LocalDate -import kotlin.random.Random - -val debugLuckyNumber - get() = LuckyNumber( - studentId = 0, - date = LocalDate.now(), - luckyNumber = Random.nextInt(1, 128), - ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt deleted file mode 100644 index 27d8613a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Message -import java.time.Instant - -val debugMessageItems = listOf( - generateMessage("Kowalski Jan", "Tytuł"), - generateMessage("Nazwisko Imię", "Tytuł wiadomości"), - generateMessage("Malinowski Kazimierz", "Nakrętki"), - generateMessage("Jastębowszki Orest", "Prośba do uczniów o pomoc przy projekcie"), - generateMessage("Metylowy Oranż", "Pozew o plagiat"), - generateMessage("VULCAN", "Uwaga na nieautoryzowane aplikacje"), - generateMessage("Mama", "Zacznij się w końcu uczyć do matury!!!11"), - generateMessage("Tata", "Kupisz mi coś w sklepie?"), - generateMessage("Wychowawca", "Upomnienie od wychowawcy za nieobecności"), - generateMessage("Kochanowska Joanna", "Poprawa rozprawki - termin"), -) - -private fun generateMessage(sender: String, subject: String) = Message( - subject = subject, - messageId = 123, - email = "", - date = Instant.now(), - folderId = 0, - unread = true, - readBy = 2, - unreadBy = 2, - hasAttachments = false, - messageGlobalKey = "", - correspondents = sender, - mailboxKey = "", -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt deleted file mode 100644 index b287a508..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/note.kt +++ /dev/null @@ -1,29 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory -import java.time.LocalDate - -val debugNoteItems = listOf( - generateNote("Aleksadra Krajewska", "Przeszkadzanie na lekcjach", NoteCategory.NEGATIVE), - generateNote("Zofia Czerwińska", "Udział w konkursie szkolnym", NoteCategory.POSITIVE), - generateNote("Stanisław Krupa", "Kultura języka", NoteCategory.NEUTRAL), - generateNote("Karolina Kowalska", "Wypełnianie obowiązków ucznia", NoteCategory.NEUTRAL), - generateNote("Joanna Krupa", "Umycie tablicy cifem", NoteCategory.POSITIVE), - generateNote("Duchowicz Maksymilian", "Reprezentowanie szkoły", NoteCategory.POSITIVE), - generateNote("Michał Mazur", "Przeszkadzanie na lekcji", NoteCategory.NEGATIVE), - generateNote("Karolina Kowalska", "Wypełnianie obowiązków ucznia", NoteCategory.NEGATIVE), - generateNote("Aleksandra Krajewska", "Wysadzenie klasy w powietrze", NoteCategory.NEGATIVE), -) - -private fun generateNote(teacher: String, category: String, type: NoteCategory) = Note( - teacher = teacher, - category = category, - categoryType = type.id, - studentId = 0, - date = LocalDate.now(), - teacherSymbol = "", - isPointsShow = false, - points = 0, - content = "" -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt deleted file mode 100644 index 9b21f08e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/schoolAnnouncement.kt +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import java.time.LocalDate - -val debugSchoolAnnouncementItems = listOf( - generateAnnouncement("Dzień wolny od zajęć dydaktycznych", "Dzień wolny od zajęć dydaktycznych
03.05.2021 – poniedziałek"), - generateAnnouncement("Zasady bezpieczeństwa", "Wszyscy uczniowie są zobowiązani do noszenia maseczek"), - generateAnnouncement("Święto szkoły", "W najbliższych dniach obchodzimy święto szkoły, podczas którego..."), - generateAnnouncement("Rocznica odzyskania przez szkołę sztandaru", "Juz niedługo, bo za tydzień, a dokładnie za 8 dni..."), - generateAnnouncement("Ogłoszenie w sprawie otwarcia stołówki", "Wszyscy uczniowie zainteresowani obiadami w szkole..."), - generateAnnouncement("Uczniowie proszeni do sekretariatu", "Kuba i Jacek z klasy czwartej proszeni do dyrektora w trybie pilnym"), - generateAnnouncement("Dzień wolny od zajęć dydaktycznych", "Dzień wolny od zajęć dydaktycznych
21.06.2021 – poniedziałek"), - generateAnnouncement("Zasady bezpieczeństwa", "Wszyscy uczniowie są zobowiązani do zdjęcia maseczek"), - generateAnnouncement("Święto państwowe", "W najbliższych dniach obchodzimy święto państwowe, podczas którego..."), - generateAnnouncement("Uczniowie proszeni do sekretariatu", "Kuba i Jacek z klasy czwartej proszeni do dyrektora w trybie wolnym"), -) - -private fun generateAnnouncement(subject: String, content: String) = SchoolAnnouncement( - subject = subject, - content = content, - studentId = 0, - date = LocalDate.now() -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/timetable.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/timetable.kt deleted file mode 100644 index ff968654..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/timetable.kt +++ /dev/null @@ -1,40 +0,0 @@ -package io.github.wulkanowy.ui.modules.debug.notification.mock - -import io.github.wulkanowy.data.db.entities.Timetable -import java.time.Duration -import java.time.Instant -import java.time.LocalDate -import kotlin.random.Random - -val debugTimetableItems = listOf( - generateTimetable("Matematyka", "12", "01"), - generateTimetable("Język angielski", "23", "12"), - generateTimetable("Geografia", "34", "23"), - generateTimetable("Sieci komputerowe", "45", "34"), - generateTimetable("Systemy operacyjne", "56", "45"), - generateTimetable("Język niemiecki", "67", "56"), - generateTimetable("Biologia", "78", "67"), - generateTimetable("Chemia", "89", "78"), - generateTimetable("Fizyka", "90", "89"), - generateTimetable("Matematyka", "01", "90"), -) - -private fun generateTimetable(subject: String, room: String, roomOld: String) = Timetable( - subject = subject, - studentId = 0, - diaryId = 0, - date = LocalDate.now().minusDays(Random.nextLong(0, 8)), - number = 1, - start = Instant.now().plus(Duration.ofHours(1)), - end = Instant.now(), - subjectOld = "", - group = "", - room = room, - roomOld = roomOld, - teacher = "Wtorkowska Renata", - teacherOld = "", - info = "", - isStudentPlan = true, - changes = true, - canceled = true -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamAdapter.kt index 4dc8afd3..53558739 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamAdapter.kt @@ -7,7 +7,6 @@ import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.databinding.HeaderExamBinding import io.github.wulkanowy.databinding.ItemExamBinding -import io.github.wulkanowy.utils.capitalise import io.github.wulkanowy.utils.toFormattedString import io.github.wulkanowy.utils.weekDayName import java.time.LocalDate @@ -43,7 +42,7 @@ class ExamAdapter @Inject constructor() : RecyclerView.Adapter() { +class ExamDialog : DialogFragment() { + + private var binding: DialogExamBinding by lifecycleAwareVariable() private lateinit var exam: Exam companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(exam: Exam) = ExamDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to exam) + fun newInstance(exam: Exam): ExamDialog { + return ExamDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - exam = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + exam = getSerializable(ARGUMENT_KEY) as Exam + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogExamBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogExamBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(binding) { examDialogSubjectValue.text = exam.subject examDialogTypeValue.text = exam.type examDialogTeacherValue.text = exam.teacher - examDialogEntryDateValue.text = exam.entryDate.toFormattedString() - examDialogDeadlineDateValue.text = exam.date.toFormattedString() - examDialogDescriptionValue.text = exam.description.ifBlank { - getString(R.string.all_no_data) - } + examDialogDateValue.text = exam.entryDate.toFormattedString() + examDialogDescriptionValue.text = exam.description examDialogClose.setOnClickListener { dismiss() } - examDialogAddToCalendar.setOnClickListener { - requireContext().openCalendarEventAdd( - title = "${exam.subject} - ${exam.type}", - description = exam.description, - start = exam.date.atTime(LocalTime.of(8, 0)), - end = exam.date.atTime(LocalTime.of(8, 45)), - ) - } } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt index 0123e234..000da00f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamFragment.kt @@ -2,7 +2,9 @@ package io.github.wulkanowy.ui.modules.exam import android.os.Bundle import android.view.View -import android.view.View.* +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R @@ -13,12 +15,11 @@ import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint class ExamFragment : BaseFragment(R.layout.fragment_exam), ExamView, - MainView.TitledView, MainView.MainChildView { + MainView.MainChildView, MainView.TitledView { @Inject lateinit var presenter: ExamPresenter @@ -54,20 +55,18 @@ class ExamFragment : BaseFragment(R.layout.fragment_exam), with(binding) { examSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - examSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - examSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) examErrorRetry.setOnClickListener { presenter.onRetry() } examErrorDetails.setOnClickListener { presenter.onDetailsClick() } examPreviousButton.setOnClickListener { presenter.onPreviousWeek() } examNextButton.setOnClickListener { presenter.onNextWeek() } - examNavContainer.elevation = requireContext().dpToPx(3f) + examNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } } - override fun showRefresh(show: Boolean) { - binding.examSwipe.isRefreshing = show + override fun hideRefresh() { + binding.examSwipe.isRefreshing = false } override fun updateData(data: List>) { @@ -88,6 +87,14 @@ class ExamFragment : BaseFragment(R.layout.fragment_exam), } } + override fun resetView() { + binding.examRecycler.scrollToPosition(0) + } + + override fun onFragmentReselected() { + if (::presenter.isInitialized) presenter.onViewReselected() + } + override fun showEmpty(show: Boolean) { binding.examEmpty.visibility = if (show) VISIBLE else GONE } @@ -124,14 +131,6 @@ class ExamFragment : BaseFragment(R.layout.fragment_exam), (activity as? MainActivity)?.showDialogFragment(ExamDialog.newInstance(exam)) } - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onViewReselected() - } - - override fun resetView() { - binding.examRecycler.smoothScrollToPosition(0) - } - override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt index 85814072..406d011c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamPresenter.kt @@ -1,13 +1,21 @@ package io.github.wulkanowy.ui.modules.exam -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Exam -import io.github.wulkanowy.data.repositories.ExamRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.exam.ExamRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday +import io.github.wulkanowy.utils.isHolidays +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.nextOrSameSchoolDay +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach @@ -37,24 +45,24 @@ class ExamPresenter @Inject constructor( view.initView() Timber.i("Exam view was initialized") errorHandler.showErrorMessage = ::showErrorViewOnError - reloadView(ofEpochDay(date ?: baseDate.toEpochDay())) - loadData() + loadData(ofEpochDay(date ?: baseDate.toEpochDay())) if (currentDate.isHolidays) setBaseDateOnHolidays() + reloadView() } fun onPreviousWeek() { - reloadView(currentDate.minusDays(7)) - loadData() + loadData(currentDate.minusDays(7)) + reloadView() } fun onNextWeek() { - reloadView(currentDate.plusDays(7)) - loadData() + loadData(currentDate.plusDays(7)) + reloadView() } fun onSwipeRefresh() { Timber.i("Force refreshing the exam") - loadData(true) + loadData(currentDate, true) } fun onRetry() { @@ -62,7 +70,7 @@ class ExamPresenter @Inject constructor( showErrorView(false) showProgress(true) } - loadData(true) + loadData(currentDate, true) } fun onDetailsClick() { @@ -74,61 +82,65 @@ class ExamPresenter @Inject constructor( view?.showExamDialog(exam) } + fun onViewReselected() { + Timber.i("Exam view is reselected") + baseDate.also { + if (currentDate != it) { + loadData(it) + reloadView() + } else if (view?.isViewEmpty == false) view?.resetView() + } + } + private fun setBaseDateOnHolidays() { flow { val student = studentRepository.getCurrentStudent() emit(semesterRepository.getCurrentSemester(student)) - } - .catch { Timber.i("Loading semester result: An exception occurred") } - .onEach { - baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) - currentDate = baseDate - reloadNavigation() - } - .launch("holidays") + }.catch { + Timber.i("Loading semester result: An exception occurred") + }.onEach { + baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) + currentDate = baseDate + reloadNavigation() + }.launch("holidays") } - private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { + currentDate = date + + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - examRepository.getExams( - student = student, - semester = semester, - start = currentDate.monday, - end = currentDate.sunday, - forceRefresh = forceRefresh - ) - } - .logResourceStatus("load exam data") - .mapResourceData { createExamItems(it) } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + examRepository.getExams(student, semester, currentDate.monday, currentDate.sunday, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading exam data started") + Status.SUCCESS -> { + Timber.i("Loading exam result: Success") + view?.apply { + updateData(createExamItems(it.data!!)) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) + } + analytics.logEvent( + "load_data", + "type" to "exam", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading exam result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "exam", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -150,9 +162,7 @@ class ExamPresenter @Inject constructor( }.flatten() } - private fun reloadView(date: LocalDate) { - currentDate = date - + private fun reloadView() { Timber.i("Reload exam view with the date ${currentDate.toFormattedString()}") view?.apply { showProgress(true) @@ -169,23 +179,8 @@ class ExamPresenter @Inject constructor( view?.apply { showPreButton(!currentDate.minusDays(7).isHolidays) showNextButton(!currentDate.plusDays(7).isHolidays) - updateNavigationWeek( - "${currentDate.monday.toFormattedString("dd.MM")} - " + - currentDate.sunday.toFormattedString("dd.MM") - ) - } - } - - fun onViewReselected() { - Timber.i("Exam view is reselected") - - baseDate = now().nextOrSameSchoolDay - - if (currentDate != baseDate) { - reloadView(baseDate) - loadData() - } else if (view?.isViewEmpty == false) { - view?.resetView() + updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " + + currentDate.sunday.toFormattedString("dd.MM")) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamView.kt index 677fac40..00429bae 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamView.kt @@ -15,7 +15,9 @@ interface ExamView : BaseView { fun clearData() - fun showRefresh(show: Boolean) + fun hideRefresh() + + fun resetView() fun showEmpty(show: Boolean) @@ -34,6 +36,4 @@ interface ExamView : BaseView { fun showPreButton(show: Boolean) fun showExamDialog(exam: Exam) - - fun resetView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt index 3158bd0b..1960c3df 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt @@ -6,6 +6,6 @@ enum class GradeAverageMode(val value: String) { BOTH_SEMESTERS("both_semesters"); companion object { - fun getByValue(value: String) = entries.firstOrNull { it.value == value } ?: ONE_SEMESTER + fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE_SEMESTER } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt index 7f14c01f..5d0a310f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt @@ -1,287 +1,114 @@ package io.github.wulkanowy.ui.modules.grade import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.dataOrNull +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.errorOrNull -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.mapData -import io.github.wulkanowy.data.mapResourceData -import io.github.wulkanowy.data.repositories.GradeRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository +import io.github.wulkanowy.data.repositories.grade.GradeRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ALL_YEAR import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.BOTH_SEMESTERS import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ONE_SEMESTER import io.github.wulkanowy.utils.calcAverage import io.github.wulkanowy.utils.changeModifier -import kotlinx.coroutines.ExperimentalCoroutinesApi +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flatMapConcat +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import javax.inject.Inject -@OptIn(ExperimentalCoroutinesApi::class) +@OptIn(FlowPreview::class) class GradeAverageProvider @Inject constructor( private val semesterRepository: SemesterRepository, private val gradeRepository: GradeRepository, private val preferencesRepository: PreferencesRepository ) { - private data class AverageCalcParams( - val gradeAverageMode: GradeAverageMode, - val forceAverageCalc: Boolean, - val isOptionalArithmeticAverage: Boolean, - val plusModifier: Double, - val minusModifier: Double, - ) + private val plusModifier get() = preferencesRepository.gradePlusModifier - fun getGradesDetailsWithAverage( - student: Student, - semesterId: Int, - forceRefresh: Boolean - ): Flow>> = combine( - flow = preferencesRepository.gradeAverageModeFlow, - flow2 = preferencesRepository.gradeAverageForceCalcFlow, - flow3 = preferencesRepository.isOptionalArithmeticAverageFlow, - flow4 = preferencesRepository.gradePlusModifierFlow, - flow5 = preferencesRepository.gradeMinusModifierFlow, - ) { gradeAverageMode, forceAverageCalc, isOptionalArithmeticAverage, plusModifier, minusModifier -> - AverageCalcParams( - gradeAverageMode = gradeAverageMode, - forceAverageCalc = forceAverageCalc, - isOptionalArithmeticAverage = isOptionalArithmeticAverage, - plusModifier = plusModifier, - minusModifier = minusModifier, - ) - }.flatMapLatest { params -> - flatResourceFlow { - val semesters = semesterRepository.getSemesters(student) - when (params.gradeAverageMode) { - ONE_SEMESTER -> getGradeSubjects( - student = student, - semester = semesters.first { it.semesterId == semesterId }, - forceRefresh = forceRefresh, - params = params, - ) + private val minusModifier get() = preferencesRepository.gradeMinusModifier - BOTH_SEMESTERS -> calculateCombinedAverage( - student = student, - semesters = semesters, - semesterId = semesterId, - forceRefresh = forceRefresh, - config = params, - ) + fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean) = flowWithResourceIn { + val semesters = semesterRepository.getSemesters(student) - ALL_YEAR -> calculateCombinedAverage( - student = student, - semesters = semesters, - semesterId = semesterId, - forceRefresh = forceRefresh, - config = params, - ) - } + when (preferencesRepository.gradeAverageMode) { + ONE_SEMESTER -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh) + BOTH_SEMESTERS -> calculateBothSemestersAverage(student, semesters, semesterId, forceRefresh) + ALL_YEAR -> calculateAllYearAverage(student, semesters, semesterId, forceRefresh) } }.distinctUntilChanged() - private fun calculateCombinedAverage( - student: Student, - semesters: List, - semesterId: Int, - forceRefresh: Boolean, - config: AverageCalcParams, - ): Flow>> { + private fun calculateBothSemestersAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Flow>> { val selectedSemester = semesters.single { it.semesterId == semesterId } - val firstSemester = - semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 } + val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 } - val selectedSemesterGradeSubjects = - getGradeSubjects(student, selectedSemester, forceRefresh, config) + return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMapConcat { selectedDetails -> + val isAnyAverage = selectedDetails.data.orEmpty().any { it.average != .0 } - if (selectedSemester == firstSemester) return selectedSemesterGradeSubjects - - val firstSemesterGradeSubjects = - getGradeSubjects(student, firstSemester, forceRefresh, config) - - return selectedSemesterGradeSubjects.combine(firstSemesterGradeSubjects) { secondSemesterGradeSubject, firstSemesterGradeSubject -> - if (firstSemesterGradeSubject.errorOrNull != null) { - return@combine firstSemesterGradeSubject - } - - val isAnyVulcanAverageInFirstSemester = - firstSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage } - val isAnyVulcanAverageInSecondSemester = - secondSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage } - - val updatedData = secondSemesterGradeSubject.dataOrNull?.map { secondSemesterSubject -> - val firstSemesterSubject = firstSemesterGradeSubject.dataOrNull.orEmpty() - .singleOrNull { it.subject == secondSemesterSubject.subject } - - val updatedAverage = if (config.gradeAverageMode == ALL_YEAR) { - calculateAllYearAverage( - student = student, - isAnyVulcanAverage = isAnyVulcanAverageInFirstSemester || isAnyVulcanAverageInSecondSemester, - secondSemesterSubject = secondSemesterSubject, - firstSemesterSubject = firstSemesterSubject, - config = config, - ) - } else { - calculateBothSemestersAverage( - student = student, - isAnyVulcanAverage = isAnyVulcanAverageInFirstSemester || isAnyVulcanAverageInSecondSemester, - secondSemesterSubject = secondSemesterSubject, - firstSemesterSubject = firstSemesterSubject, - config = config - ) - } - secondSemesterSubject.copy(average = updatedAverage) - } - secondSemesterGradeSubject.mapData { updatedData!! } + if (selectedSemester != firstSemester) { + getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails -> + secondDetails.copy(data = selectedDetails.data?.map { selected -> + val second = secondDetails.data.orEmpty().singleOrNull { it.subject == selected.subject } + selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) { + val selectedGrades = selected.grades.updateModifiers(student).calcAverage() + (selectedGrades + (second?.grades?.updateModifiers(student)?.calcAverage() ?: selectedGrades)) / 2 + } else (selected.average + (second?.average ?: selected.average)) / 2) + }) + }.filter { it.status != Status.LOADING }.filter { it.data != null } + } else flowOf(selectedDetails) } } - private fun calculateAllYearAverage( - student: Student, - isAnyVulcanAverage: Boolean, - secondSemesterSubject: GradeSubject, - firstSemesterSubject: GradeSubject?, - config: AverageCalcParams, - ) = if (!isAnyVulcanAverage || config.forceAverageCalc) { - val updatedSecondSemesterGrades = secondSemesterSubject.grades - .updateModifiers(student, config) - val updatedFirstSemesterGrades = firstSemesterSubject?.grades - ?.updateModifiers(student, config).orEmpty() + private fun calculateAllYearAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Flow>> { + val selectedSemester = semesters.single { it.semesterId == semesterId } + val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 } - (updatedSecondSemesterGrades + updatedFirstSemesterGrades).calcAverage( - isOptionalArithmeticAverage = config.isOptionalArithmeticAverage, - ) - } else { - secondSemesterSubject.average - } + return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMapConcat { selectedDetails -> + val isAnyAverage = selectedDetails.data.orEmpty().any { it.average != .0 } - private fun calculateBothSemestersAverage( - student: Student, - isAnyVulcanAverage: Boolean, - secondSemesterSubject: GradeSubject, - firstSemesterSubject: GradeSubject?, - config: AverageCalcParams, - ): Double { - return if (!isAnyVulcanAverage || config.forceAverageCalc) { - val isSecondSemesterHasWeightGrade = secondSemesterSubject.grades - .any { it.weightValue > .0 } - val isSecondSemesterHasArithmeticGrade = secondSemesterSubject.grades - .all { it.weightValue == .0 } && config.isOptionalArithmeticAverage - val isSecondSemesterHaveAverage = - isSecondSemesterHasWeightGrade || isSecondSemesterHasArithmeticGrade - - val divider = if (isSecondSemesterHaveAverage) 2 else 1 - val secondSemesterAverage = secondSemesterSubject.grades - .updateModifiers(student, config) - .calcAverage(isOptionalArithmeticAverage = config.isOptionalArithmeticAverage) - val firstSemesterAverage = firstSemesterSubject?.grades - ?.updateModifiers(student, config) - ?.calcAverage(isOptionalArithmeticAverage = config.isOptionalArithmeticAverage) - ?: secondSemesterAverage - - (secondSemesterAverage + firstSemesterAverage) / divider - } else { - val divider = if (secondSemesterSubject.average > 0) 2 else 1 - - secondSemesterSubject.average.plus( - (firstSemesterSubject?.average ?: secondSemesterSubject.average) - ) / divider + if (selectedSemester != firstSemester) { + getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails -> + secondDetails.copy(data = selectedDetails.data?.map { selected -> + val second = secondDetails.data.orEmpty().singleOrNull { it.subject == selected.subject } + selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) { + (selected.grades.updateModifiers(student) + second?.grades?.updateModifiers(student).orEmpty()).calcAverage() + } else selected.average) + }) + }.filter { it.status != Status.LOADING }.filter { it.data != null } + } else flowOf(selectedDetails) } } - private fun getGradeSubjects( - student: Student, - semester: Semester, - forceRefresh: Boolean, - params: AverageCalcParams, - ): Flow>> { - return gradeRepository.getGrades(student, semester, forceRefresh = forceRefresh) - .mapResourceData { res -> - val (details, summaries, descriptives) = res - val isAnyAverage = summaries.any { it.average != .0 } - val allGrades = details.groupBy { it.subject } - val descriptiveGradesBySubject = descriptives.associateBy { it.subject } + private fun getSemesterDetailsWithAverage(student: Student, semester: Semester, forceRefresh: Boolean): Flow>> { + return gradeRepository.getGrades(student, semester, forceRefresh = forceRefresh).map { res -> + val (details, summaries) = res.data ?: null to null + val isAnyAverage = summaries.orEmpty().any { it.average != .0 } + val allGrades = details.orEmpty().groupBy { it.subject } - val items = summaries - .createEmptySummariesByGradesIfNeeded( - student = student, - semester = semester, - grades = allGrades.toList(), - calcAverage = isAnyAverage, - params = params, - ) - .createEmptySummariesByDescriptiveGradesIfNeeded( - student = student, - semester = semester, - descriptives = descriptives, - ) - .map { summary -> - val grades = allGrades[summary.subject].orEmpty() - val descriptiveGrade = descriptiveGradesBySubject[summary.subject] - - GradeSubject( - subject = summary.subject, - average = if (!isAnyAverage || params.forceAverageCalc) { - grades.updateModifiers(student, params) - .calcAverage(isOptionalArithmeticAverage = params.isOptionalArithmeticAverage) - } else summary.average, - points = summary.pointsSum, - summary = summary, - grades = grades, - descriptive = descriptiveGrade, - isVulcanAverage = isAnyAverage - ) - } - - items - } - } - - private fun List.createEmptySummariesByDescriptiveGradesIfNeeded( - student: Student, - semester: Semester, - descriptives: List - ): List { - val summarySubjects = this.map { it.subject } - val gradeSummaryToAdd = descriptives.mapNotNull { gradeDescriptive -> - if (gradeDescriptive.subject in summarySubjects) return@mapNotNull null - - GradeSummary( - studentId = student.studentId, - semesterId = semester.semesterId, - position = 0, - subject = gradeDescriptive.subject, - predictedGrade = "", - finalGrade = "", - proposedPoints = "", - finalPoints = "", - pointsSum = "", - pointsSumAllYear = null, - average = .0, - averageAllYear = null, - ) + Resource(res.status, summaries?.emulateEmptySummaries(student, semester, allGrades.toList(), isAnyAverage)?.map { summary -> + val grades = allGrades[summary.subject].orEmpty() + GradeDetailsWithAverage( + subject = summary.subject, + average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) { + grades.updateModifiers(student).calcAverage() + } else summary.average, + points = summary.pointsSum, + summary = summary, + grades = grades + ) + }, res.error) } - - return this + gradeSummaryToAdd } - private fun List.createEmptySummariesByGradesIfNeeded( - student: Student, - semester: Semester, - grades: List>>, - calcAverage: Boolean, - params: AverageCalcParams, - ): List { + private fun List.emulateEmptySummaries(student: Student, semester: Semester, grades: List>>, calcAverage: Boolean): List { if (isNotEmpty() && size > grades.size) return this return grades.mapIndexed { i, (subject, details) -> @@ -296,23 +123,14 @@ class GradeAverageProvider @Inject constructor( proposedPoints = "", finalPoints = "", pointsSum = "", - pointsSumAllYear = null, - average = when { - calcAverage -> details - .updateModifiers(student, params) - .calcAverage(isOptionalArithmeticAverage = params.isOptionalArithmeticAverage) - - else -> .0 - }, - averageAllYear = null, + average = if (calcAverage) details.updateModifiers(student).calcAverage() else .0 ) } } - private fun List.updateModifiers( - student: Student, - params: AverageCalcParams, - ): List = if (student.loginMode == Sdk.Mode.SCRAPPER.name) { - map { it.changeModifier(params.plusModifier, params.minusModifier) } - } else this + private fun List.updateModifiers(student: Student): List { + return if (student.loginMode == Sdk.Mode.SCRAPPER.name) { + map { it.changeModifier(plusModifier, minusModifier) } + } else this + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSubject.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeDetailsWithAverage.kt similarity index 58% rename from app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSubject.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeDetailsWithAverage.kt index a465551f..3f5d706b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSubject.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeDetailsWithAverage.kt @@ -1,15 +1,12 @@ package io.github.wulkanowy.ui.modules.grade import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.db.entities.GradeDescriptive import io.github.wulkanowy.data.db.entities.GradeSummary -data class GradeSubject( +data class GradeDetailsWithAverage( val subject: String, val average: Double, val points: String, val summary: GradeSummary, - val descriptive: GradeDescriptive?, - val grades: List, - val isVulcanAverage: Boolean + val grades: List ) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt index cc61dc25..0678e13e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt @@ -7,11 +7,9 @@ import android.view.MenuItem import android.view.View import android.view.View.INVISIBLE import android.view.View.VISIBLE -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.tabs.TabLayoutMediator +import androidx.appcompat.app.AlertDialog import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.databinding.FragmentGradeBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter @@ -30,9 +28,12 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade @Inject lateinit var presenter: GradePresenter + private val pagerAdapter by lazy { BaseFragmentPagerAdapter(childFragmentManager) } + private var semesterSwitchMenu: MenuItem? = null companion object { + private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER" fun newInstance() = GradeFragment() } @@ -43,9 +44,6 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade override val currentPageIndex get() = binding.gradeViewPager.currentItem - private var pagerAdapter: BaseFragmentPagerAdapter? = null - - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -54,7 +52,7 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentGradeBinding.bind(view) - presenter.onAttachView(this) + presenter.onAttachView(this, savedInstanceState?.getInt(SAVED_SEMESTER_KEY)) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -64,18 +62,14 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade } override fun initView() { - with(binding) { - gradeErrorRetry.setOnClickListener { presenter.onRetry() } - gradeErrorDetails.setOnClickListener { presenter.onDetailsClick() } + with(pagerAdapter) { + containerId = binding.gradeViewPager.id + addFragmentsWithTitle(mapOf( + GradeDetailsFragment.newInstance() to getString(R.string.all_details), + GradeSummaryFragment.newInstance() to getString(R.string.grade_menu_summary), + GradeStatisticsFragment.newInstance() to getString(R.string.grade_menu_statistics) + )) } - } - - override fun initTabs(pageCount: Int) { - pagerAdapter = BaseFragmentPagerAdapter( - lifecycle = lifecycle, - pagesCount = pageCount, - fragmentManager = childFragmentManager - ) with(binding.gradeViewPager) { adapter = pagerAdapter @@ -83,28 +77,15 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade setOnSelectPageListener(presenter::onPageSelected) } - with(pagerAdapter!!) { - containerId = binding.gradeViewPager.id - titleFactory = { - when (it) { - 0 -> getString(R.string.all_details) - 1 -> getString(R.string.grade_menu_summary) - 2 -> getString(R.string.grade_menu_statistics) - else -> throw IllegalStateException() - } - } - itemFactory = { - when (it) { - 0 -> GradeDetailsFragment.newInstance() - 1 -> GradeSummaryFragment.newInstance() - 2 -> GradeStatisticsFragment.newInstance() - else -> throw IllegalStateException() - } - } - TabLayoutMediator(binding.gradeTabLayout, binding.gradeViewPager, this).attach() + with(binding.gradeTabLayout) { + setupWithViewPager(binding.gradeViewPager) + setElevationCompat(context.dpToPx(4f)) } - binding.gradeTabLayout.elevation = requireContext().dpToPx(4f) + with(binding) { + gradeErrorRetry.setOnClickListener { presenter.onRetry() } + gradeErrorDetails.setOnClickListener { presenter.onDetailsClick() } + } } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -139,11 +120,13 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade semesterSwitchMenu?.isVisible = show } - override fun showSemesterDialog(selectedIndex: Int, semesters: List) { - val choices = semesters.map { getString(R.string.grade_semester, it.semesterName) } - .toTypedArray() + override fun showSemesterDialog(selectedIndex: Int) { + val choices = arrayOf( + getString(R.string.grade_semester, 1), + getString(R.string.grade_semester, 2) + ) - MaterialAlertDialogBuilder(requireContext()) + AlertDialog.Builder(requireContext()) .setSingleChoiceItems(choices, selectedIndex) { dialog, which -> presenter.onSemesterSelected(which) dialog.dismiss() @@ -155,10 +138,7 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade override fun setCurrentSemesterName(semester: Int, schoolYear: Int) { subtitleString = getString(R.string.grade_subtitle, semester, schoolYear, schoolYear + 1) - - if (isVisible) { - (activity as MainView?)?.setViewSubTitle(subtitleString) - } + (activity as MainView).setViewSubTitle(subtitleString) } fun onChildRefresh() { @@ -170,20 +150,23 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade } override fun notifyChildLoadData(index: Int, semesterId: Int, forceRefresh: Boolean) { - (pagerAdapter?.getFragmentInstance(index) as? GradeView.GradeChildView) - ?.onParentLoadData(semesterId, forceRefresh) + (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentLoadData(semesterId, forceRefresh) } override fun notifyChildParentReselected(index: Int) { - (pagerAdapter?.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentReselected() + (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentReselected() } override fun notifyChildSemesterChange(index: Int) { - (pagerAdapter?.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentChangeSemester() + (pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentChangeSemester() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putInt(SAVED_SEMESTER_KEY, presenter.selectedIndex) } override fun onDestroyView() { - pagerAdapter = null presenter.onDetachView() super.onDestroyView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt index 8a70b3c1..e91c94eb 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradePresenter.kt @@ -1,16 +1,16 @@ package io.github.wulkanowy.ui.modules.grade +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.getCurrentOrLast +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -21,15 +21,20 @@ class GradePresenter @Inject constructor( private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { - private var selectedIndex = 0 + var selectedIndex = 0 + private set + private var schoolYear = 0 - private var availableSemesters = emptyList() + + private var semesters = emptyList() + private val loadedSemesterId = mutableMapOf() private lateinit var lastError: Throwable - override fun onAttachView(view: GradeView) { + fun onAttachView(view: GradeView, savedIndex: Int?) { super.onAttachView(view) + selectedIndex = savedIndex ?: 0 view.initView() Timber.i("Grade view was initialized with $selectedIndex index") errorHandler.showErrorMessage = ::showErrorViewOnError @@ -37,7 +42,7 @@ class GradePresenter @Inject constructor( } fun onCreateMenu() { - if (availableSemesters.isEmpty()) view?.showSemesterSwitch(false) + if (semesters.isEmpty()) view?.showSemesterSwitch(false) } fun onViewReselected() { @@ -46,9 +51,7 @@ class GradePresenter @Inject constructor( } fun onSemesterSwitch(): Boolean { - if (availableSemesters.isNotEmpty()) { - view?.showSemesterDialog(selectedIndex - 1, availableSemesters.take(2)) - } + if (semesters.isNotEmpty()) view?.showSemesterDialog(selectedIndex - 1) return true } @@ -80,7 +83,7 @@ class GradePresenter @Inject constructor( } fun onPageSelected(index: Int) { - if (availableSemesters.isNotEmpty()) loadChild(index) + if (semesters.isNotEmpty()) loadChild(index) } fun onRetry() { @@ -96,34 +99,33 @@ class GradePresenter @Inject constructor( } private fun loadData() { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() - val semesters = semesterRepository.getSemesters(student, refreshOnNoCurrent = true) + delay(200) + semesterRepository.getSemesters(student, refreshOnNoCurrent = true) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading grade data started") + Status.SUCCESS -> { + val current = it.data!!.getCurrentOrLast() + selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex + schoolYear = current.schoolYear + semesters = it.data.filter { semester -> semester.diaryId == current.diaryId } + view?.setCurrentSemesterName(current.semesterName, schoolYear) - student to semesters - } - .logResourceStatus("load grade data") - .onResourceData { (student, semesters) -> - val currentSemester = semesters.getCurrentOrLast() - selectedIndex = - if (selectedIndex == 0) currentSemester.semesterName else selectedIndex - schoolYear = currentSemester.schoolYear - availableSemesters = semesters.filter { semester -> - semester.diaryId == currentSemester.diaryId + view?.run { + Timber.i("Loading grade result: Attempt load index $currentPageIndex") + loadChild(currentPageIndex) + showErrorView(false) + showSemesterSwitch(true) + } } - - view?.run { - initTabs(if (student.isEduOne == true) 2 else 3) - setCurrentSemesterName(currentSemester.semesterName, schoolYear) - - Timber.i("Loading grade data: Attempt load index $currentPageIndex") - loadChild(currentPageIndex) - showErrorView(false) - showSemesterSwitch(true) + Status.ERROR -> { + Timber.i("Loading grade result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -136,18 +138,12 @@ class GradePresenter @Inject constructor( } private fun loadChild(index: Int, forceRefresh: Boolean = false) { - Timber.d("Load grade tab child. Selected semester: $selectedIndex, semesters: ${availableSemesters.joinToString { it.semesterName.toString() }}") - - val newSelectedSemesterId = try { - availableSemesters.first { it.semesterName == selectedIndex }.semesterId - } catch (e: NoSuchElementException) { - Timber.e(e, "Selected semester no exists") - return - } - - if (forceRefresh || loadedSemesterId[index] != newSelectedSemesterId) { - Timber.i("Load grade child view index: $index") - view?.notifyChildLoadData(index, newSelectedSemesterId, forceRefresh) + Timber.d("Load grade tab child. Selected semester: $selectedIndex, semesters: ${semesters.joinToString { it.semesterName.toString() }}") + semesters.first { it.semesterName == selectedIndex }.semesterId.also { + if (forceRefresh || loadedSemesterId[index] != it) { + Timber.i("Load grade child view index: $index") + view?.notifyChildLoadData(index, it, forceRefresh) + } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSortingMode.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSortingMode.kt new file mode 100644 index 00000000..1e6b26e8 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeSortingMode.kt @@ -0,0 +1,10 @@ +package io.github.wulkanowy.ui.modules.grade + +enum class GradeSortingMode(val value: String) { + ALPHABETIC("alphabetic"), + DATE("date"); + + companion object { + fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ALPHABETIC + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeView.kt index fc06c480..7b52daa8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeView.kt @@ -1,6 +1,5 @@ package io.github.wulkanowy.ui.modules.grade -import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.ui.base.BaseView interface GradeView : BaseView { @@ -9,8 +8,6 @@ interface GradeView : BaseView { fun initView() - fun initTabs(pageCount: Int) - fun showContent(show: Boolean) fun showProgress(show: Boolean) @@ -21,7 +18,7 @@ interface GradeView : BaseView { fun showSemesterSwitch(show: Boolean) - fun showSemesterDialog(selectedIndex: Int, semesters: List) + fun showSemesterDialog(selectedIndex: Int) fun setCurrentSemesterName(semester: Int, schoolYear: Int) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt index bcbd2df2..6f932169 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt @@ -1,27 +1,21 @@ package io.github.wulkanowy.ui.modules.grade.details import android.annotation.SuppressLint -import android.content.res.ColorStateList import android.content.res.Resources import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.NO_POSITION import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.enums.GradeExpandMode import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding import io.github.wulkanowy.databinding.ItemGradeDetailsBinding import io.github.wulkanowy.ui.base.BaseExpandableAdapter import io.github.wulkanowy.utils.getBackgroundColor -import io.github.wulkanowy.utils.getCompatColor import io.github.wulkanowy.utils.toFormattedString import timber.log.Timber -import java.util.* import javax.inject.Inject class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter() { @@ -30,20 +24,19 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter() - private val expandedPositions = BitSet(items.size) + private var expandedPosition = NO_POSITION - private var expandMode = GradeExpandMode.ONE + private var isExpandable = false var onClickListener: (Grade, position: Int) -> Unit = { _, _ -> } - lateinit var gradeColorTheme: GradeColorTheme + var colorTheme = "" - fun setDataItems(data: List, expandMode: GradeExpandMode = this.expandMode) { + fun setDataItems(data: List, isExpanded: Boolean = isExpandable) { headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList() - items = - (if (expandMode != GradeExpandMode.ALWAYS_EXPANDED) headers else data).toMutableList() - this.expandMode = expandMode - expandedPositions.clear() + items = if (isExpanded) headers else data.toMutableList() + isExpandable = isExpanded + expandedPosition = NO_POSITION } fun updateDetailsItem(position: Int, grade: Grade) { @@ -55,7 +48,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter 1) { - Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPositions. Items: $candidates") + Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPosition. Items: $candidates") } return candidates.first() @@ -71,9 +64,9 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter HeaderViewHolder( - HeaderGradeDetailsBinding.inflate(inflater, parent, false) - ) - - ViewType.ITEM.id -> ItemViewHolder( - ItemGradeDetailsBinding.inflate(inflater, parent, false) - ) - + ViewType.HEADER.id -> HeaderViewHolder(HeaderGradeDetailsBinding.inflate(inflater, parent, false)) + ViewType.ITEM.id -> ItemViewHolder(ItemGradeDetailsBinding.inflate(inflater, parent, false)) else -> throw IllegalStateException() } } @@ -112,7 +99,6 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter bindItemViewHolder( holder = holder, grade = items[position].value as Grade @@ -120,132 +106,65 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter 0 + gradeHeaderPointsSum.text = root.context.getString(R.string.grade_points_sum, header.pointsSum) + gradeHeaderPointsSum.visibility = if (!header.pointsSum.isNullOrEmpty()) View.VISIBLE else View.GONE + gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.grades.size, header.grades.size) + gradeHeaderNote.visibility = if (header.newGrades > 0) View.VISIBLE else View.GONE + if (header.newGrades > 0) gradeHeaderNote.text = header.newGrades.toString(10) - if (header.newGrades > 0) { - gradeHeaderNote.text = header.newGrades.toString() - } - - gradeHeaderContainer.isEnabled = expandMode != GradeExpandMode.ALWAYS_EXPANDED + gradeHeaderContainer.isEnabled = isExpandable gradeHeaderContainer.setOnClickListener { - expandGradeHeader(headerPosition, header, holder) - } - } - } + expandedPosition = if (expandedPosition == adapterPosition) -1 else adapterPosition - private fun expandGradeHeader( - headerPosition: Int, - header: GradeDetailsHeader, - holder: HeaderViewHolder - ) { - if (expandMode == GradeExpandMode.ONE) { - val isHeaderExpanded = expandedPositions[headerPosition] - - expandedPositions.clear() - - if (!isHeaderExpanded) { - val updatedItemList = headers.toMutableList() - .apply { addAll(headerPosition + 1, header.grades) } - - expandedPositions.set(headerPosition) - refreshList(updatedItemList) - scrollToHeaderWithSubItems(headerPosition, header.grades.size) - } else { - refreshList(headers.toMutableList()) - } - } else if (expandMode == GradeExpandMode.UNLIMITED) { - val headerAdapterPosition = holder.bindingAdapterPosition - val isHeaderExpanded = expandedPositions[headerPosition] - - expandedPositions.flip(headerPosition) - - if (!isHeaderExpanded) { - val updatedList = items.toMutableList() - .apply { addAll(headerAdapterPosition + 1, header.grades) } - - refreshList(updatedList) - scrollToHeaderWithSubItems(headerAdapterPosition, header.grades.size) - } else { - val startPosition = headerAdapterPosition + 1 - val updatedList = items.toMutableList() - .apply { - subList(startPosition, startPosition + header.grades.size).clear() - } - - refreshList(updatedList) - } - } - } - - @SuppressLint("SetTextI18n") - private fun bindItemViewHolder(holder: ItemViewHolder, grade: Grade) { - val context = holder.binding.root.context - - with(holder.binding) { - gradeItemValue.run { - text = grade.entry - backgroundTintList = ColorStateList.valueOf( - context.getCompatColor(grade.getBackgroundColor(gradeColorTheme)) - ) - } - gradeItemDescription.text = when { - grade.description.isNotBlank() -> grade.description - grade.gradeSymbol.isNotBlank() -> grade.gradeSymbol - else -> context.getString(R.string.all_no_description) - } - gradeItemDate.text = grade.date.toFormattedString() - gradeItemWeight.text = "${context.getString(R.string.grade_weight)}: ${grade.weight}" - gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE - - root.setOnClickListener { - holder.bindingAdapterPosition.let { - if (it != NO_POSITION) onClickListener(grade, it) + if (expandedPosition != NO_POSITION) { + refreshList(headers.toMutableList().apply { + addAll(headerPosition + 1, header.grades) + }) + scrollToHeaderWithSubItems(headerPosition, header.grades.size) + } else { + refreshList(headers) } } } } - private fun formatAverage(average: Double?, resources: Resources) = - if (average == null || average == .0) { - resources.getString(R.string.grade_no_average) - } else { - resources.getString(R.string.grade_average, average) - } + private fun formatAverage(average: Double?, resources: Resources): String { + return if (average == null || average == .0) resources.getString(R.string.grade_no_average) + else resources.getString(R.string.grade_average, average) + } - private fun formatAverageAllYear(average: Double?, resources: Resources) = - if (average == null || average == .0) { - resources.getString(R.string.grade_no_average) - } else { - resources.getString(R.string.grade_average_year, average) + @SuppressLint("SetTextI18n") + private fun bindItemViewHolder(holder: ItemViewHolder, grade: Grade) { + with(holder.binding) { + gradeItemValue.run { + text = grade.entry + setBackgroundResource(grade.getBackgroundColor(colorTheme)) + } + gradeItemDescription.text = when { + grade.description.isNotBlank() -> grade.description + grade.gradeSymbol.isNotBlank() -> grade.gradeSymbol + else -> root.context.getString(R.string.all_no_description) + } + gradeItemDate.text = grade.date.toFormattedString() + gradeItemWeight.text = "${root.context.getString(R.string.grade_weight)}: ${grade.weight}" + gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE + + root.setOnClickListener { + holder.adapterPosition.let { if (it != NO_POSITION) onClickListener(grade, it) } + } } + } private class HeaderViewHolder(val binding: HeaderGradeDetailsBinding) : RecyclerView.ViewHolder(binding.root) @@ -253,10 +172,8 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter, - private val new: List - ) : DiffUtil.Callback() { + class GradeDetailsDiffUtil(private val old: List, private val new: List) : + DiffUtil.Callback() { override fun getOldListSize() = old.size diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt index 39f72f8b..698aff3e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt @@ -1,63 +1,65 @@ package io.github.wulkanowy.ui.modules.grade.details -import android.app.Dialog -import android.content.res.ColorStateList import android.os.Bundle +import android.view.LayoutInflater import android.view.View import android.view.View.GONE -import androidx.core.content.ContextCompat -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeColorTheme import io.github.wulkanowy.databinding.DialogGradeBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.colorStringId +import io.github.wulkanowy.utils.getBackgroundColor +import io.github.wulkanowy.utils.getGradeColor +import io.github.wulkanowy.utils.lifecycleAwareVariable +import io.github.wulkanowy.utils.toFormattedString -@AndroidEntryPoint -class GradeDetailsDialog : BaseDialogFragment() { +class GradeDetailsDialog : DialogFragment() { + + private var binding: DialogGradeBinding by lifecycleAwareVariable() private lateinit var grade: Grade - private lateinit var gradeColorTheme: GradeColorTheme + private lateinit var colorScheme: String companion object { - private const val ARGUMENT_KEY = "Item" + private const val COLOR_SCHEME_KEY = "Scheme" - private const val COLOR_THEME_KEY = "Theme" - - fun newInstance(grade: Grade, colorTheme: GradeColorTheme) = GradeDetailsDialog().apply { - arguments = bundleOf( - ARGUMENT_KEY to grade, - COLOR_THEME_KEY to colorTheme - ) + fun newInstance(grade: Grade, colorScheme: String): GradeDetailsDialog { + return GradeDetailsDialog().apply { + arguments = Bundle().apply { + putSerializable(ARGUMENT_KEY, grade) + putString(COLOR_SCHEME_KEY, colorScheme) + } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - grade = requireArguments().serializable(ARGUMENT_KEY) - gradeColorTheme = requireArguments().serializable(COLOR_THEME_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + grade = getSerializable(ARGUMENT_KEY) as Grade + colorScheme = getString(COLOR_SCHEME_KEY) ?: "default" + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogGradeBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogGradeBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(binding) { gradeDialogSubject.text = grade.subject - gradeDialogWeightValue.text = grade.weight - gradeDialogWeightLayout.backgroundTintList = - ColorStateList.valueOf(requireContext().getCompatColor(grade.getGradeColor())) + gradeDialogColorAndWeightValue.run { + text = context.getString(R.string.grade_weight_value, grade.weight) + setBackgroundResource(grade.getGradeColor()) + } gradeDialogDateValue.text = grade.date.toFormattedString() gradeDialogColorValue.text = getString(grade.colorStringId) @@ -71,15 +73,12 @@ class GradeDetailsDialog : BaseDialogFragment() { gradeDialogValue.run { text = grade.entry - backgroundTintList = ColorStateList.valueOf( - ContextCompat.getColor( - requireContext(), - grade.getBackgroundColor(gradeColorTheme) - ) - ) + setBackgroundResource(grade.getBackgroundColor(colorScheme)) } - gradeDialogTeacherValue.text = grade.teacher.ifBlank { getString(R.string.all_no_data) } + gradeDialogTeacherValue.text = if (grade.teacher.isBlank()) { + getString(R.string.all_no_data) + } else grade.teacher gradeDialogDescriptionValue.text = grade.run { when { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt index 23d767a6..ef9a932e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt @@ -5,19 +5,18 @@ import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View -import android.view.View.* +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.enums.GradeExpandMode import io.github.wulkanowy.databinding.FragmentGradeDetailsBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.grade.GradeView import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint @@ -40,7 +39,6 @@ class GradeDetailsFragment : override val isViewEmpty get() = gradeDetailsAdapter.itemCount == 0 - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -67,9 +65,7 @@ class GradeDetailsFragment : layoutManager = LinearLayoutManager(context) adapter = gradeDetailsAdapter } - gradeDetailsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - gradeDetailsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - gradeDetailsSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) + gradeDetailsSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } gradeDetailsErrorRetry.setOnClickListener { presenter.onRetry() } gradeDetailsErrorDetails.setOnClickListener { presenter.onDetailsClick() } } @@ -80,10 +76,10 @@ class GradeDetailsFragment : else false } - override fun updateData(data: List, expandMode: GradeExpandMode, gradeColorTheme: GradeColorTheme) { + override fun updateData(data: List, isGradeExpandable: Boolean, gradeColorTheme: String) { with(gradeDetailsAdapter) { - this.gradeColorTheme = gradeColorTheme - setDataItems(data, expandMode) + colorTheme = gradeColorTheme + setDataItems(data, isGradeExpandable) notifyDataSetChanged() } } @@ -143,8 +139,8 @@ class GradeDetailsFragment : binding.gradeDetailsSwipe.isRefreshing = show } - override fun showGradeDialog(grade: Grade, colorTheme: GradeColorTheme) { - (activity as? MainActivity)?.showDialogFragment(GradeDetailsDialog.newInstance(grade, colorTheme)) + override fun showGradeDialog(grade: Grade, colorScheme: String) { + (activity as? MainActivity)?.showDialogFragment(GradeDetailsDialog.newInstance(grade, colorScheme)) } override fun onParentLoadData(semesterId: Int, forceRefresh: Boolean) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsItem.kt index 1224efaf..479aff80 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsItem.kt @@ -13,7 +13,6 @@ data class GradeDetailsItem( data class GradeDetailsHeader( val subject: String, val average: Double?, - val averageAllYear: Double?, val pointsSum: String?, val grades: List ) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt index ec5d34c5..a34dd7ac 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt @@ -1,29 +1,24 @@ package io.github.wulkanowy.ui.modules.grade.details +import android.annotation.SuppressLint +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeExpandMode -import io.github.wulkanowy.data.enums.GradeSortingMode.ALPHABETIC -import io.github.wulkanowy.data.enums.GradeSortingMode.AVERAGE -import io.github.wulkanowy.data.enums.GradeSortingMode.DATE -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceIntermediate -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.GradeRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.grade.GradeRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider -import io.github.wulkanowy.ui.modules.grade.GradeSubject +import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage +import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.ALPHABETIC +import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.DATE import io.github.wulkanowy.utils.AnalyticsHelper -import kotlinx.coroutines.flow.catch +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.flowWithResourceIn import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -52,8 +47,8 @@ class GradeDetailsPresenter @Inject constructor( fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) { currentSemesterId = semesterId - if (!forceRefresh) view?.showErrorView(false) loadData(semesterId, forceRefresh) + if (!forceRefresh) view?.showErrorView(false) } fun onGradeItemSelected(grade: Grade, position: Int) { @@ -75,7 +70,7 @@ class GradeDetailsPresenter @Inject constructor( } fun onMarkAsReadSelected(): Boolean { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() val semesters = semesterRepository.getSemesters(student) val semester = semesters.first { item -> item.semesterId == currentSemesterId } @@ -83,11 +78,19 @@ class GradeDetailsPresenter @Inject constructor( Timber.i("Mark as read ${unreadGrades.size} grades") gradeRepository.updateGrades(unreadGrades.map { it.apply { isRead = true } }) - } - .logResourceStatus("mark grades as read") - .onResourceSuccess { loadData(currentSemesterId, false) } - .onResourceError(errorHandler::dispatch) - .launch("mark") + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Select mark grades as read") + Status.SUCCESS -> { + Timber.i("Mark as read result: Success") + loadData(currentSemesterId, false) + } + Status.ERROR -> { + Timber.i("Mark as read result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.launch("mark") return true } @@ -111,7 +114,7 @@ class GradeDetailsPresenter @Inject constructor( fun onParentViewReselected() { view?.run { if (!isViewEmpty) { - if (preferencesRepository.gradeExpandMode != GradeExpandMode.ALWAYS_EXPANDED) collapseAllItems() + if (preferencesRepository.isGradeExpandable) collapseAllItems() scrollToStart() } } @@ -134,56 +137,46 @@ class GradeDetailsPresenter @Inject constructor( } private fun loadData(semesterId: Int, forceRefresh: Boolean) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh) - } - .logResourceStatus("load grade details") - .onResourceData { - val gradeItems = createGradeItems(it) - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(gradeItems.isNotEmpty()) - showEmpty(gradeItems.isEmpty()) - updateNewGradesAmount(it) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading grade details data started") + Status.SUCCESS -> { + Timber.i("Loading grade details result: Success") + newGradesAmount = it.data!!.sumBy { item -> item.grades.sumBy { grade -> if (!grade.isRead) 1 else 0 } } updateMarkAsDoneButton() - updateData( - data = gradeItems, - expandMode = preferencesRepository.gradeExpandMode, - preferencesRepository.gradeColorTheme + val items = createGradeItems(it.data) + view?.run { + showEmpty(items.isEmpty()) + showErrorView(false) + showContent(items.isNotEmpty()) + updateData( + data = items, + isGradeExpandable = preferencesRepository.isGradeExpandable, + gradeColorTheme = preferencesRepository.gradeColorTheme + ) + } + analytics.logEvent( + "load_data", + "type" to "grade_details", + "items" to it.data.size ) } - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "grade_details", - "items" to it.size - ) - } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showRefresh(false) - showProgress(false) - notifyParentDataLoaded(semesterId) + Status.ERROR -> { + Timber.i("Loading grade details result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .catch { - errorHandler.dispatch(it) - view?.notifyParentDataLoaded(semesterId) + }.afterLoading { + view?.run { + showRefresh(false) + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded(semesterId) } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private fun updateNewGradesAmount(grades: List) { - newGradesAmount = grades.sumOf { item -> - item.grades.sumOf { grade -> (if (!grade.isRead) 1 else 0).toInt() } - } + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -193,60 +186,50 @@ class GradeDetailsPresenter @Inject constructor( setErrorDetails(message) showErrorView(true) showEmpty(false) - showProgress(false) } else showError(message, error) } } - private fun createGradeItems(items: List): List { + @SuppressLint("DefaultLocale") + private fun createGradeItems(items: List): List { return items .let { gradesWithAverages -> if (!preferencesRepository.showSubjectsWithoutGrades) { gradesWithAverages.filter { it.grades.isNotEmpty() } } else gradesWithAverages } - .let { gradeSubjects -> + .let { when (preferencesRepository.gradeSortingMode) { - DATE -> gradeSubjects.sortedByDescending { gradeDetailsWithAverage -> - gradeDetailsWithAverage.grades.maxByOrNull { it.date }?.date - } - ALPHABETIC -> gradeSubjects.sortedBy { gradeDetailsWithAverage -> - gradeDetailsWithAverage.subject.lowercase() - } - AVERAGE -> gradeSubjects.sortedByDescending { it.average } + DATE -> it.sortedByDescending { gradeDetailsWithAverage -> gradeDetailsWithAverage.grades.firstOrNull()?.date } + ALPHABETIC -> it.sortedBy { gradeDetailsWithAverage -> gradeDetailsWithAverage.subject.toLowerCase() } } } - .map { gradeSubject -> - val subItems = gradeSubject.grades + .map { (subject, average, points, _, grades) -> + val subItems = grades .sortedByDescending { it.date } .map { GradeDetailsItem(it, ViewType.ITEM) } - val gradeDetailsItems = listOf( - GradeDetailsItem( - GradeDetailsHeader( - subject = gradeSubject.subject, - average = gradeSubject.average, - averageAllYear = gradeSubject.summary.averageAllYear, - pointsSum = gradeSubject.points, - grades = subItems, - ).apply { - newGrades = gradeSubject.grades.filter { grade -> !grade.isRead }.size - }, ViewType.HEADER - ) - ) - - if (preferencesRepository.gradeExpandMode == GradeExpandMode.ALWAYS_EXPANDED) { - gradeDetailsItems + subItems - } else { - gradeDetailsItems - } + listOf(GradeDetailsItem(GradeDetailsHeader( + subject = subject, + average = average, + pointsSum = points, + grades = subItems + ).apply { + newGrades = grades.filter { grade -> !grade.isRead }.size + }, ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems }.flatten() } private fun updateGrade(grade: Grade) { - resourceFlow { gradeRepository.updateGrade(grade) } - .logResourceStatus("update grade result ${grade.id}") - .onResourceError(errorHandler::dispatch) - .launch("update") + flowWithResource { gradeRepository.updateGrade(grade) }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Attempt to update grade ${grade.id}") + Status.SUCCESS -> Timber.i("Update grade result: Success") + Status.ERROR -> { + Timber.i("Update grade result: An exception occurred") + errorHandler.dispatch(it.error!!) + } + } + }.launch("update") } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsView.kt index 491bf300..e71fcc3c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsView.kt @@ -1,8 +1,6 @@ package io.github.wulkanowy.ui.modules.grade.details import io.github.wulkanowy.data.db.entities.Grade -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.data.enums.GradeExpandMode import io.github.wulkanowy.ui.base.BaseView interface GradeDetailsView : BaseView { @@ -11,7 +9,7 @@ interface GradeDetailsView : BaseView { fun initView() - fun updateData(data: List, expandMode: GradeExpandMode, gradeColorTheme: GradeColorTheme) + fun updateData(data: List, isGradeExpandable: Boolean, gradeColorTheme: String) fun updateItem(item: Grade, position: Int) @@ -23,7 +21,7 @@ interface GradeDetailsView : BaseView { fun collapseAllItems() - fun showGradeDialog(grade: Grade, colorTheme: GradeColorTheme) + fun showGradeDialog(grade: Grade, colorScheme: String) fun showContent(show: Boolean) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsAdapter.kt index e5f1eba0..cbcb444a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsAdapter.kt @@ -9,35 +9,32 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.github.mikephil.charting.components.Legend import com.github.mikephil.charting.components.LegendEntry -import com.github.mikephil.charting.data.* +import com.github.mikephil.charting.data.BarData +import com.github.mikephil.charting.data.BarDataSet +import com.github.mikephil.charting.data.BarEntry +import com.github.mikephil.charting.data.PieData +import com.github.mikephil.charting.data.PieDataSet +import com.github.mikephil.charting.data.PieEntry import com.github.mikephil.charting.formatter.ValueFormatter import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.GradePartialStatistics import io.github.wulkanowy.data.db.entities.GradePointsStatistics import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics -import io.github.wulkanowy.data.enums.GradeColorTheme import io.github.wulkanowy.data.pojos.GradeStatisticsItem import io.github.wulkanowy.databinding.ItemGradeStatisticsBarBinding -import io.github.wulkanowy.databinding.ItemGradeStatisticsHeaderBinding import io.github.wulkanowy.databinding.ItemGradeStatisticsPieBinding import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject -import kotlin.math.max -import kotlin.math.roundToInt class GradeStatisticsAdapter @Inject constructor() : RecyclerView.Adapter() { - var currentDataType = GradeStatisticsItem.DataType.PARTIAL - var items = emptyList() - lateinit var gradeColorTheme: GradeColorTheme + var theme: String = "vulcan" var showAllSubjectsOnList: Boolean = false - var onDataTypeChangeListener: () -> Unit = {} - private val vulcanGradeColors = listOf( 6 to R.color.grade_vulcan_six, 5 to R.color.grade_vulcan_five, @@ -65,145 +62,56 @@ class GradeStatisticsAdapter @Inject constructor() : "6, 6-", "5, 5-, 5+", "4, 4-, 4+", "3, 3-, 3+", "2, 2-, 2+", "1, 1+" ) - override fun getItemCount() = - (if (showAllSubjectsOnList) items.size else (if (items.isEmpty()) 0 else 1)) + 1 + override fun getItemCount() = if (showAllSubjectsOnList) items.size else (if (items.isEmpty()) 0 else 1) - override fun getItemViewType(position: Int) = - if (position == 0) { - ViewType.HEADER.id - } else { - when (items[position - 1].type) { - GradeStatisticsItem.DataType.PARTIAL -> ViewType.PARTIAL.id - GradeStatisticsItem.DataType.POINTS -> ViewType.POINTS.id - GradeStatisticsItem.DataType.SEMESTER -> ViewType.SEMESTER.id - } - } + override fun getItemViewType(position: Int) = items[position].type.id override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val inflater = LayoutInflater.from(parent.context) return when (viewType) { - ViewType.PARTIAL.id -> PartialViewHolder( - ItemGradeStatisticsPieBinding.inflate(inflater, parent, false) - ) - ViewType.SEMESTER.id -> SemesterViewHolder( - ItemGradeStatisticsPieBinding.inflate(inflater, parent, false) - ) - ViewType.POINTS.id -> PointsViewHolder( - ItemGradeStatisticsBarBinding.inflate(inflater, parent, false) - ) - ViewType.HEADER.id -> HeaderViewHolder( - ItemGradeStatisticsHeaderBinding.inflate(inflater, parent, false) - ) + ViewType.PARTIAL.id -> PartialViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false)) + ViewType.SEMESTER.id -> SemesterViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false)) + ViewType.POINTS.id -> PointsViewHolder(ItemGradeStatisticsBarBinding.inflate(inflater, parent, false)) else -> throw IllegalStateException() } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - val index = position - 1 - when (holder) { - is PartialViewHolder -> bindPartialChart(holder.binding, items[index].partial!!) - is SemesterViewHolder -> bindSemesterChart(holder.binding, items[index].semester!!) - is PointsViewHolder -> bindBarChart(holder.binding, items[index].points!!) - is HeaderViewHolder -> bindHeader(holder.binding) + is PartialViewHolder -> bindPartialChart(holder, items[position].partial!!) + is SemesterViewHolder -> bindSemesterChart(holder, items[position].semester!!) + is PointsViewHolder -> bindBarChart(holder, items[position].points!!) } } - private fun bindHeader(binding: ItemGradeStatisticsHeaderBinding) { - binding.gradeStatisticsTypeSwitch.check( - when (currentDataType) { - GradeStatisticsItem.DataType.PARTIAL -> R.id.gradeStatisticsTypePartial - GradeStatisticsItem.DataType.SEMESTER -> R.id.gradeStatisticsTypeSemester - GradeStatisticsItem.DataType.POINTS -> R.id.gradeStatisticsTypePoints - } - ) - - binding.gradeStatisticsTypeSwitch.addOnButtonCheckedListener { _, checkedId, isChecked -> - if (!isChecked) return@addOnButtonCheckedListener - - currentDataType = when (checkedId) { - R.id.gradeStatisticsTypePartial -> GradeStatisticsItem.DataType.PARTIAL - R.id.gradeStatisticsTypeSemester -> GradeStatisticsItem.DataType.SEMESTER - R.id.gradeStatisticsTypePoints -> GradeStatisticsItem.DataType.POINTS - else -> GradeStatisticsItem.DataType.PARTIAL - } - onDataTypeChangeListener() - } + private fun bindPartialChart(holder: PartialViewHolder, partials: GradePartialStatistics) { + bindPieChart(holder.binding, partials.subject, partials.classAverage, partials.classAmounts) } - private fun bindPartialChart( - binding: ItemGradeStatisticsPieBinding, - partials: GradePartialStatistics - ) { - val studentAverage = partials.studentAverage.takeIf { it.isNotEmpty() }?.let { - binding.root.context.getString(R.string.grade_statistics_student_average, it) - } - bindPieChart( - binding = binding, - subject = partials.subject, - average = partials.classAverage, - studentValue = studentAverage, - amounts = partials.classAmounts - ) + private fun bindSemesterChart(holder: SemesterViewHolder, semester: GradeSemesterStatistics) { + bindPieChart(holder.binding, semester.subject, semester.average, semester.amounts) } - private fun bindSemesterChart( - binding: ItemGradeStatisticsPieBinding, - semester: GradeSemesterStatistics - ) { - val studentAverage = semester.studentAverage.takeIf { it.isNotBlank() } - val studentGrade = semester.studentGrade.takeIf { it != 0 } - - val studentValue = when { - studentAverage != null -> binding.root.context.getString( - R.string.grade_statistics_student_average, - studentAverage - ) - studentGrade != null -> binding.root.context.getString( - R.string.grade_statistics_student_grade, - studentGrade.toString() - ) - else -> null - } - bindPieChart( - binding = binding, - subject = semester.subject, - average = semester.classAverage, - studentValue = studentValue, - amounts = semester.amounts - ) - } - - private fun bindPieChart( - binding: ItemGradeStatisticsPieBinding, - subject: String, - average: String, - studentValue: String?, - amounts: List - ) { + private fun bindPieChart(binding: ItemGradeStatisticsPieBinding, subject: String, average: String, amounts: List) { with(binding.gradeStatisticsPieTitle) { text = subject visibility = if (items.size == 1 || !showAllSubjectsOnList) GONE else VISIBLE } - val gradeColors = when (gradeColorTheme) { - GradeColorTheme.VULCAN -> vulcanGradeColors + val gradeColors = when (theme) { + "vulcan" -> vulcanGradeColors else -> materialGradeColors } - val dataset = PieDataSet( - amounts.mapIndexed { grade, amount -> - PieEntry(amount.toFloat(), (grade + 1).toString()) - }.reversed().filterNot { it.value == 0f }, - binding.root.context.getString(R.string.grade_statistics_legend) - ) + val dataset = PieDataSet(amounts.mapIndexed { grade, amount -> + PieEntry(amount.toFloat(), (grade + 1).toString()) + }.reversed().filterNot { it.value == 0f }, "Legenda") with(dataset) { valueTextSize = 12f sliceSpace = 1f valueTextColor = Color.WHITE - val grades = amounts.mapIndexed { grade, amount -> (grade + 1) to amount } - .filterNot { it.second == 0 } + val grades = amounts.mapIndexed { grade, amount -> (grade + 1) to amount }.filterNot { it.second == 0 } setColors(grades.reversed().map { (grade, _) -> gradeColors.single { color -> color.first == grade }.second }.toIntArray(), binding.root.context) @@ -215,11 +123,7 @@ class GradeStatisticsAdapter @Inject constructor() : data = PieData(dataset).apply { setValueFormatter(object : ValueFormatter() { override fun getPieLabel(value: Float, pieEntry: PieEntry): String { - return resources.getQuantityString( - R.plurals.grade_number_item, - value.toInt(), - value.toInt() - ) + return resources.getQuantityString(R.plurals.grade_number_item, value.toInt(), value.toInt()) } }) } @@ -234,16 +138,11 @@ class GradeStatisticsAdapter @Inject constructor() : }) } - val numberOfGradesString = amounts.fold(0) { acc, it -> acc + it } - .let { resources.getQuantityString(R.plurals.grade_number_item, it, it) } - val averageString = - binding.root.context.getString(R.string.grade_statistics_class_average, average) - minAngleForSlices = 25f description.isEnabled = false - centerText = - numberOfGradesString + ("\n\n" + averageString).takeIf { average.isNotBlank() } - .orEmpty() + studentValue?.let { "\n$it" }.orEmpty() + centerText = amounts.fold(0) { acc, it -> acc + it } + .let { resources.getQuantityString(R.plurals.grade_number_item, it, it) } + + ("\n\nŚrednia: $average").takeIf { average.isNotBlank() }.orEmpty() setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground)) setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary)) @@ -251,32 +150,27 @@ class GradeStatisticsAdapter @Inject constructor() : } } - private fun bindBarChart( - binding: ItemGradeStatisticsBarBinding, - points: GradePointsStatistics - ) { - with(binding.gradeStatisticsBarTitle) { + private fun bindBarChart(holder: PointsViewHolder, points: GradePointsStatistics) { + with(holder.binding.gradeStatisticsBarTitle) { text = points.subject visibility = if (items.size == 1) GONE else VISIBLE } - val dataset = BarDataSet( - listOf( - BarEntry(1f, points.others.toFloat()), - BarEntry(2f, points.student.toFloat()) - ), binding.root.context.getString(R.string.grade_statistics_legend) - ) + val dataset = BarDataSet(listOf( + BarEntry(1f, points.others.toFloat()), + BarEntry(2f, points.student.toFloat()) + ), "Legenda") with(dataset) { valueTextSize = 12f - valueTextColor = binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary) + valueTextColor = holder.binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary) valueFormatter = object : ValueFormatter() { - override fun getBarLabel(barEntry: BarEntry) = "${barEntry.y}" + override fun getBarLabel(barEntry: BarEntry) = "${barEntry.y}%" } colors = gradePointsColors } - with(binding.gradeStatisticsBar) { + with(holder.binding.gradeStatisticsBar) { setTouchEnabled(false) if (items.size == 1) animateXY(1000, 1000) data = BarData(dataset).apply { @@ -285,13 +179,12 @@ class GradeStatisticsAdapter @Inject constructor() : } legend.setCustom(listOf( LegendEntry().apply { - label = binding.root.context.getString(R.string.grade_statistics_average_class) + label = "Średnia klasy" formColor = gradePointsColors[0] form = Legend.LegendForm.SQUARE }, LegendEntry().apply { - label = - binding.root.context.getString(R.string.grade_statistics_average_student) + label = "Uczeń" formColor = gradePointsColors[1] form = Legend.LegendForm.SQUARE } @@ -300,26 +193,21 @@ class GradeStatisticsAdapter @Inject constructor() : description.isEnabled = false - binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary).let { + holder.binding.root.context.getThemeAttrColor(android.R.attr.textColorPrimary).let { axisLeft.textColor = it axisRight.textColor = it } xAxis.setDrawLabels(false) xAxis.setDrawGridLines(false) - - val yMaxFromValues = (max(points.others, points.student)).roundToInt() + 30f - val yMaxFromValuesWithMargin = ((yMaxFromValues / 10.0).roundToInt() * 10).toFloat() - val yMax = yMaxFromValuesWithMargin.coerceAtLeast(100f) - val yLabelCount = (yMax / 10).toInt() + 1 with(axisLeft) { axisMinimum = 0f - axisMaximum = yMax - labelCount = yLabelCount + axisMaximum = 100f + labelCount = 11 } with(axisRight) { axisMinimum = 0f - axisMaximum = yMax - labelCount = yLabelCount + axisMaximum = 100f + labelCount = 11 } invalidate() } @@ -333,7 +221,4 @@ class GradeStatisticsAdapter @Inject constructor() : private class PointsViewHolder(val binding: ItemGradeStatisticsBarBinding) : RecyclerView.ViewHolder(binding.root) - - private class HeaderViewHolder(val binding: ItemGradeStatisticsHeaderBinding) : - RecyclerView.ViewHolder(binding.root) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt index edc384c5..75050249 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt @@ -7,15 +7,12 @@ import android.widget.TextView import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.enums.GradeColorTheme import io.github.wulkanowy.data.pojos.GradeStatisticsItem import io.github.wulkanowy.databinding.FragmentGradeStatisticsBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.grade.GradeView import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.serializable import io.github.wulkanowy.utils.setOnItemSelectedListener import javax.inject.Inject @@ -34,37 +31,33 @@ class GradeStatisticsFragment : companion object { private const val SAVED_CHART_TYPE = "CURRENT_TYPE" - private const val SAVED_SUBJECT_NAME = "SUBJECT_NAME" fun newInstance() = GradeStatisticsFragment() } override val isViewEmpty get() = statisticsAdapter.items.isEmpty() - override val currentType get() = statisticsAdapter.currentDataType + override val currentType + get() = when (binding.gradeStatisticsTypeSwitch.checkedRadioButtonId) { + R.id.gradeStatisticsTypeSemester -> ViewType.SEMESTER + R.id.gradeStatisticsTypePartial -> ViewType.PARTIAL + else -> ViewType.POINTS + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentGradeStatisticsBinding.bind(view) - messageContainer = binding.gradeStatisticsRecycler - presenter.onAttachView( - view = this, - type = savedInstanceState?.serializable(SAVED_CHART_TYPE), - subjectName = savedInstanceState?.serializable(SAVED_SUBJECT_NAME), - ) + messageContainer = binding.gradeStatisticsSwipe + presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_CHART_TYPE) as? ViewType) } override fun initView() { - statisticsAdapter.onDataTypeChangeListener = presenter::onTypeChange - with(binding.gradeStatisticsRecycler) { layoutManager = LinearLayoutManager(requireContext()) - statisticsAdapter.currentDataType = presenter.currentType adapter = statisticsAdapter } - subjectsAdapter = - ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf()) + subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf()) subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject) with(binding.gradeStatisticsSubjects) { @@ -73,20 +66,15 @@ class GradeStatisticsFragment : } with(binding) { - gradeStatisticsSubjectsContainer.elevation = requireContext().dpToPx(1f) + gradeStatisticsSubjectsContainer.setElevationCompat(requireContext().dpToPx(1f)) gradeStatisticsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - gradeStatisticsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - gradeStatisticsSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) gradeStatisticsErrorRetry.setOnClickListener { presenter.onRetry() } gradeStatisticsErrorDetails.setOnClickListener { presenter.onDetailsClick() } } } - override fun updateSubjects(data: List, selectedIndex: Int) { - binding.gradeStatisticsSubjects.setSelection(selectedIndex) + override fun updateSubjects(data: ArrayList) { with(subjectsAdapter) { clear() addAll(data) @@ -94,15 +82,11 @@ class GradeStatisticsFragment : } } - override fun updateData( - newItems: List, - newTheme: GradeColorTheme, - showAllSubjectsOnStatisticsList: Boolean - ) { + override fun updateData(items: List, theme: String, showAllSubjectsOnStatisticsList: Boolean) { with(statisticsAdapter) { - showAllSubjectsOnList = showAllSubjectsOnStatisticsList - gradeColorTheme = newTheme - items = newItems + this.showAllSubjectsOnList = showAllSubjectsOnStatisticsList + this.theme = theme + this.items = items notifyDataSetChanged() } } @@ -116,7 +100,11 @@ class GradeStatisticsFragment : } override fun resetView() { - binding.gradeStatisticsRecycler.scrollToPosition(0) + binding.gradeStatisticsScroll.scrollTo(0, 0) + } + + override fun showContent(show: Boolean) { + binding.gradeStatisticsRecycler.visibility = if (show) View.VISIBLE else View.GONE } override fun showEmpty(show: Boolean) { @@ -163,10 +151,14 @@ class GradeStatisticsFragment : (parentFragment as? GradeFragment)?.onChildRefresh() } + override fun onResume() { + super.onResume() + binding.gradeStatisticsTypeSwitch.setOnCheckedChangeListener { _, _ -> presenter.onTypeChange() } + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putSerializable(SAVED_CHART_TYPE, presenter.currentType) - outState.putSerializable(SAVED_SUBJECT_NAME, presenter.currentSubjectName) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt index aa0e5999..aca3ec96 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsPresenter.kt @@ -1,12 +1,18 @@ package io.github.wulkanowy.ui.modules.grade.statistics -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Subject -import io.github.wulkanowy.data.pojos.GradeStatisticsItem -import io.github.wulkanowy.data.repositories.* +import io.github.wulkanowy.data.repositories.gradestatistics.GradeStatisticsRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.subject.SubjectRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -24,22 +30,16 @@ class GradeStatisticsPresenter @Inject constructor( private var currentSemesterId = 0 - var currentSubjectName: String = "Wszystkie" - private set + private var currentSubjectName: String = "Wszystkie" private lateinit var lastError: Throwable - var currentType: GradeStatisticsItem.DataType = GradeStatisticsItem.DataType.PARTIAL + var currentType: ViewType = ViewType.PARTIAL private set - fun onAttachView( - view: GradeStatisticsView, - type: GradeStatisticsItem.DataType?, - subjectName: String? - ) { + fun onAttachView(view: GradeStatisticsView, type: ViewType?) { super.onAttachView(view) - currentType = type ?: GradeStatisticsItem.DataType.PARTIAL - currentSubjectName = subjectName ?: currentSubjectName + currentType = type ?: ViewType.PARTIAL view.initView() errorHandler.showErrorMessage = ::showErrorViewOnError } @@ -58,11 +58,11 @@ class GradeStatisticsPresenter @Inject constructor( } fun onParentViewChangeSemester() { - clearDataInView() view?.run { showProgress(true) enableSwipe(false) showRefresh(false) + showContent(false) showErrorView(false) showEmpty(false) clearView() @@ -89,8 +89,8 @@ class GradeStatisticsPresenter @Inject constructor( fun onSubjectSelected(name: String?) { Timber.i("Select grade stats subject $name") - clearDataInView() view?.run { + showContent(false) showProgress(true) enableSwipe(false) showEmpty(false) @@ -103,11 +103,11 @@ class GradeStatisticsPresenter @Inject constructor( } fun onTypeChange() { - val type = view?.currentType ?: GradeStatisticsItem.DataType.POINTS + val type = view?.currentType ?: ViewType.POINTS Timber.i("Select grade stats semester: $type") cancelJobs("load") - clearDataInView() view?.run { + showContent(false) showProgress(true) enableSwipe(false) showEmpty(false) @@ -118,138 +118,84 @@ class GradeStatisticsPresenter @Inject constructor( } private fun loadSubjects() { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) subjectRepository.getSubjects(student, semester) - } - .logResourceStatus("load grade stats subjects") - .onResourceData { - subjects = it - view?.run { - showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList) - updateSubjects( - data = it.map { subject -> subject.name }, - selectedIndex = it.indexOfFirst { subject -> - subject.name == currentSubjectName - }, - ) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading grade stats subjects started") + Status.SUCCESS -> { + subjects = it.data!! + + Timber.i("Loading grade stats subjects result: Success") + view?.run { + view?.updateSubjects(ArrayList(it.data.map { subject -> subject.name })) + showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList) + } + } + Status.ERROR -> { + Timber.i("Loading grade stats subjects result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch("subjects") + }.launch("subjects") } - private fun loadDataByType( - semesterId: Int, - subjectName: String, - type: GradeStatisticsItem.DataType, - forceRefresh: Boolean = false - ) { - Timber.i("Loading grade stats data started") - + private fun loadDataByType(semesterId: Int, subjectName: String, type: ViewType, forceRefresh: Boolean = false) { + currentSubjectName = if (preferencesRepository.showAllSubjectsOnStatisticsList) "Wszystkie" else subjectName currentType = type - currentSubjectName = when { - preferencesRepository.showAllSubjectsOnStatisticsList -> "Wszystkie" - else -> subjectName - } - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semesters = semesterRepository.getSemesters(student) val semester = semesters.first { item -> item.semesterId == semesterId } with(gradeStatisticsRepository) { when (type) { - GradeStatisticsItem.DataType.PARTIAL -> { - getGradesPartialStatistics( - student = student, - semester = semester, - subjectName = currentSubjectName, - forceRefresh = forceRefresh - ) - } - GradeStatisticsItem.DataType.SEMESTER -> { - getGradesSemesterStatistics( - student = student, - semester = semester, - subjectName = currentSubjectName, - forceRefresh = forceRefresh - ) - } - GradeStatisticsItem.DataType.POINTS -> { - getGradesPointsStatistics( - student = student, - semester = semester, - subjectName = currentSubjectName, - forceRefresh = forceRefresh - ) - } + ViewType.PARTIAL -> getGradesPartialStatistics(student, semester, currentSubjectName, forceRefresh) + ViewType.SEMESTER -> getGradesSemesterStatistics(student, semester, currentSubjectName, forceRefresh) + ViewType.POINTS -> getGradesPointsStatistics(student, semester, currentSubjectName, forceRefresh) } } - } - .logResourceStatus("load grade stats data") - .mapResourceData { - val isNoContent = checkIsNoContent(it, type) - if (isNoContent) emptyList() else it - } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showEmpty(it.isEmpty()) - updateData( - newItems = it, - newTheme = preferencesRepository.gradeColorTheme, - showAllSubjectsOnStatisticsList = preferencesRepository.showAllSubjectsOnStatisticsList + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading grade stats data started") + Status.SUCCESS -> { + Timber.i("Loading grade stats result: Success") + view?.run { + val isNoContent = it.data!!.isEmpty() || when (type) { + ViewType.SEMESTER -> it.data.firstOrNull()?.semester?.amounts.orEmpty().sum() == 0 + ViewType.PARTIAL -> it.data.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0 + ViewType.POINTS -> it.data.firstOrNull()?.points?.let { points -> + points.student == .0 && points.others == .0 + } ?: false + } + showEmpty(isNoContent) + showContent(!isNoContent) + showErrorView(false) + updateData(it.data, preferencesRepository.gradeColorTheme, preferencesRepository.showAllSubjectsOnStatisticsList) + showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList) + } + analytics.logEvent( + "load_data", + "type" to "grade_statistics", + "items" to it.data!!.size ) } - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "grade_statistics", - "items" to it.size - ) - } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showRefresh(false) - showProgress(false) - notifyParentDataLoaded(semesterId) + Status.ERROR -> { + Timber.i("Loading grade stats result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch("load") - } - - private fun checkIsNoContent( - items: List, - type: GradeStatisticsItem.DataType - ): Boolean { - return items.isEmpty() || when (type) { - GradeStatisticsItem.DataType.SEMESTER -> { - items.firstOrNull()?.semester?.amounts.orEmpty().sum() == 0 + }.afterLoading { + view?.run { + showRefresh(false) + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded(semesterId) } - GradeStatisticsItem.DataType.PARTIAL -> { - items.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0 - } - GradeStatisticsItem.DataType.POINTS -> { - items.firstOrNull()?.points?.let { points -> points.student == .0 && points.others == .0 } - ?: false - } - } - } - - private fun clearDataInView() { - view?.updateData( - emptyList(), - preferencesRepository.gradeColorTheme, - preferencesRepository.showAllSubjectsOnStatisticsList - ) + }.launch("load") } private fun showErrorViewOnError(message: String, error: Throwable) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsView.kt index 4333bb0a..26b4a119 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsView.kt @@ -1,6 +1,5 @@ package io.github.wulkanowy.ui.modules.grade.statistics -import io.github.wulkanowy.data.enums.GradeColorTheme import io.github.wulkanowy.data.pojos.GradeStatisticsItem import io.github.wulkanowy.ui.base.BaseView @@ -8,17 +7,13 @@ interface GradeStatisticsView : BaseView { val isViewEmpty: Boolean - val currentType: GradeStatisticsItem.DataType + val currentType: ViewType fun initView() - fun updateSubjects(data: List, selectedIndex: Int) + fun updateSubjects(data: ArrayList) - fun updateData( - newItems: List, - newTheme: GradeColorTheme, - showAllSubjectsOnStatisticsList: Boolean - ) + fun updateData(items: List, theme: String, showAllSubjectsOnStatisticsList: Boolean) fun showSubjects(show: Boolean) @@ -30,6 +25,8 @@ interface GradeStatisticsView : BaseView { fun resetView() + fun showContent(show: Boolean) + fun showEmpty(show: Boolean) fun showErrorView(show: Boolean) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/ViewType.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/ViewType.kt index f695eaf9..02e95b0e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/ViewType.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/ViewType.kt @@ -3,6 +3,5 @@ package io.github.wulkanowy.ui.modules.grade.statistics enum class ViewType(val id: Int) { SEMESTER(1), PARTIAL(2), - POINTS(3), - HEADER(4) + POINTS(3) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt index 1cc74ef0..ccebe94f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt @@ -2,34 +2,24 @@ package io.github.wulkanowy.ui.modules.grade.summary import android.annotation.SuppressLint import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup -import androidx.core.view.isGone -import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.databinding.ItemGradeSummaryBinding import io.github.wulkanowy.databinding.ScrollableHeaderGradeSummaryBinding -import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid -import io.github.wulkanowy.utils.calcFinalAverage -import io.github.wulkanowy.utils.ifNullOrBlank +import io.github.wulkanowy.utils.calcAverage import java.util.Locale import javax.inject.Inject -class GradeSummaryAdapter @Inject constructor( - private val preferencesRepository: PreferencesRepository -) : RecyclerView.Adapter() { +class GradeSummaryAdapter @Inject constructor() : RecyclerView.Adapter() { private enum class ViewType(val id: Int) { HEADER(1), ITEM(2) } - var items = emptyList() - - var onCalculatedHelpClickListener: () -> Unit = {} - - var onFinalHelpClickListener: () -> Unit = {} + var items = emptyList() override fun getItemCount() = items.size + if (items.isNotEmpty()) 1 else 0 @@ -42,14 +32,8 @@ class GradeSummaryAdapter @Inject constructor( val inflater = LayoutInflater.from(parent.context) return when (viewType) { - ViewType.HEADER.id -> HeaderViewHolder( - ScrollableHeaderGradeSummaryBinding.inflate(inflater, parent, false) - ) - - ViewType.ITEM.id -> ItemViewHolder( - ItemGradeSummaryBinding.inflate(inflater, parent, false) - ) - + ViewType.HEADER.id -> HeaderViewHolder(ScrollableHeaderGradeSummaryBinding.inflate(inflater, parent, false)) + ViewType.ITEM.id -> ItemViewHolder(ItemGradeSummaryBinding.inflate(inflater, parent, false)) else -> throw IllegalStateException() } } @@ -63,97 +47,28 @@ class GradeSummaryAdapter @Inject constructor( private fun bindHeaderViewHolder(binding: ScrollableHeaderGradeSummaryBinding) { if (items.isEmpty()) return - val gradeSummaries = items - .filter { it.gradeDescriptive == null } - .map { it.gradeSummary } - val isSecondSemester = items.any { item -> - item.gradeSummary.let { it.averageAllYear != null && it.averageAllYear != .0 } - } - - val context = binding.root.context - val finalItemsCount = gradeSummaries.count { isGradeValid(it.finalGrade) } - val calculatedSemesterItemsCount = gradeSummaries.count { value -> value.average != 0.0 } - val calculatedAnnualItemsCount = - gradeSummaries.count { value -> value.averageAllYear != 0.0 } - val allItemsCount = gradeSummaries.count { !it.subject.equals("zachowanie", true) } - val finalAverage = gradeSummaries.calcFinalAverage( - plusModifier = preferencesRepository.gradePlusModifier, - minusModifier = preferencesRepository.gradeMinusModifier, - ) - val calculatedSemesterAverage = gradeSummaries.filter { value -> value.average != 0.0 } - .map { values -> values.average } - .reversed() // fix average precision - .average() - .let { if (it.isNaN()) 0.0 else it } - val calculatedAnnualAverage = gradeSummaries.filter { value -> value.averageAllYear != 0.0 } - .mapNotNull { values -> values.averageAllYear } - .reversed() // fix average precision - .average() - .let { if (it.isNaN()) 0.0 else it } with(binding) { - gradeSummaryScrollableHeaderCalculated.text = formatAverage(calculatedSemesterAverage) - gradeSummaryScrollableHeaderCalculatedAnnual.text = - formatAverage(calculatedAnnualAverage) - gradeSummaryScrollableHeaderFinal.text = formatAverage(finalAverage) - gradeSummaryScrollableHeaderFinalSubjectCount.text = context.getString( - R.string.grade_summary_from_subjects, - finalItemsCount, - allItemsCount + gradeSummaryScrollableHeaderFinal.text = formatAverage(items.calcAverage()) + gradeSummaryScrollableHeaderCalculated.text = formatAverage(items + .filter { value -> value.average != 0.0 } + .map { values -> values.average } + .reversed() // fix average precision + .average() ) - gradeSummaryScrollableHeaderCalculatedSubjectCount.text = context.getString( - R.string.grade_summary_from_subjects, - calculatedSemesterItemsCount, - allItemsCount - ) - gradeSummaryScrollableHeaderCalculatedSubjectCountAnnual.text = context.getString( - R.string.grade_summary_from_subjects, - calculatedAnnualItemsCount, - allItemsCount - ) - gradeSummaryScrollableHeaderCalculatedAnnualContainer.isVisible = isSecondSemester - - gradeSummaryCalculatedAverageHelp.setOnClickListener { onCalculatedHelpClickListener() } - gradeSummaryCalculatedAverageHelpAnnual.setOnClickListener { onCalculatedHelpClickListener() } - gradeSummaryFinalAverageHelp.setOnClickListener { onFinalHelpClickListener() } } } @SuppressLint("SetTextI18n") - private fun bindItemViewHolder(binding: ItemGradeSummaryBinding, item: GradeSummaryItem) { - val (gradeSummary, gradeDescriptive) = item - + private fun bindItemViewHolder(binding: ItemGradeSummaryBinding, item: GradeSummary) { with(binding) { - gradeSummaryItemTitle.text = gradeSummary.subject - gradeSummaryItemPoints.text = gradeSummary.pointsSum + gradeSummaryItemTitle.text = item.subject + gradeSummaryItemPoints.text = item.pointsSum + gradeSummaryItemAverage.text = formatAverage(item.average, "") + gradeSummaryItemPredicted.text = "${item.predictedGrade} ${item.proposedPoints}".trim() + gradeSummaryItemFinal.text = "${item.finalGrade} ${item.finalPoints}".trim() - gradeSummaryItemAverage.text = formatAverage(gradeSummary.average, "") - gradeSummaryItemAverageAllYear.text = gradeSummary.averageAllYear?.let { - formatAverage(it, "") - } - - gradeSummaryItemPredicted.text = - "${gradeSummary.predictedGrade} ${gradeSummary.proposedPoints}".trim() - gradeSummaryItemFinal.text = - "${gradeSummary.finalGrade} ${gradeSummary.finalPoints}".trim() - gradeSummaryItemDescriptive.text = gradeDescriptive?.description.ifNullOrBlank { - root.context.getString(R.string.all_no_data) - } - - gradeSummaryItemAverageContainer.isVisible = gradeSummary.average != .0 - gradeSummaryItemAverageDivider.isVisible = gradeSummaryItemAverageContainer.isVisible - gradeSummaryItemAverageAllYearContainer.isGone = - gradeSummary.averageAllYear == null || gradeSummary.averageAllYear == .0 - gradeSummaryItemAverageAllYearDivider.isGone = - gradeSummaryItemAverageAllYearContainer.isGone - gradeSummaryItemFinalDivider.isVisible = gradeDescriptive == null - gradeSummaryItemPredictedDivider.isVisible = gradeDescriptive == null - gradeSummaryItemPointsDivider.isVisible = gradeDescriptive == null - gradeSummaryItemPredictedContainer.isVisible = gradeDescriptive == null - gradeSummaryItemFinalContainer.isVisible = gradeDescriptive == null - gradeSummaryItemDescriptiveContainer.isVisible = gradeDescriptive != null - gradeSummaryItemPointsContainer.isVisible = gradeSummary.pointsSum.isNotBlank() - gradeSummaryItemPointsDivider.isVisible = gradeSummaryItemPointsContainer.isVisible + gradeSummaryItemPointsContainer.visibility = if (item.pointsSum.isBlank()) View.GONE else View.VISIBLE } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt index 35b2edd5..4d12dcd5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryFragment.kt @@ -6,14 +6,13 @@ import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.databinding.FragmentGradeSummaryBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.grade.GradeFragment import io.github.wulkanowy.ui.modules.grade.GradeView -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint @@ -48,29 +47,18 @@ class GradeSummaryFragment : } override fun initView() { - with(gradeSummaryAdapter) { - onCalculatedHelpClickListener = presenter::onCalculatedAverageHelpClick - onFinalHelpClickListener = presenter::onFinalAverageHelpClick - } - with(binding.gradeSummaryRecycler) { layoutManager = LinearLayoutManager(context) adapter = gradeSummaryAdapter } with(binding) { - gradeSummarySwipe.setOnRefreshListener(presenter::onSwipeRefresh) - gradeSummarySwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - gradeSummarySwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor( - R.attr.colorSwipeRefresh - ) - ) + gradeSummarySwipe.setOnRefreshListener { presenter.onSwipeRefresh() } gradeSummaryErrorRetry.setOnClickListener { presenter.onRetry() } gradeSummaryErrorDetails.setOnClickListener { presenter.onDetailsClick() } } } - override fun updateData(data: List) { + override fun updateData(data: List) { with(gradeSummaryAdapter) { items = data notifyDataSetChanged() @@ -116,22 +104,6 @@ class GradeSummaryFragment : binding.gradeSummarySwipe.isRefreshing = show } - override fun showCalculatedAverageHelpDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.grade_summary_calculated_average_help_dialog_title) - .setMessage(R.string.grade_summary_calculated_average_help_dialog_message) - .setPositiveButton(R.string.all_close) { _, _ -> } - .show() - } - - override fun showFinalAverageHelpDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.grade_summary_final_average_help_dialog_title) - .setMessage(R.string.grade_summary_final_average_help_dialog_message) - .setPositiveButton(R.string.all_close) { _, _ -> } - .show() - } - override fun onParentLoadData(semesterId: Int, forceRefresh: Boolean) { presenter.onParentViewLoadData(semesterId, forceRefresh) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryItem.kt deleted file mode 100644 index cf0f1d92..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryItem.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.wulkanowy.ui.modules.grade.summary - -import io.github.wulkanowy.data.db.entities.GradeDescriptive -import io.github.wulkanowy.data.db.entities.GradeSummary - -data class GradeSummaryItem( - val gradeSummary: GradeSummary, - val gradeDescriptive: GradeDescriptive? -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt index d762df02..7ce98d10 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt @@ -1,30 +1,22 @@ package io.github.wulkanowy.ui.modules.grade.summary -import io.github.wulkanowy.data.enums.GradeSortingMode.ALPHABETIC -import io.github.wulkanowy.data.enums.GradeSortingMode.AVERAGE -import io.github.wulkanowy.data.enums.GradeSortingMode.DATE -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.mapResourceData -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceIntermediate -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.db.entities.GradeSummary +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider -import io.github.wulkanowy.ui.modules.grade.GradeSubject +import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject class GradeSummaryPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, - private val preferencesRepository: PreferencesRepository, private val averageProvider: GradeAverageProvider, private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { @@ -45,40 +37,40 @@ class GradeSummaryPresenter @Inject constructor( } private fun loadData(semesterId: Int, forceRefresh: Boolean) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh) - } - .logResourceStatus("load grade summary") - .mapResourceData { createGradeSummaryItems(it) } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading grade summary started") + Status.SUCCESS -> { + Timber.i("Loading grade summary result: Success") + val items = createGradeSummaryItems(it.data!!) + view?.run { + showEmpty(items.isEmpty()) + showContent(items.isNotEmpty()) + showErrorView(false) + updateData(items) + } + analytics.logEvent( + "load_data", + "type" to "grade_summary", + "items" to it.data.size + ) + } + Status.ERROR -> { + Timber.i("Loading grade summary result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "grade_summary", - "items" to it.size - ) + }.afterLoading { + view?.run { + showRefresh(false) + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded(semesterId) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showRefresh(false) - showProgress(false) - notifyParentDataLoaded(semesterId) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -127,48 +119,19 @@ class GradeSummaryPresenter @Inject constructor( cancelJobs("load") } - fun onCalculatedAverageHelpClick() { - view?.showCalculatedAverageHelpDialog() - } - - fun onFinalAverageHelpClick() { - view?.showFinalAverageHelpDialog() - } - - private fun createGradeSummaryItems(items: List): List { + private fun createGradeSummaryItems(items: List): List { return items .filter { !checkEmpty(it) } - .let { gradeSubjects -> - when (preferencesRepository.gradeSortingMode) { - DATE -> gradeSubjects.sortedByDescending { gradeDetailsWithAverage -> - gradeDetailsWithAverage.grades.maxByOrNull { it.date }?.date - } - - ALPHABETIC -> gradeSubjects.sortedBy { gradeDetailsWithAverage -> - gradeDetailsWithAverage.subject.lowercase() - } - - AVERAGE -> gradeSubjects.sortedByDescending { it.average } - } - } - .map { - val gradeSummary = it.summary.copy(average = it.average) - val descriptive = it.descriptive - GradeSummaryItem( - gradeSummary = gradeSummary, - gradeDescriptive = descriptive, - ) - } - + .sortedBy { it.subject } + .map { it.summary.copy(average = it.average) } } - private fun checkEmpty(gradeSummary: GradeSubject): Boolean { + private fun checkEmpty(gradeSummary: GradeDetailsWithAverage): Boolean { return gradeSummary.run { summary.finalGrade.isBlank() && summary.predictedGrade.isBlank() && average == .0 && points.isBlank() - && descriptive == null } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt index 36bd6142..974d9141 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryView.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.grade.summary +import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.ui.base.BaseView interface GradeSummaryView : BaseView { @@ -12,7 +13,7 @@ interface GradeSummaryView : BaseView { fun initView() - fun updateData(data: List) + fun updateData(data: List) fun resetView() @@ -32,10 +33,6 @@ interface GradeSummaryView : BaseView { fun showEmpty(show: Boolean) - fun showCalculatedAverageHelpDialog() - - fun showFinalAverageHelpDialog() - fun notifyParentDataLoaded(semesterId: Int) fun notifyParentRefresh() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkAdapter.kt index 9dcd3d4a..8ae06aeb 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkAdapter.kt @@ -8,7 +8,6 @@ import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.databinding.HeaderHomeworkBinding import io.github.wulkanowy.databinding.ItemHomeworkBinding -import io.github.wulkanowy.utils.capitalise import io.github.wulkanowy.utils.toFormattedString import io.github.wulkanowy.utils.weekDayName import java.time.LocalDate @@ -44,7 +43,7 @@ class HomeworkAdapter @Inject constructor() : RecyclerView.Adapter(R.layout.fragment_homework), - HomeworkView, MainView.TitledView, MainView.MainChildView { + HomeworkView, MainView.TitledView { @Inject lateinit var presenter: HomeworkPresenter @@ -57,17 +55,13 @@ class HomeworkFragment : BaseFragment(R.layout.fragment with(binding) { homeworkSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - homeworkSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - homeworkSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) homeworkErrorRetry.setOnClickListener { presenter.onRetry() } homeworkErrorDetails.setOnClickListener { presenter.onDetailsClick() } homeworkPreviousButton.setOnClickListener { presenter.onPreviousDay() } homeworkNextButton.setOnClickListener { presenter.onNextDay() } - openAddHomeworkButton.setOnClickListener { presenter.onHomeworkAddButtonClicked() } - - homeworkNavContainer.elevation = requireContext().dpToPx(3f) + homeworkNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } } @@ -89,8 +83,8 @@ class HomeworkFragment : BaseFragment(R.layout.fragment binding.homeworkNavDate.text = date } - override fun showRefresh(show: Boolean) { - binding.homeworkSwipe.isRefreshing = show + override fun hideRefresh() { + binding.homeworkSwipe.isRefreshing = false } override fun showEmpty(show: Boolean) { @@ -125,22 +119,10 @@ class HomeworkFragment : BaseFragment(R.layout.fragment binding.homeworkNextButton.visibility = if (show) VISIBLE else View.INVISIBLE } - override fun showHomeworkDialog(homework: Homework) { + override fun showTimetableDialog(homework: Homework) { (activity as? MainActivity)?.showDialogFragment(HomeworkDetailsDialog.newInstance(homework)) } - override fun showAddHomeworkDialog() { - (activity as? MainActivity)?.showDialogFragment(HomeworkAddDialog()) - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onViewReselected() - } - - override fun resetView() { - binding.homeworkRecycler.smoothScrollToPosition(0) - } - override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt index 6b263e26..f264d58e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkPresenter.kt @@ -1,13 +1,21 @@ package io.github.wulkanowy.ui.modules.homework -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.homework.HomeworkRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday +import io.github.wulkanowy.utils.isHolidays +import io.github.wulkanowy.utils.monday +import io.github.wulkanowy.utils.nextOrSameSchoolDay +import io.github.wulkanowy.utils.sunday +import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach @@ -36,24 +44,24 @@ class HomeworkPresenter @Inject constructor( view.initView() Timber.i("Homework view was initialized") errorHandler.showErrorMessage = ::showErrorViewOnError - reloadView(ofEpochDay(date ?: baseDate.toEpochDay())) - loadData() + loadData(ofEpochDay(date ?: baseDate.toEpochDay())) if (currentDate.isHolidays) setBaseDateOnHolidays() + reloadView() } fun onPreviousDay() { - reloadView(currentDate.minusDays(7)) - loadData() + loadData(currentDate.minusDays(7)) + reloadView() } fun onNextDay() { - reloadView(currentDate.plusDays(7)) - loadData() + loadData(currentDate.plusDays(7)) + reloadView() } fun onSwipeRefresh() { Timber.i("Force refreshing the homework") - loadData(true) + loadData(currentDate, true) } fun onRetry() { @@ -61,7 +69,7 @@ class HomeworkPresenter @Inject constructor( showErrorView(false) showProgress(true) } - loadData(true) + loadData(currentDate, true) } fun onDetailsClick() { @@ -70,70 +78,58 @@ class HomeworkPresenter @Inject constructor( fun onHomeworkItemSelected(homework: Homework) { Timber.i("Select homework item ${homework.id}") - view?.showHomeworkDialog(homework) - } - - fun onHomeworkAddButtonClicked() { - view?.showAddHomeworkDialog() + view?.showTimetableDialog(homework) } private fun setBaseDateOnHolidays() { flow { val student = studentRepository.getCurrentStudent() emit(semesterRepository.getCurrentSemester(student)) - } - .catch { Timber.i("Loading semester result: An exception occurred") } - .onEach { - baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) - currentDate = baseDate - reloadNavigation() - } - .launch("holidays") + }.catch { + Timber.i("Loading semester result: An exception occurred") + }.onEach { + baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) + currentDate = baseDate + reloadNavigation() + }.launch("holidays") } - private fun loadData(forceRefresh: Boolean = false) { - Timber.i("Loading homework data started") + private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { + currentDate = date - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - homeworkRepository.getHomework( - student = student, - semester = semester, - start = currentDate, - end = currentDate, - forceRefresh = forceRefresh - ) - } - .logResourceStatus("loading homework") - .mapResourceData { createHomeworkItem(it) } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + homeworkRepository.getHomework(student, semester, date, date, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading homework data started") + Status.SUCCESS -> { + Timber.i("Loading homework result: Success") + view?.apply { + updateData(createHomeworkItem(it.data!!)) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) + } + analytics.logEvent( + "load_data", + "type" to "homework", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading homework result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "homework", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -149,16 +145,13 @@ class HomeworkPresenter @Inject constructor( private fun createHomeworkItem(items: List): List> { return items.groupBy { it.date }.toSortedMap().map { (date, exams) -> - listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed() - .map { exam -> - HomeworkItem(exam, HomeworkItem.ViewType.ITEM) - } + listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed().map { exam -> + HomeworkItem(exam, HomeworkItem.ViewType.ITEM) + } }.flatten() } - private fun reloadView(date: LocalDate) { - currentDate = date - + private fun reloadView() { Timber.i("Reload homework view with the date ${currentDate.toFormattedString()}") view?.apply { showProgress(true) @@ -175,23 +168,8 @@ class HomeworkPresenter @Inject constructor( view?.apply { showPreButton(!currentDate.minusDays(7).isHolidays) showNextButton(!currentDate.plusDays(7).isHolidays) - updateNavigationWeek( - "${currentDate.monday.toFormattedString("dd.MM")} - " + - currentDate.sunday.toFormattedString("dd.MM") - ) - } - } - - fun onViewReselected() { - Timber.i("Homework view is reselected") - - baseDate = LocalDate.now().nextOrSameSchoolDay - - if (currentDate != baseDate) { - reloadView(baseDate) - loadData() - } else if (view?.isViewEmpty == false) { - view?.resetView() + updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " + + currentDate.sunday.toFormattedString("dd.MM")) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkView.kt index 56ba6c89..2a678cd4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/HomeworkView.kt @@ -15,7 +15,7 @@ interface HomeworkView : BaseView { fun updateNavigationWeek(date: String) - fun showRefresh(show: Boolean) + fun hideRefresh() fun showEmpty(show: Boolean) @@ -33,9 +33,5 @@ interface HomeworkView : BaseView { fun showNextButton(show: Boolean) - fun showHomeworkDialog(homework: Homework) - - fun showAddHomeworkDialog() - - fun resetView() + fun showTimetableDialog(homework: Homework) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddDialog.kt deleted file mode 100644 index 400d9f46..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddDialog.kt +++ /dev/null @@ -1,112 +0,0 @@ -package io.github.wulkanowy.ui.modules.homework.add - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.widget.doOnTextChanged -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.DialogHomeworkAddBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear -import io.github.wulkanowy.utils.openMaterialDatePicker -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate -import javax.inject.Inject - -@AndroidEntryPoint -class HomeworkAddDialog : BaseDialogFragment(), HomeworkAddView { - - @Inject - lateinit var presenter: HomeworkAddPresenter - - //todo: move it to presenter - private var date: LocalDate? = null - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogHomeworkAddBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - } - - override fun initView() { - with(binding) { - homeworkDialogSubjectEdit.doOnTextChanged { _, _, _, _ -> - homeworkDialogSubject.error = null - homeworkDialogSubject.isErrorEnabled = false - } - homeworkDialogDateEdit.doOnTextChanged { _, _, _, _ -> - homeworkDialogDate.error = null - homeworkDialogDate.isErrorEnabled = false - } - homeworkDialogContentEdit.doOnTextChanged { _, _, _, _ -> - homeworkDialogContent.error = null - homeworkDialogContent.isErrorEnabled = false - } - homeworkDialogClose.setOnClickListener { dismiss() } - homeworkDialogDateEdit.setOnClickListener { presenter.showDatePicker(date) } - homeworkDialogAdd.setOnClickListener { - presenter.onAddHomeworkClicked( - subject = homeworkDialogSubjectEdit.text?.toString(), - teacher = homeworkDialogTeacherEdit.text?.toString(), - date = homeworkDialogDateEdit.text?.toString(), - content = homeworkDialogContentEdit.text?.toString() - ) - } - } - } - - override fun showSuccessMessage() { - showMessage(getString(R.string.homework_add_success)) - } - - override fun setErrorSubjectRequired() { - with(binding.homeworkDialogSubject) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorDateRequired() { - with(binding.homeworkDialogDate) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorContentRequired() { - with(binding.homeworkDialogContent) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun closeDialog() { - dismiss() - } - - override fun showDatePickerDialog(selectedDate: LocalDate) { - openMaterialDatePicker( - selected = selectedDate, - rangeStart = LocalDate.now(), - rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear, - onDateSelected = { - date = it - if (isAdded) { - binding.homeworkDialogDate.editText?.setText(date!!.toFormattedString()) - } - } - ) - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddPresenter.kt deleted file mode 100644 index a21f6aef..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddPresenter.kt +++ /dev/null @@ -1,87 +0,0 @@ -package io.github.wulkanowy.ui.modules.homework.add - -import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.toLocalDate -import timber.log.Timber -import java.time.LocalDate -import javax.inject.Inject - -class HomeworkAddPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val homeworkRepository: HomeworkRepository, - private val semesterRepository: SemesterRepository -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: HomeworkAddView) { - super.onAttachView(view) - view.initView() - Timber.i("Homework details view was initialized") - } - - fun showDatePicker(date: LocalDate?) { - view?.showDatePickerDialog(date ?: LocalDate.now()) - } - - fun onAddHomeworkClicked(subject: String?, teacher: String?, date: String?, content: String?) { - var isError = false - - if (subject.isNullOrBlank()) { - view?.setErrorSubjectRequired() - isError = true - } - - if (date.isNullOrBlank()) { - view?.setErrorDateRequired() - isError = true - } - - if (content.isNullOrBlank()) { - view?.setErrorContentRequired() - isError = true - } - - if (!isError) { - saveHomework(subject!!, teacher.orEmpty(), date!!.toLocalDate(), content!!) - } - } - - private fun saveHomework(subject: String, teacher: String, date: LocalDate, content: String) { - resourceFlow { - val student = studentRepository.getCurrentStudent() - val semester = semesterRepository.getCurrentSemester(student) - val entryDate = LocalDate.now() - homeworkRepository.saveHomework( - Homework( - semesterId = semester.semesterId, - studentId = student.studentId, - date = date, - entryDate = entryDate, - subject = subject, - content = content, - teacher = teacher, - teacherSymbol = "", - attachments = emptyList(), - ).apply { isAddedByUser = true } - ) - } - .logResourceStatus("homework insert") - .onResourceSuccess { - view?.run { - showSuccessMessage() - closeDialog() - } - } - .onResourceError(errorHandler::dispatch) - .launch("add_homework") - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddView.kt deleted file mode 100644 index 91414ae2..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/add/HomeworkAddView.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.wulkanowy.ui.modules.homework.add - -import io.github.wulkanowy.ui.base.BaseView -import java.time.LocalDate - -interface HomeworkAddView : BaseView { - - fun initView() - - fun showSuccessMessage() - - fun setErrorSubjectRequired() - - fun setErrorDateRequired() - - fun setErrorContentRequired() - - fun closeDialog() - - fun showDatePickerDialog(selectedDate: LocalDate) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsAdapter.kt index 1ad2a0e3..cd9a7e85 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsAdapter.kt @@ -5,12 +5,10 @@ import android.view.View.GONE import android.view.View.VISIBLE import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.databinding.ItemHomeworkDialogAttachmentBinding import io.github.wulkanowy.databinding.ItemHomeworkDialogAttachmentsHeaderBinding import io.github.wulkanowy.databinding.ItemHomeworkDialogDetailsBinding -import io.github.wulkanowy.utils.ifNullOrBlank import io.github.wulkanowy.utils.toFormattedString import javax.inject.Inject @@ -31,9 +29,13 @@ class HomeworkDetailsAdapter @Inject constructor() : attachments = value?.attachments.orEmpty() } + var isHomeworkFullscreen = false + var onAttachmentClickListener: (url: String) -> Unit = {} - var onDeleteClickListener: (homework: Homework) -> Unit = {} + var onFullScreenClickListener = {} + + var onFullScreenExitClickListener = {} override fun getItemCount() = 1 + if (attachments.isNotEmpty()) attachments.size + 1 else 0 @@ -47,15 +49,9 @@ class HomeworkDetailsAdapter @Inject constructor() : val inflater = LayoutInflater.from(parent.context) return when (viewType) { - ViewType.ATTACHMENTS_HEADER.id -> AttachmentsHeaderViewHolder( - ItemHomeworkDialogAttachmentsHeaderBinding.inflate(inflater, parent, false) - ) - ViewType.ATTACHMENT.id -> AttachmentViewHolder( - ItemHomeworkDialogAttachmentBinding.inflate(inflater, parent, false) - ) - else -> DetailsViewHolder( - ItemHomeworkDialogDetailsBinding.inflate(inflater, parent, false) - ) + ViewType.ATTACHMENTS_HEADER.id -> AttachmentsHeaderViewHolder(ItemHomeworkDialogAttachmentsHeaderBinding.inflate(inflater, parent, false)) + ViewType.ATTACHMENT.id -> AttachmentViewHolder(ItemHomeworkDialogAttachmentBinding.inflate(inflater, parent, false)) + else -> DetailsViewHolder(ItemHomeworkDialogDetailsBinding.inflate(inflater, parent, false)) } } @@ -67,17 +63,23 @@ class HomeworkDetailsAdapter @Inject constructor() : } private fun bindDetailsViewHolder(holder: DetailsViewHolder) { - val noDataString = holder.binding.root.context.getString(R.string.all_no_data) - with(holder.binding) { homeworkDialogDate.text = homework?.date?.toFormattedString() homeworkDialogEntryDate.text = homework?.entryDate?.toFormattedString() - homeworkDialogSubject.text = homework?.subject.ifNullOrBlank { noDataString } - homeworkDialogTeacher.text = homework?.teacher.ifNullOrBlank { noDataString } - homeworkDialogContent.text = homework?.content.ifNullOrBlank { noDataString } - homeworkDialogDelete.visibility = if (homework?.isAddedByUser == true) VISIBLE else GONE - homeworkDialogDelete.setOnClickListener { - onDeleteClickListener(homework!!) + homeworkDialogSubject.text = homework?.subject + homeworkDialogTeacher.text = homework?.teacher + homeworkDialogContent.text = homework?.content + homeworkDialogFullScreen.visibility = if (isHomeworkFullscreen) GONE else VISIBLE + homeworkDialogFullScreenExit.visibility = if (isHomeworkFullscreen) VISIBLE else GONE + homeworkDialogFullScreen.setOnClickListener { + homeworkDialogFullScreen.visibility = GONE + homeworkDialogFullScreenExit.visibility = VISIBLE + onFullScreenClickListener() + } + homeworkDialogFullScreenExit.setOnClickListener { + homeworkDialogFullScreen.visibility = VISIBLE + homeworkDialogFullScreenExit.visibility = GONE + onFullScreenExitClickListener() } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt index 1f9bc881..aecaa394 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt @@ -1,19 +1,19 @@ package io.github.wulkanowy.ui.modules.homework.details import android.annotation.SuppressLint -import android.app.Dialog import android.os.Bundle +import android.view.LayoutInflater import android.view.View -import androidx.core.os.bundleOf +import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT +import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.databinding.DialogHomeworkBinding import io.github.wulkanowy.ui.base.BaseDialogFragment import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.serializable import javax.inject.Inject @AndroidEntryPoint @@ -25,62 +25,69 @@ class HomeworkDetailsDialog : BaseDialogFragment(), Homew @Inject lateinit var detailsAdapter: HomeworkDetailsAdapter - override val homeworkDeleteSuccess: String - get() = getString(R.string.homework_delete_success) - private lateinit var homework: Homework companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(homework: Homework) = HomeworkDetailsDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to homework) + fun newInstance(homework: Homework): HomeworkDetailsDialog { + return HomeworkDetailsDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, homework) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - homework = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + homework = getSerializable(ARGUMENT_KEY) as Homework + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogHomeworkBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogHomeworkBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) presenter.onAttachView(this) } @SuppressLint("SetTextI18n") override fun initView() { with(binding) { - homeworkDialogRead.text = - view?.context?.getString(if (homework.isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done) + homeworkDialogRead.text = view?.context?.getString(if (homework.isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done) homeworkDialogRead.setOnClickListener { presenter.toggleDone(homework) } homeworkDialogClose.setOnClickListener { dismiss() } } + if (presenter.isHomeworkFullscreen) { + dialog?.window?.setLayout(MATCH_PARENT, MATCH_PARENT) + } else { + dialog?.window?.setLayout(WRAP_CONTENT, WRAP_CONTENT) + } + with(binding.homeworkDialogRecycler) { layoutManager = LinearLayoutManager(context) adapter = detailsAdapter.apply { onAttachmentClickListener = { context.openInternetBrowser(it, ::showMessage) } - onDeleteClickListener = { homework -> presenter.deleteHomework(homework) } + onFullScreenClickListener = { + dialog?.window?.setLayout(MATCH_PARENT, MATCH_PARENT) + presenter.isHomeworkFullscreen = true + } + onFullScreenExitClickListener = { + dialog?.window?.setLayout(WRAP_CONTENT, WRAP_CONTENT) + presenter.isHomeworkFullscreen = false + } + isHomeworkFullscreen = presenter.isHomeworkFullscreen homework = this@HomeworkDetailsDialog.homework } } } - override fun closeDialog() { - dismiss() - } - override fun updateMarkAsDoneLabel(isDone: Boolean) { - binding.homeworkDialogRead.text = - view?.context?.getString(if (isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done) + binding.homeworkDialogRead.text = view?.context?.getString(if (isDone) R.string.homework_mark_as_undone else R.string.homework_mark_as_done) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsPresenter.kt index 84933f06..1d4dac2c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsPresenter.kt @@ -1,15 +1,15 @@ package io.github.wulkanowy.ui.modules.homework.details +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Homework -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.HomeworkRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.homework.HomeworkRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -18,35 +18,35 @@ class HomeworkDetailsPresenter @Inject constructor( studentRepository: StudentRepository, private val homeworkRepository: HomeworkRepository, private val analytics: AnalyticsHelper, + private val preferencesRepository: PreferencesRepository ) : BasePresenter(errorHandler, studentRepository) { + var isHomeworkFullscreen + get() = preferencesRepository.isHomeworkFullscreen + set(value) { + preferencesRepository.isHomeworkFullscreen = value + } + override fun onAttachView(view: HomeworkDetailsView) { super.onAttachView(view) view.initView() Timber.i("Homework details view was initialized") } - fun deleteHomework(homework: Homework) { - resourceFlow { homeworkRepository.deleteHomework(homework) } - .logResourceStatus("homework delete") - .onResourceSuccess { - view?.run { - showMessage(homeworkDeleteSuccess) - closeDialog() + fun toggleDone(homework: Homework) { + flowWithResource { homeworkRepository.toggleDone(homework) }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Homework details update start") + Status.SUCCESS -> { + Timber.i("Homework details update: Success") + view?.updateMarkAsDoneLabel(homework.isDone) + analytics.logEvent("homework_mark_as_done") + } + Status.ERROR -> { + Timber.i("Homework details update result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch("delete") - } - - fun toggleDone(homework: Homework) { - resourceFlow { homeworkRepository.toggleDone(homework) } - .logResourceStatus("homework details update") - .onResourceSuccess { - view?.updateMarkAsDoneLabel(homework.isDone) - analytics.logEvent("homework_mark_as_done") - } - .onResourceError(errorHandler::dispatch) - .launch("toggle") + }.launch("toggle") } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsView.kt index 4a47de43..697f2233 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsView.kt @@ -4,11 +4,7 @@ import io.github.wulkanowy.ui.base.BaseView interface HomeworkDetailsView : BaseView { - val homeworkDeleteSuccess: String - fun initView() - fun closeDialog() - fun updateMarkAsDoneLabel(isDone: Boolean) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt index e528c514..aff1c84c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt @@ -2,28 +2,20 @@ package io.github.wulkanowy.ui.modules.login import android.content.Context import android.content.Intent -import android.content.pm.PackageManager -import android.os.Build.VERSION_CODES.TIRAMISU import android.os.Bundle import android.view.MenuItem -import androidx.core.content.ContextCompat -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE -import androidx.fragment.app.commit import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.pojos.RegisterUser +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.ActivityLoginBinding import io.github.wulkanowy.ui.base.BaseActivity +import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.notifications.NotificationsFragment -import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.InAppUpdateHelper +import io.github.wulkanowy.utils.UpdateHelper +import io.github.wulkanowy.utils.setOnSelectPageListener import javax.inject.Inject @AndroidEntryPoint @@ -32,29 +24,37 @@ class LoginActivity : BaseActivity(), Logi @Inject override lateinit var presenter: LoginPresenter - @Inject - lateinit var inAppUpdateHelper: InAppUpdateHelper + private val loginAdapter = BaseFragmentPagerAdapter(supportFragmentManager) @Inject - lateinit var appInfo: AppInfo + lateinit var updateHelper: UpdateHelper companion object { + fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java) } + override val currentViewIndex get() = binding.loginViewpager.currentItem + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityLoginBinding.inflate(layoutInflater).apply { binding = this }.root) setSupportActionBar(binding.loginToolbar) messageContainer = binding.loginContainer - inAppUpdateHelper.messageContainer = binding.loginContainer + updateHelper.messageContainer = binding.loginContainer presenter.onAttachView(this) - inAppUpdateHelper.checkAndInstallUpdates() + updateHelper.checkAndInstallUpdates(this) + } - if (savedInstanceState == null) { - openFragment(LoginFormFragment.newInstance(), clearBackStack = true) - } + override fun onResume() { + super.onResume() + updateHelper.onResume(this) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + updateHelper.onActivityResult(requestCode, resultCode) } override fun initView() { @@ -62,62 +62,63 @@ class LoginActivity : BaseActivity(), Logi setDisplayHomeAsUpEnabled(true) setDisplayShowTitleEnabled(false) } - } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == android.R.id.home) onBackPressedDispatcher.onBackPressed() - return true - } + with(loginAdapter) { + containerId = binding.loginViewpager.id + addFragments(listOf( + LoginFormFragment.newInstance(), + LoginSymbolFragment.newInstance(), + LoginStudentSelectFragment.newInstance(), + LoginAdvancedFragment.newInstance(), + LoginRecoverFragment.newInstance() + )) + } - fun showActionBar(show: Boolean) { - supportActionBar?.run { if (show) show() else hide() } - } - - fun navigateToSymbolFragment(loginData: LoginData) { - openFragment(LoginSymbolFragment.newInstance(loginData)) - } - - fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) { - openFragment(LoginStudentSelectFragment.newInstance(loginData, registerUser)) - } - - fun navigateToNotifications() { - val isNotificationsPermissionRequired = appInfo.systemVersion >= TIRAMISU - val isPermissionGranted = ContextCompat.checkSelfPermission( - this, "android.permission.POST_NOTIFICATIONS" - ) == PackageManager.PERMISSION_GRANTED - - if (isNotificationsPermissionRequired && !isPermissionGranted) { - openFragment(NotificationsFragment.newInstance(), clearBackStack = true) - } else navigateToFinish() - } - - fun navigateToFinish() { - startActivity(MainActivity.getStartIntent(this)) - finish() - } - - fun onAdvancedLoginClick() { - openFragment(LoginAdvancedFragment.newInstance()) - } - - fun onRecoverClick() { - openFragment(LoginRecoverFragment.newInstance()) - } - - private fun openFragment(fragment: Fragment, clearBackStack: Boolean = false) { - supportFragmentManager.popBackStack(fragment::class.java.name, POP_BACK_STACK_INCLUSIVE) - - supportFragmentManager.commit { - replace(R.id.loginContainer, fragment) - setReorderingAllowed(true) - if (!clearBackStack) addToBackStack(fragment::class.java.name) + with(binding.loginViewpager) { + offscreenPageLimit = 2 + adapter = loginAdapter + setOnSelectPageListener(presenter::onViewSelected) } } - override fun onResume() { - super.onResume() - inAppUpdateHelper.onResume() - presenter.updateSdkMappings() + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) onBackPressed() + return true + } + + override fun switchView(index: Int) { + binding.loginViewpager.setCurrentItem(index, false) + } + + override fun showActionBar(show: Boolean) { + supportActionBar?.run { if (show) show() else hide() } + } + + override fun onBackPressed() { + presenter.onBackPressed { super.onBackPressed() } + } + + override fun notifyInitSymbolFragment(loginData: Triple) { + (loginAdapter.getFragmentInstance(1) as? LoginSymbolFragment)?.onParentInitSymbolFragment(loginData) + } + + override fun notifyInitStudentSelectFragment(studentsWithSemesters: List) { + (loginAdapter.getFragmentInstance(2) as? LoginStudentSelectFragment)?.onParentInitStudentSelectFragment(studentsWithSemesters) + } + + fun onFormFragmentAccountLogged(studentsWithSemesters: List, loginData: Triple) { + presenter.onFormViewAccountLogged(studentsWithSemesters, loginData) + } + + fun onSymbolFragmentAccountLogged(studentsWithSemesters: List) { + presenter.onSymbolViewAccountLogged(studentsWithSemesters) + } + + fun onAdvancedLoginClick() { + presenter.onAdvancedLoginClick() + } + + fun onRecoverClick() { + presenter.onRecoverClick() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt deleted file mode 100644 index b066cceb..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.ui.modules.login - -import java.io.Serializable - -data class LoginData( - val login: String, - val password: String, - val baseUrl: String, - val domainSuffix: String, - val defaultSymbol: String, - val userEnteredSymbol: String? = null, -) : Serializable diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt index 4f709438..f30825cf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginErrorHandler.kt @@ -1,24 +1,23 @@ package io.github.wulkanowy.ui.modules.login -import android.content.Context +import android.content.res.Resources import android.database.sqlite.SQLiteConstraintException -import dagger.hilt.android.qualifiers.ApplicationContext +import com.chuckerteam.chucker.api.ChuckerCollector import io.github.wulkanowy.R -import io.github.wulkanowy.sdk.hebe.exception.InvalidPinException -import io.github.wulkanowy.sdk.hebe.exception.InvalidTokenException -import io.github.wulkanowy.sdk.hebe.exception.TokenDeadException -import io.github.wulkanowy.sdk.hebe.exception.UnknownTokenException +import io.github.wulkanowy.sdk.mobile.exception.InvalidPinException +import io.github.wulkanowy.sdk.mobile.exception.InvalidSymbolException +import io.github.wulkanowy.sdk.mobile.exception.InvalidTokenException +import io.github.wulkanowy.sdk.mobile.exception.TokenDeadException import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException import io.github.wulkanowy.ui.base.ErrorHandler import javax.inject.Inject -import io.github.wulkanowy.sdk.hebe.exception.InvalidSymbolException as InvalidHebeSymbolException -import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException as InvalidScrapperSymbolException class LoginErrorHandler @Inject constructor( - @ApplicationContext context: Context, -) : ErrorHandler(context) { + resources: Resources, + chuckerCollector: ChuckerCollector +) : ErrorHandler(resources, chuckerCollector) { - var onBadCredentials: (String?) -> Unit = {} + var onBadCredentials: () -> Unit = {} var onInvalidToken: (String) -> Unit = {} @@ -29,16 +28,13 @@ class LoginErrorHandler @Inject constructor( var onStudentDuplicate: (String) -> Unit = {} override fun proceed(error: Throwable) { - val resources = context.resources when (error) { - is BadCredentialsException -> onBadCredentials(error.message) + is BadCredentialsException -> onBadCredentials() is SQLiteConstraintException -> onStudentDuplicate(resources.getString(R.string.login_duplicate_student)) is TokenDeadException -> onInvalidToken(resources.getString(R.string.login_expired_token)) - is UnknownTokenException, is InvalidTokenException -> onInvalidToken(resources.getString(R.string.login_invalid_token)) is InvalidPinException -> onInvalidPin(resources.getString(R.string.login_invalid_pin)) - is InvalidScrapperSymbolException, - is InvalidHebeSymbolException -> onInvalidSymbol(resources.getString(R.string.login_invalid_symbol)) + is InvalidSymbolException -> onInvalidSymbol(resources.getString(R.string.login_invalid_symbol)) else -> super.proceed(error) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt index aff0515f..7e731772 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginPresenter.kt @@ -1,29 +1,72 @@ package io.github.wulkanowy.ui.modules.login -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.WulkanowyRepository +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler -import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject class LoginPresenter @Inject constructor( - private val wulkanowyRepository: WulkanowyRepository, errorHandler: ErrorHandler, studentRepository: StudentRepository ) : BasePresenter(errorHandler, studentRepository) { override fun onAttachView(view: LoginView) { super.onAttachView(view) - view.initView() + with(view) { + initView() + showActionBar(false) + } Timber.i("Login view was initialized") } - fun updateSdkMappings() { - presenterScope.launch { - runCatching { wulkanowyRepository.fetchMapping() } - .onFailure { Timber.e(it) } + fun onFormViewAccountLogged(studentsWithSemesters: List, loginData: Triple) { + view?.apply { + if (studentsWithSemesters.isEmpty()) { + Timber.i("Switch to symbol form") + notifyInitSymbolFragment(loginData) + switchView(1) + } else { + Timber.i("Switch to student select") + notifyInitStudentSelectFragment(studentsWithSemesters) + switchView(2) + } + } + } + + fun onSymbolViewAccountLogged(studentsWithSemesters: List) { + view?.apply { + Timber.i("Switch to student select") + notifyInitStudentSelectFragment(studentsWithSemesters) + switchView(2) + } + } + + fun onAdvancedLoginClick() { + view?.switchView(3) + } + + fun onRecoverClick() { + view?.switchView(4) + } + + fun onViewSelected(index: Int) { + view?.apply { + when (index) { + 0 -> showActionBar(false) + 1, 2, 3, 4 -> showActionBar(true) + } + } + } + + fun onBackPressed(default: () -> Unit) { + Timber.i("Back pressed in login view") + view?.apply { + when (currentViewIndex) { + 1, 2, 3, 4 -> switchView(0) + else -> default() + } } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginView.kt index a0949e6d..2a5cf316 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginView.kt @@ -1,8 +1,19 @@ package io.github.wulkanowy.ui.modules.login +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView interface LoginView : BaseView { + val currentViewIndex: Int + fun initView() + + fun switchView(index: Int) + + fun showActionBar(show: Boolean) + + fun notifyInitSymbolFragment(loginData: Triple) + + fun notifyInitStudentSelectFragment(studentsWithSemesters: List) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt index 13d2c14a..9231914c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt @@ -5,16 +5,14 @@ import android.view.View import android.view.View.GONE import android.view.View.VISIBLE import android.widget.ArrayAdapter -import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.pojos.RegisterUser +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.FragmentLoginAdvancedBinding import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.form.LoginSymbolAdapter import io.github.wulkanowy.utils.hideSoftInput import io.github.wulkanowy.utils.setOnEditorDoneSignIn @@ -35,9 +33,9 @@ class LoginAdvancedFragment : override val formLoginType: String get() = when (binding.loginTypeSwitch.checkedRadioButtonId) { - R.id.loginTypeApi -> Sdk.Mode.HEBE.name - R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER.name - else -> Sdk.Mode.HYBRID.name + R.id.loginTypeApi -> "API" + R.id.loginTypeScrapper -> "SCRAPPER" + else -> "HYBRID" } override val formUsernameValue: String @@ -53,15 +51,10 @@ class LoginAdvancedFragment : private lateinit var hostSymbols: Array override val formHostValue: String - get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())) - .orEmpty() - - override val formDomainSuffix: String - get() = binding.loginFormDomainSuffix.text.toString().trim() + get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty() override val formHostSymbol: String - get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())) - .orEmpty() + get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty() override val formPinValue: String get() = binding.loginFormPin.text.toString().trim() @@ -85,8 +78,6 @@ class LoginAdvancedFragment : } override fun initView() { - (requireActivity() as LoginActivity).showActionBar(true) - hostKeys = resources.getStringArray(R.array.hosts_keys) hostValues = resources.getStringArray(R.array.hosts_values) hostSymbols = resources.getStringArray(R.array.hosts_symbols) @@ -101,62 +92,39 @@ class LoginAdvancedFragment : loginFormSignIn.setOnClickListener { presenter.onSignInClick() } loginTypeSwitch.setOnCheckedChangeListener { _, checkedId -> - presenter.onLoginModeSelected( - when (checkedId) { - R.id.loginTypeApi -> Sdk.Mode.HEBE - R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER - else -> Sdk.Mode.HYBRID - } - ) + presenter.onLoginModeSelected(when (checkedId) { + R.id.loginTypeApi -> Sdk.Mode.API + R.id.loginTypeScrapper -> Sdk.Mode.SCRAPPER + else -> Sdk.Mode.HYBRID + }) } loginFormPin.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() } loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() } - loginFormSymbol.setAdapter( - ArrayAdapter( - requireContext(), - android.R.layout.simple_list_item_1, - resources.getStringArray(R.array.symbols_values) - ) - ) + loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values))) } with(binding.loginFormHost) { setText(hostKeys.getOrNull(0).orEmpty()) - setAdapter( - LoginSymbolAdapter( - context, - R.layout.support_simple_spinner_dropdown_item, - hostKeys - ) - ) + setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)) setOnClickListener { if (binding.loginFormContainer.visibility == GONE) dismissDropDown() } } } override fun showMobileApiWarningMessage() { - binding.loginFormAdvancedWarningInfo.text = - getString(R.string.login_advanced_warning_mobile_api) + binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_mobile_api) } override fun showScraperWarningMessage() { - binding.loginFormAdvancedWarningInfo.text = - getString(R.string.login_advanced_warning_scraper) + binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_scraper) } override fun showHybridWarningMessage() { - binding.loginFormAdvancedWarningInfo.text = - getString(R.string.login_advanced_warning_hybrid) + binding.loginFormAdvancedWarningInfo.text = getString(R.string.login_advanced_warning_hybrid) } - override fun setDefaultCredentials( - username: String, - pass: String, - symbol: String, - token: String, - pin: String - ) { + override fun setDefaultCredentials(username: String, pass: String, symbol: String, token: String, pin: String) { with(binding) { loginFormUsername.setText(username) loginFormPass.setText(pass) @@ -177,7 +145,7 @@ class LoginAdvancedFragment : override fun setErrorUsernameRequired() { with(binding.loginFormUsernameLayout) { requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -198,7 +166,7 @@ class LoginAdvancedFragment : override fun setErrorPassRequired(focus: Boolean) { with(binding.loginFormPassLayout) { if (focus) requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -209,17 +177,17 @@ class LoginAdvancedFragment : } } - override fun setErrorPassIncorrect(message: String?) { + override fun setErrorPassIncorrect() { with(binding.loginFormPassLayout) { requestFocus() - error = message ?: getString(R.string.login_incorrect_password_default) + error = getString(R.string.login_incorrect_password) } } override fun setErrorPinRequired() { with(binding.loginFormPinLayout) { requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -233,7 +201,7 @@ class LoginAdvancedFragment : override fun setErrorSymbolRequired() { with(binding.loginFormSymbolLayout) { requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -247,7 +215,7 @@ class LoginAdvancedFragment : override fun setErrorTokenRequired() { with(binding.loginFormTokenLayout) { requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -283,7 +251,6 @@ class LoginAdvancedFragment : loginFormUsernameLayout.visibility = VISIBLE loginFormPassLayout.visibility = VISIBLE loginFormHostLayout.visibility = VISIBLE - loginFormDomainSuffixLayout.isVisible = true loginFormPinLayout.visibility = GONE loginFormSymbolLayout.visibility = VISIBLE loginFormTokenLayout.visibility = GONE @@ -295,7 +262,6 @@ class LoginAdvancedFragment : loginFormUsernameLayout.visibility = VISIBLE loginFormPassLayout.visibility = VISIBLE loginFormHostLayout.visibility = VISIBLE - loginFormDomainSuffixLayout.isVisible = true loginFormPinLayout.visibility = GONE loginFormSymbolLayout.visibility = VISIBLE loginFormTokenLayout.visibility = GONE @@ -307,7 +273,6 @@ class LoginAdvancedFragment : loginFormUsernameLayout.visibility = GONE loginFormPassLayout.visibility = GONE loginFormHostLayout.visibility = GONE - loginFormDomainSuffixLayout.isVisible = false loginFormPinLayout.visibility = VISIBLE loginFormSymbolLayout.visibility = VISIBLE loginFormTokenLayout.visibility = VISIBLE @@ -330,12 +295,12 @@ class LoginAdvancedFragment : binding.loginFormContainer.visibility = if (show) VISIBLE else GONE } - override fun navigateToSymbol(loginData: LoginData) { - (activity as? LoginActivity)?.navigateToSymbolFragment(loginData) - } - - override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) { - (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser) + override fun notifyParentAccountLogged(studentsWithSemesters: List) { + (activity as? LoginActivity)?.onFormFragmentAccountLogged(studentsWithSemesters, Triple( + binding.loginFormUsername.text.toString(), + binding.loginFormPass.text.toString(), + resources.getStringArray(R.array.hosts_values)[1] + )) } override fun onResume() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt index 009f26e1..9dfc3011 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt @@ -1,17 +1,14 @@ package io.github.wulkanowy.ui.modules.login.advanced -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.sdk.Sdk -import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.ifNullOrBlank import kotlinx.coroutines.flow.onEach import timber.log.Timber @@ -37,9 +34,9 @@ class LoginAdvancedPresenter @Inject constructor( } } - private fun onBadCredentials(message: String?) { + private fun onBadCredentials() { view?.run { - setErrorPassIncorrect(message) + setErrorPassIncorrect() showSoftKeyboard() Timber.i("Entered wrong username or password") } @@ -71,7 +68,7 @@ class LoginAdvancedPresenter @Inject constructor( fun updateUsernameLabel() { view?.apply { - setUsernameLabel(if ("vulcan" in formHostValue || "wulkanowy" in formHostValue) emailLabel else nicknameLabel) + setUsernameLabel(if ("vulcan" in formHostValue || "fakelog" in formHostValue) emailLabel else nicknameLabel) } } @@ -79,10 +76,8 @@ class LoginAdvancedPresenter @Inject constructor( view?.apply { clearPassError() clearUsernameError() - if (formHostValue.contains("wulkanowy")) { - setDefaultCredentials( - "jan@fakelog.cf", "jan123", "powiatwulkanowy", "FK100000", "999999" - ) + if (formHostValue.contains("fakelog")) { + setDefaultCredentials("jan@fakelog.cf", "jan123", "powiatwulkanowy", "FK100000", "999999") } setSymbol(formHostSymbol) updateUsernameLabel() @@ -92,16 +87,14 @@ class LoginAdvancedPresenter @Inject constructor( fun onLoginModeSelected(type: Sdk.Mode) { view?.run { when (type) { - Sdk.Mode.HEBE -> { + Sdk.Mode.API -> { showOnlyMobileApiModeInputs() showMobileApiWarningMessage() } - Sdk.Mode.SCRAPPER -> { showOnlyScrapperModeInputs() showScraperWarningMessage() } - Sdk.Mode.HYBRID -> { showOnlyHybridModeInputs() showHybridWarningMessage() @@ -133,75 +126,54 @@ class LoginAdvancedPresenter @Inject constructor( fun onSignInClick() { if (!validateCredentials()) return - resourceFlow { getStudentsAppropriatesToLoginType() } - .logResourceStatus("login") - .onEach { - when (it) { - is Resource.Loading -> view?.run { - hideSoftKeyboard() - showProgress(true) - showContent(false) - } - - is Resource.Success -> { - analytics.logEvent( - "registration_form", - "success" to true, - "scrapperBaseUrl" to view?.formHostValue.orEmpty(), - "error" to "No error" - ) - val loginData = LoginData( - login = view?.formUsernameValue.orEmpty().trim(), - password = view?.formPassValue.orEmpty().trim(), - baseUrl = view?.formHostValue.orEmpty().trim(), - domainSuffix = view?.formDomainSuffix.orEmpty().trim(), - defaultSymbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(), - ) - when (it.data.symbols.size) { - 0 -> view?.navigateToSymbol(loginData) - else -> view?.navigateToStudentSelect( - loginData = loginData, - registerUser = it.data, - ) - } - } - - is Resource.Error -> { - analytics.logEvent( - "registration_form", - "success" to false, "students" to -1, - "error" to it.error.message.ifNullOrBlank { "No message" } - ) - loginErrorHandler.dispatch(it.error) - } + flowWithResource { getStudentsAppropriatesToLoginType() }.onEach { + when (it.status) { + Status.LOADING -> view?.run { + Timber.i("Login started") + hideSoftKeyboard() + showProgress(true) + showContent(false) } - }.onResourceNotLoading { - view?.apply { - showProgress(false) - showContent(true) + Status.SUCCESS -> { + Timber.i("Login result: Success") + analytics.logEvent("registration_form", + "success" to true, + "students" to it.data!!.size, + "error" to "No error" + ) + view?.notifyParentAccountLogged(it.data) } - }.launch("login") + Status.ERROR -> { + Timber.i("Login result: An exception occurred") + analytics.logEvent( + "registration_form", + "success" to false, "students" to -1, + "error" to it.error!!.message.ifNullOrBlank { "No message" } + ) + loginErrorHandler.dispatch(it.error) + } + } + }.afterLoading { + view?.apply { + showProgress(false) + showContent(true) + } + }.launch("login") } - private suspend fun getStudentsAppropriatesToLoginType(): RegisterUser { + private suspend fun getStudentsAppropriatesToLoginType(): List { val email = view?.formUsernameValue.orEmpty() val password = view?.formPassValue.orEmpty() val endpoint = view?.formHostValue.orEmpty() - val domainSuffix = view?.formDomainSuffix.orEmpty() val pin = view?.formPinValue.orEmpty() val symbol = view?.formSymbolValue.orEmpty() val token = view?.formTokenValue.orEmpty() return when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) { - Sdk.Mode.HEBE -> studentRepository.getStudentsApi(pin, symbol, token) - Sdk.Mode.SCRAPPER -> studentRepository.getUserSubjectsFromScrapper( - email, password, endpoint, domainSuffix, symbol - ) - - Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid( - email, password, endpoint, symbol - ) + Sdk.Mode.API -> studentRepository.getStudentsApi(pin, symbol, token) + Sdk.Mode.SCRAPPER -> studentRepository.getStudentsScrapper(email, password, endpoint, symbol) + Sdk.Mode.HYBRID -> studentRepository.getStudentsHybrid(email, password, endpoint, symbol) } } @@ -217,8 +189,8 @@ class LoginAdvancedPresenter @Inject constructor( var isCorrect = true - when (Sdk.Mode.valueOf(view?.formLoginType.orEmpty())) { - Sdk.Mode.HEBE -> { + when (Sdk.Mode.valueOf(view?.formLoginType ?: "")) { + Sdk.Mode.API -> { if (pin.isEmpty()) { view?.setErrorPinRequired() isCorrect = false @@ -234,17 +206,17 @@ class LoginAdvancedPresenter @Inject constructor( isCorrect = false } } - Sdk.Mode.HYBRID, Sdk.Mode.SCRAPPER -> { if (login.isEmpty()) { view?.setErrorUsernameRequired() isCorrect = false } else { - if ("@" in login && "login" in host) { + if ("@" in login && "standard" !in host) { view?.setErrorLoginRequired() isCorrect = false } - if ("@" !in login && "email" in host) { + + if ("@" !in login && "standard" in host) { view?.setErrorEmailRequired() isCorrect = false } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt index afd33e3b..029a6b4d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt @@ -1,8 +1,7 @@ package io.github.wulkanowy.ui.modules.login.advanced -import io.github.wulkanowy.data.pojos.RegisterUser +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.login.LoginData interface LoginAdvancedView : BaseView { @@ -12,8 +11,6 @@ interface LoginAdvancedView : BaseView { val formHostValue: String - val formDomainSuffix: String - val formHostSymbol: String val formLoginType: String @@ -52,7 +49,7 @@ interface LoginAdvancedView : BaseView { fun setErrorPassInvalid(focus: Boolean) - fun setErrorPassIncorrect(message: String?) + fun setErrorPassIncorrect() fun clearUsernameError() @@ -72,9 +69,7 @@ interface LoginAdvancedView : BaseView { fun showContent(show: Boolean) - fun navigateToSymbol(loginData: LoginData) - - fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) + fun notifyParentAccountLogged(studentsWithSemesters: List) fun setErrorPinRequired() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index 1c492069..c6d0209d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -5,23 +5,19 @@ import android.os.Bundle import android.view.View import android.view.View.GONE import android.view.View.VISIBLE -import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged -import androidx.fragment.app.setFragmentResultListener import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.FragmentLoginFormBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportDialog -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.hideSoftInput +import io.github.wulkanowy.utils.openEmailClient +import io.github.wulkanowy.utils.openInternetBrowser +import io.github.wulkanowy.utils.setOnEditorDoneSignIn +import io.github.wulkanowy.utils.showSoftInput import javax.inject.Inject @AndroidEntryPoint @@ -34,9 +30,6 @@ class LoginFormFragment : BaseFragment(R.layout.fragme @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - companion object { fun newInstance() = LoginFormFragment() } @@ -48,15 +41,10 @@ class LoginFormFragment : BaseFragment(R.layout.fragme get() = binding.loginFormPass.text.toString() override val formHostValue: String - get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())) - .orEmpty() - - override val formDomainSuffix: String - get() = binding.loginFormDomainSuffix.text.toString() + get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty() override val formHostSymbol: String - get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())) - .orEmpty() + get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginFormHost.text.toString())).orEmpty() override val nicknameLabel: String get() = getString(R.string.login_nickname_hint) @@ -74,18 +62,9 @@ class LoginFormFragment : BaseFragment(R.layout.fragme super.onViewCreated(view, savedInstanceState) binding = FragmentLoginFormBinding.bind(view) presenter.onAttachView(this) - initializeCaptchaResultObserver() - } - - private fun initializeCaptchaResultObserver() { - setFragmentResultListener(CaptchaDialog.CAPTCHA_SUCCESS) { _, _ -> - presenter.onRetryAfterCaptcha() - } } override fun initView() { - (requireActivity() as LoginActivity).showActionBar(false) - hostKeys = resources.getStringArray(R.array.hosts_keys) hostValues = resources.getStringArray(R.array.hosts_values) hostSymbols = resources.getStringArray(R.array.hosts_symbols) @@ -94,29 +73,18 @@ class LoginFormFragment : BaseFragment(R.layout.fragme loginFormUsername.doOnTextChanged { _, _, _, _ -> presenter.onUsernameTextChanged() } loginFormPass.doOnTextChanged { _, _, _, _ -> presenter.onPassTextChanged() } loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() } - loginFormDomainSuffix.doOnTextChanged { _, _, _, _ -> presenter.onDomainSuffixChanged() } loginFormSignIn.setOnClickListener { presenter.onSignInClick() } loginFormAdvancedButton.setOnClickListener { presenter.onAdvancedLoginClick() } loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() } loginFormFaq.setOnClickListener { presenter.onFaqClick() } loginFormContactEmail.setOnClickListener { presenter.onEmailClick() } loginFormRecoverLink.setOnClickListener { presenter.onRecoverClick() } - loginFormRecoverLinkSecond.setOnClickListener { presenter.onRecoverClick() } loginFormPass.setOnEditorDoneSignIn { loginFormSignIn.callOnClick() } - loginFormHost.setOnFocusChangeListener { _, hasFocus -> - if (hasFocus) requireActivity().hideSoftInput() - } } with(binding.loginFormHost) { setText(hostKeys.getOrNull(0).orEmpty()) - setAdapter( - LoginSymbolAdapter( - context, - R.layout.support_simple_spinner_dropdown_item, - hostKeys - ) - ) + setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)) setOnClickListener { if (binding.loginFormContainer.visibility == GONE) dismissDropDown() } } } @@ -142,79 +110,52 @@ class LoginFormFragment : BaseFragment(R.layout.fragme override fun setErrorUsernameRequired() { with(binding.loginFormUsernameLayout) { - error = getString(R.string.error_field_required) + requestFocus() + error = getString(R.string.login_field_required) } } override fun setErrorLoginRequired() { with(binding.loginFormUsernameLayout) { + requestFocus() error = getString(R.string.login_invalid_login) } } override fun setErrorEmailRequired() { with(binding.loginFormUsernameLayout) { + requestFocus() error = getString(R.string.login_invalid_email) } } override fun setErrorPassRequired(focus: Boolean) { with(binding.loginFormPassLayout) { - error = getString(R.string.error_field_required) - setEndIconTintList(requireContext().getAttrColorStateList(R.attr.colorError)) + if (focus) requestFocus() + error = getString(R.string.login_field_required) } } override fun setErrorPassInvalid(focus: Boolean) { with(binding.loginFormPassLayout) { + if (focus) requestFocus() error = getString(R.string.login_invalid_password) - setEndIconTintList(requireContext().getAttrColorStateList(R.attr.colorError)) } } - override fun setErrorPassIncorrect(message: String?) { - with(binding) { - loginFormUsernameLayout.error = " " - loginFormPassLayout.error = " " - loginFormPassLayout.setEndIconTintList(requireContext().getAttrColorStateList(R.attr.colorError)) - loginFormHostLayout.error = " " - loginFormErrorBox.text = message ?: getString(R.string.login_incorrect_password_default) - loginFormErrorBox.isVisible = true - } - } - - override fun setErrorEmailInvalid(domain: String) { - with(binding.loginFormUsernameLayout) { - error = getString(R.string.login_invalid_custom_email, domain) - } - } - - override fun setDomainSuffixInvalid() { - with(binding.loginFormDomainSuffixLayout) { - error = getString(R.string.login_invalid_domain_suffix) + override fun setErrorPassIncorrect() { + with(binding.loginFormPassLayout) { + requestFocus() + error = getString(R.string.login_incorrect_password) } } override fun clearUsernameError() { binding.loginFormUsernameLayout.error = null - binding.loginFormErrorBox.isVisible = false } override fun clearPassError() { binding.loginFormPassLayout.error = null - binding.loginFormPassLayout.setEndIconTintList( - requireContext().getAttrColorStateList(R.attr.colorOnSurface) - ) - binding.loginFormErrorBox.isVisible = false - } - - override fun clearHostError() { - binding.loginFormHostLayout.error = null - binding.loginFormErrorBox.isVisible = false - } - - override fun clearDomainSuffixError() { - binding.loginFormDomainSuffixLayout.error = null } override fun showSoftKeyboard() { @@ -233,49 +174,21 @@ class LoginFormFragment : BaseFragment(R.layout.fragme binding.loginFormContainer.visibility = if (show) VISIBLE else GONE } - override fun showAdminMessage(message: AdminMessage?) { - AdminMessageViewHolder( - binding = binding.loginFormMessage, - onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, - onAdminMessageClickListener = presenter::onAdminMessageSelected, - ).bind(message) - binding.loginFormMessage.root.isVisible = message != null - } - - override fun openInternetBrowser(url: String) { - requireContext().openInternetBrowser(url) - } - - override fun showDomainSuffixInput(show: Boolean) { - binding.loginFormDomainSuffixLayout.isVisible = show - } - - override fun showOtherOptionsButton(show: Boolean) { - binding.loginFormAdvancedButton.isVisible = show - } - @SuppressLint("SetTextI18n") override fun showVersion() { binding.loginFormVersion.text = "v${appInfo.versionName}" } - override fun showContact(show: Boolean) { - binding.loginFormContact.isVisible = show + override fun notifyParentAccountLogged(studentsWithSemesters: List, loginData: Triple) { + (activity as? LoginActivity)?.onFormFragmentAccountLogged(studentsWithSemesters, loginData) } override fun openPrivacyPolicyPage() { - context?.openInternetBrowser( - "https://wulkanowy.github.io/polityka-prywatnosci.html", - ::showMessage - ) + context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage) } - override fun navigateToSymbol(loginData: LoginData) { - (activity as? LoginActivity)?.navigateToSymbolFragment(loginData) - } - - override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) { - (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser) + override fun showContact(show: Boolean) { + binding.loginFormContact.visibility = if (show) VISIBLE else GONE } override fun openAdvancedLogin() { @@ -292,19 +205,26 @@ class LoginFormFragment : BaseFragment(R.layout.fragme } override fun openFaqPage() { - context?.openInternetBrowser( - "https://wulkanowy.github.io/czesto-zadawane-pytania/dlaczego-nie-moge-sie-zalogowac", - ::showMessage - ) + context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania/dlaczego-nie-moge-sie-zalogowac", ::showMessage) } override fun onResume() { super.onResume() presenter.updateUsernameLabel() - presenter.updateCustomDomainSuffixVisibility() } - override fun openEmail(supportInfo: LoginSupportInfo) { - LoginSupportDialog.newInstance(supportInfo).show(childFragmentManager, "support_dialog") + override fun openEmail(lastError: String) { + context?.openEmailClient( + chooserTitle = requireContext().getString(R.string.login_email_intent_title), + email = "wulkanowyinc@gmail.com", + subject = requireContext().getString(R.string.login_email_subject), + body = requireContext().getString(R.string.login_email_text, + "${appInfo.systemManufacturer} ${appInfo.systemModel}", + appInfo.systemVersion.toString(), + appInfo.versionName, + "$formHostValue/$formHostSymbol", + lastError + ) + ) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index 39bc3f02..e165d264 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -1,38 +1,22 @@ package io.github.wulkanowy.ui.modules.login.form import androidx.core.net.toUri -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceLoading -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow -import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase -import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginErrorHandler -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.ifNullOrBlank +import kotlinx.coroutines.flow.onEach import timber.log.Timber -import java.net.URL import javax.inject.Inject class LoginFormPresenter @Inject constructor( studentRepository: StudentRepository, private val loginErrorHandler: LoginErrorHandler, - private val appInfo: AppInfo, - private val analytics: AnalyticsHelper, - private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase, - private val preferencesRepository: PreferencesRepository, + private val analytics: AnalyticsHelper ) : BasePresenter(loginErrorHandler, studentRepository) { private var lastError: Throwable? = null @@ -42,40 +26,14 @@ class LoginFormPresenter @Inject constructor( view.run { initView() showContact(false) - showOtherOptionsButton(appInfo.isDebug) showVersion() loginErrorHandler.onBadCredentials = { - setErrorPassIncorrect(it.takeIf { !it.isNullOrBlank() }) + setErrorPassIncorrect() showSoftKeyboard() Timber.i("Entered wrong username or password") } } - - reloadAdminMessage() - } - - private fun reloadAdminMessage() { - flatResourceFlow { - getAppropriateAdminMessageUseCase( - scrapperBaseUrl = view?.formHostValue.orEmpty(), - type = MessageType.LOGIN_MESSAGE, - ) - } - .logResourceStatus("load login admin message") - .onResourceData { view?.showAdminMessage(it) } - .onResourceError { view?.showAdminMessage(null) } - .launch() - } - - fun onAdminMessageSelected(url: String?) { - url?.let { view?.openInternetBrowser(it) } - } - - fun onAdminMessageDismissed(adminMessage: AdminMessage) { - preferencesRepository.dismissedAdminMessageIds += adminMessage.id - - view?.showAdminMessage(null) } fun onPrivacyLinkClick() { @@ -90,27 +48,10 @@ class LoginFormPresenter @Inject constructor( view?.apply { clearPassError() clearUsernameError() - clearHostError() - if (formHostValue.contains("wulkanowy")) { + if (formHostValue.contains("fakelog")) { setCredentials("jan@fakelog.cf", "jan123") - } else if (formUsernameValue == "jan@fakelog.cf" && formPassValue == "jan123") { - setCredentials("", "") } - updateCustomDomainSuffixVisibility() updateUsernameLabel() - reloadAdminMessage() - } - } - - fun onDomainSuffixChanged() { - view?.apply { - clearDomainSuffixError() - } - } - - fun updateCustomDomainSuffixVisibility() { - view?.run { - showDomainSuffixInput("customSuffix" in formHostValue) } } @@ -129,95 +70,61 @@ class LoginFormPresenter @Inject constructor( val username = view?.formUsernameValue.orEmpty().trim() if ("@" in username && "@vulcan" !in username) { - val hosts = view?.getHostsValues().orEmpty().associateBy { it.toUri().host } + val hosts = view?.getHostsValues().orEmpty().map { it.toUri().host to it }.toMap() val usernameHost = username.substringAfter("@") hosts[usernameHost]?.let { - view?.run { - setHost(it) - clearHostError() - } + view?.setHost(it) } } } - private fun getLoginData(): LoginData { + fun onSignInClick() { val email = view?.formUsernameValue.orEmpty().trim() val password = view?.formPassValue.orEmpty().trim() val host = view?.formHostValue.orEmpty().trim() - val domainSuffix = view?.formDomainSuffix.orEmpty().trim().takeIf { - "customSuffix" in host - }.orEmpty() val symbol = view?.formHostSymbol.orEmpty().trim() - return LoginData( - login = email, - password = password, - baseUrl = host, - domainSuffix = domainSuffix, - defaultSymbol = symbol - ) - } + if (!validateCredentials(email, password, host)) return - fun onRetryAfterCaptcha() { - onSignInClick() - } - - fun onSignInClick() { - val loginData = getLoginData() - - if (!validateCredentials(loginData)) return - - resourceFlow { - studentRepository.getUserSubjectsFromScrapper( - email = loginData.login, - password = loginData.password, - scrapperBaseUrl = loginData.baseUrl, - domainSuffix = loginData.domainSuffix, - symbol = loginData.defaultSymbol, - ) - } - .logResourceStatus("login") - .onResourceLoading { - view?.run { + flowWithResource { studentRepository.getStudentsScrapper(email, password, host, symbol) }.onEach { + when (it.status) { + Status.LOADING -> view?.run { + Timber.i("Login started") hideSoftKeyboard() showProgress(true) showContent(false) } - } - .onResourceSuccess { - when (it.symbols.size) { - 0 -> view?.navigateToSymbol(loginData) - else -> view?.navigateToStudentSelect(loginData, it) + Status.SUCCESS -> { + Timber.i("Login result: Success") + analytics.logEvent( + "registration_form", + "success" to true, + "students" to it.data!!.size, + "scrapperBaseUrl" to host, + "error" to "No error" + ) + view?.notifyParentAccountLogged(it.data, Triple(email, password, host)) } - analytics.logEvent( - "registration_form", - "success" to true, - "scrapperBaseUrl" to loginData.baseUrl, - "error" to "No error" - ) - } - .onResourceNotLoading { - view?.apply { - showProgress(false) - showContent(true) + Status.ERROR -> { + Timber.i("Login result: An exception occurred") + analytics.logEvent( + "registration_form", + "success" to false, + "students" to -1, + "scrapperBaseUrl" to host, + "error" to it.error!!.message.ifNullOrBlank { "No message" }) + loginErrorHandler.dispatch(it.error) + lastError = it.error + view?.showContact(true) } } - .onResourceError { - loginErrorHandler.dispatch(it) - if (it is InvalidSymbolException) { - loginErrorHandler.showDefaultMessage(it) - } - lastError = it - view?.showContact(true) - analytics.logEvent( - "registration_form", - "success" to false, - "scrapperBaseUrl" to loginData.baseUrl, - "error" to it.message.ifNullOrBlank { "No message" } - ) + }.afterLoading { + view?.apply { + showProgress(false) + showContent(true) } - .launch("login") + }.launch("login") } fun onFaqClick() { @@ -225,65 +132,41 @@ class LoginFormPresenter @Inject constructor( } fun onEmailClick() { - view?.openEmail( - LoginSupportInfo( - loginData = getLoginData(), - lastErrorMessage = lastError?.message, - registerUser = null, - enteredSymbol = null, - ) - ) + view?.openEmail(lastError?.message.ifNullOrBlank { "none" }) } fun onRecoverClick() { view?.onRecoverClick() } - private fun validateCredentials(loginData: LoginData): Boolean { + private fun validateCredentials(login: String, password: String, host: String): Boolean { var isCorrect = true - if (loginData.login.isEmpty()) { + if (login.isEmpty()) { view?.setErrorUsernameRequired() isCorrect = false } else { - if ("@" in loginData.login && "login" in loginData.baseUrl) { + if ("@" in login && "login" in host) { view?.setErrorLoginRequired() isCorrect = false } - if ("@" !in loginData.login && "email" in loginData.baseUrl) { + + if ("@" !in login && "email" in host) { view?.setErrorEmailRequired() isCorrect = false } - - val isEmailLogin = "@" in loginData.login - val isEmailWithLogin = "||" !in loginData.login - val isLoginNotRequired = "login" !in loginData.baseUrl - val isEmailNotRequired = "email" !in loginData.baseUrl - if (isEmailLogin && isEmailWithLogin && isLoginNotRequired && isEmailNotRequired) { - val emailHost = loginData.login.substringAfter("@") - val emailDomain = URL(loginData.baseUrl).host - if (!emailHost.equals(emailDomain, true)) { - view?.setErrorEmailInvalid(domain = emailDomain) - isCorrect = false - } - } } - if (loginData.password.isEmpty()) { + if (password.isEmpty()) { view?.setErrorPassRequired(focus = isCorrect) isCorrect = false } - if (loginData.password.length < 6 && loginData.password.isNotEmpty()) { + if (password.length < 6 && password.isNotEmpty()) { view?.setErrorPassInvalid(focus = isCorrect) isCorrect = false } - if (loginData.domainSuffix !in listOf("", "rc", "kurs")) { - view?.setDomainSuffixInvalid() - isCorrect = false - } - return isCorrect } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 6ea22d18..31f8a621 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -1,10 +1,7 @@ package io.github.wulkanowy.ui.modules.login.form -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.pojos.RegisterUser +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo interface LoginFormView : BaseView { @@ -16,8 +13,6 @@ interface LoginFormView : BaseView { val formHostValue: String - val formDomainSuffix: String - val formHostSymbol: String val nicknameLabel: String @@ -42,20 +37,12 @@ interface LoginFormView : BaseView { fun setErrorPassInvalid(focus: Boolean) - fun setErrorPassIncorrect(message: String?) - - fun setErrorEmailInvalid(domain: String) - - fun setDomainSuffixInvalid() + fun setErrorPassIncorrect() fun clearUsernameError() fun clearPassError() - fun clearHostError() - - fun clearDomainSuffixError() - fun showSoftKeyboard() fun hideSoftKeyboard() @@ -64,19 +51,9 @@ interface LoginFormView : BaseView { fun showContent(show: Boolean) - fun showAdminMessage(message: AdminMessage?) - - fun openInternetBrowser(url: String) - - fun showDomainSuffixInput(show: Boolean) - - fun showOtherOptionsButton(show: Boolean) - fun showVersion() - fun navigateToSymbol(loginData: LoginData) - - fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) + fun notifyParentAccountLogged(studentsWithSemesters: List, loginData: Triple) fun openPrivacyPolicyPage() @@ -84,7 +61,7 @@ interface LoginFormView : BaseView { fun openFaqPage() - fun openEmail(supportInfo: LoginSupportInfo) + fun openEmail(lastError: String) fun openAdvancedLogin() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt index b9afba98..f0c9652f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt @@ -6,13 +6,12 @@ import android.os.Bundle import android.view.View import android.view.View.GONE import android.view.View.VISIBLE -import android.webkit.* -import androidx.core.view.isVisible +import android.webkit.JavascriptInterface +import android.webkit.WebView +import android.webkit.WebViewClient import androidx.core.widget.doOnTextChanged -import com.yariksoffice.lingver.Lingver import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.databinding.FragmentLoginRecoverBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity @@ -32,12 +31,6 @@ class LoginRecoverFragment : @Inject lateinit var presenter: LoginRecoverPresenter - @Inject - lateinit var lingver: Lingver - - @Inject - lateinit var preferencesRepository: PreferencesRepository - companion object { fun newInstance() = LoginRecoverFragment() } @@ -49,12 +42,10 @@ class LoginRecoverFragment : private lateinit var hostSymbols: Array override val recoverHostValue: String - get() = hostValues.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())) - .orEmpty() + get() = hostValues.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty() override val formHostSymbol: String - get() = hostSymbols.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())) - .orEmpty() + get() = hostSymbols.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty() override val recoverNameValue: String get() = bindingLocal.loginRecoverName.text.toString().trim() @@ -70,23 +61,11 @@ class LoginRecoverFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - restoreCorrectLocale() _binding = FragmentLoginRecoverBinding.bind(view) presenter.onAttachView(this) } - // https://issuetracker.google.com/issues/37113860 - private fun restoreCorrectLocale() { - if (preferencesRepository.appLanguage == "system") { - lingver.setFollowSystemLocale(requireContext()) - } else { - lingver.setLocale(requireContext(), lingver.getLocale()) - } - } - override fun initView() { - (requireActivity() as LoginActivity).showActionBar(true) - hostKeys = resources.getStringArray(R.array.hosts_keys) hostValues = resources.getStringArray(R.array.hosts_values) hostSymbols = resources.getStringArray(R.array.hosts_symbols) @@ -98,14 +77,12 @@ class LoginRecoverFragment : loginRecoverButton.setOnClickListener { presenter.onRecoverClick() } loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() } loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() } - loginRecoverLogin.setOnClickListener { (activity as LoginActivity).onBackPressedDispatcher.onBackPressed() } + loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) } } with(bindingLocal.loginRecoverHost) { setText(hostKeys.getOrNull(0).orEmpty()) - setAdapter( - LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys) - ) + setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys)) setOnClickListener { if (bindingLocal.loginRecoverFormContainer.visibility == GONE) dismissDropDown() } } } @@ -117,7 +94,7 @@ class LoginRecoverFragment : override fun setErrorNameRequired() { with(bindingLocal.loginRecoverNameLayout) { requestFocus() - error = getString(R.string.error_field_required) + error = getString(R.string.login_field_required) } } @@ -150,7 +127,6 @@ class LoginRecoverFragment : override fun showErrorView(show: Boolean) { bindingLocal.loginRecoverError.visibility = if (show) VISIBLE else GONE - bindingLocal.loginRecoverErrorDetails.isVisible = true } override fun setErrorDetails(message: String) { @@ -190,7 +166,7 @@ class LoginRecoverFragment : with(bindingLocal.loginRecoverWebView) { settings.javaScriptEnabled = true webViewClient = object : WebViewClient() { - private var recoverWebViewSuccess = true + private var recoverWebViewSuccess: Boolean = true override fun onPageFinished(view: WebView?, url: String?) { if (recoverWebViewSuccess) { @@ -199,15 +175,10 @@ class LoginRecoverFragment : } else { showProgress(false) showErrorView(true) - bindingLocal.loginRecoverErrorDetails.isVisible = false } } - override fun onReceivedError( - view: WebView?, - request: WebResourceRequest?, - error: WebResourceError? - ) { + override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) { recoverWebViewSuccess = false } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverPresenter.kt index 18902e01..319541b8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverPresenter.kt @@ -1,12 +1,12 @@ package io.github.wulkanowy.ui.modules.login.recover -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.repositories.RecoverRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.recover.RecoverRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.ifNullOrBlank import kotlinx.coroutines.flow.onEach import timber.log.Timber @@ -38,7 +38,7 @@ class LoginRecoverPresenter @Inject constructor( fun onHostSelected() { view?.run { - if ("wulkanowy" in recoverHostValue) setDefaultCredentials("jan@fakelog.cf") + if ("fakelog" in recoverHostValue) setDefaultCredentials("jan@fakelog.cf") clearUsernameError() updateFields() } @@ -46,7 +46,7 @@ class LoginRecoverPresenter @Inject constructor( fun updateFields() { view?.run { - setUsernameHint(if ("email" in recoverHostValue) emailHintString else loginPeselEmailHintString) + setUsernameHint(if ("standard" in recoverHostValue) emailHintString else loginPeselEmailHintString) } } @@ -57,28 +57,24 @@ class LoginRecoverPresenter @Inject constructor( if (!validateInput(username, host)) return - resourceFlow { - recoverRepository.getReCaptchaSiteKey( - host, - symbol.ifBlank { "default" }) - }.onEach { - when (it) { - is Resource.Loading -> view?.run { + flowWithResource { recoverRepository.getReCaptchaSiteKey(host, symbol.ifBlank { "Default" }) }.onEach { + when (it.status) { + Status.LOADING -> view?.run { hideSoftKeyboard() showRecoverForm(false) showProgress(true) showErrorView(false) showCaptcha(false) } - is Resource.Success -> view?.run { - loadReCaptcha(url = it.data.first, siteKey = it.data.second) + Status.SUCCESS -> view?.run { + loadReCaptcha(url = it.data!!.first, siteKey = it.data.second) showProgress(false) showErrorView(false) showCaptcha(true) } - is Resource.Error -> { + Status.ERROR -> { Timber.i("Obtain captcha site key result: An exception occurred") - errorHandler.dispatch(it.error) + errorHandler.dispatch(it.error!!) } } }.launch("captcha") @@ -92,7 +88,7 @@ class LoginRecoverPresenter @Inject constructor( isCorrect = false } - if ("email" in host && "@" !in username) { + if ("standard" in host && "@" !in username) { view?.setUsernameError(view?.invalidEmailString.orEmpty()) isCorrect = false } @@ -103,45 +99,28 @@ class LoginRecoverPresenter @Inject constructor( fun onReCaptchaVerified(reCaptchaResponse: String) { val username = view?.recoverNameValue.orEmpty() val host = view?.recoverHostValue.orEmpty() - val symbol = view?.formHostSymbol.ifNullOrBlank { "default" } + val symbol = view?.formHostSymbol.ifNullOrBlank { "Default" } - resourceFlow { - recoverRepository.sendRecoverRequest( - host, - symbol, - username, - reCaptchaResponse - ) - }.onEach { - when (it) { - is Resource.Loading -> view?.run { + flowWithResource { recoverRepository.sendRecoverRequest(host, symbol, username, reCaptchaResponse) }.onEach { + when (it.status) { + Status.LOADING -> view?.run { showProgress(true) showRecoverForm(false) showCaptcha(false) } - is Resource.Success -> view?.run { + Status.SUCCESS -> view?.run { showSuccessView(true) - setSuccessTitle(it.data.substringBefore(". ")) + setSuccessTitle(it.data!!.substringBefore(". ")) setSuccessMessage(it.data.substringAfter(". ")) - analytics.logEvent( - "account_recover", - "register" to host, - "symbol" to symbol, - "success" to true - ) + analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to true) } - is Resource.Error -> { + Status.ERROR -> { Timber.i("Send recover request result: An exception occurred") - errorHandler.dispatch(it.error) - analytics.logEvent( - "account_recover", - "register" to host, - "symbol" to symbol, - "success" to false - ) + errorHandler.dispatch(it.error!!) + analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false) } } - }.onResourceNotLoading { + }.afterLoading { view?.showProgress(false) }.launch("verified") } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/RecoverErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/RecoverErrorHandler.kt index 28686d62..110dd82e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/RecoverErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/RecoverErrorHandler.kt @@ -1,7 +1,7 @@ package io.github.wulkanowy.ui.modules.login.recover -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext +import android.content.res.Resources +import com.chuckerteam.chucker.api.ChuckerCollector import io.github.wulkanowy.sdk.scrapper.exception.InvalidCaptchaException import io.github.wulkanowy.sdk.scrapper.exception.InvalidEmailException import io.github.wulkanowy.sdk.scrapper.exception.NoAccountFoundException @@ -9,8 +9,9 @@ import io.github.wulkanowy.ui.base.ErrorHandler import javax.inject.Inject class RecoverErrorHandler @Inject constructor( - @ApplicationContext context: Context, -) : ErrorHandler(context) { + resources: Resources, + chuckerCollector: ChuckerCollector +) : ErrorHandler(resources, chuckerCollector) { var onInvalidUsername: (String) -> Unit = {} @@ -18,8 +19,7 @@ class RecoverErrorHandler @Inject constructor( override fun proceed(error: Throwable) { when (error) { - is InvalidEmailException, - is NoAccountFoundException -> onInvalidUsername(error.localizedMessage.orEmpty()) + is InvalidEmailException, is NoAccountFoundException -> onInvalidUsername(error.localizedMessage.orEmpty()) is InvalidCaptchaException -> onInvalidCaptcha(error.localizedMessage.orEmpty(), error) else -> super.proceed(error) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt index ef8cf4ee..c046c2ff 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt @@ -2,190 +2,65 @@ package io.github.wulkanowy.ui.modules.login.studentselect import android.annotation.SuppressLint import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.DiffUtil.ItemCallback -import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.* +import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.databinding.ItemLoginStudentSelectBinding import javax.inject.Inject -@SuppressLint("SetTextI18n") class LoginStudentSelectAdapter @Inject constructor() : - ListAdapter(Differ) { + RecyclerView.Adapter() { - override fun getItemViewType(position: Int): Int = getItem(position).type.ordinal + private val checkedList = mutableMapOf() - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val inflater = LayoutInflater.from(parent.context) - return when (LoginStudentSelectItemType.entries[viewType]) { - LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER -> EmptySymbolsHeaderViewHolder( - ItemLoginStudentSelectEmptySymbolHeaderBinding.inflate(inflater, parent, false), - ) - - LoginStudentSelectItemType.SYMBOL_HEADER -> SymbolsHeaderViewHolder( - ItemLoginStudentSelectHeaderSymbolBinding.inflate(inflater, parent, false) - ) - - LoginStudentSelectItemType.SCHOOL_HEADER -> SchoolHeaderViewHolder( - ItemLoginStudentSelectHeaderSchoolBinding.inflate(inflater, parent, false) - ) - - LoginStudentSelectItemType.STUDENT -> StudentViewHolder( - ItemLoginStudentSelectStudentBinding.inflate(inflater, parent, false) - ) - - LoginStudentSelectItemType.HELP -> HelpViewHolder( - ItemLoginStudentSelectHelpBinding.inflate(inflater, parent, false) - ) + var items = emptyList>() + set(value) { + field = value + checkedList.clear() } - } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - when (holder) { - is EmptySymbolsHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.EmptySymbolsHeader) - is SymbolsHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.SymbolHeader) - is SchoolHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.SchoolHeader) - is StudentViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.Student) - is HelpViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.Help) - } - } + var onClickListener: (StudentWithSemesters, alreadySaved: Boolean) -> Unit = { _, _ -> } - private class EmptySymbolsHeaderViewHolder( - private val binding: ItemLoginStudentSelectEmptySymbolHeaderBinding, - ) : RecyclerView.ViewHolder(binding.root) { + override fun getItemCount() = items.size - fun bind(item: LoginStudentSelectItem.EmptySymbolsHeader) { - with(binding) { - loginStudentSelectEmptySymbolChevron.rotation = if (item.isExpanded) 270f else 90f - root.setOnClickListener { item.onClick() } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + ItemLoginStudentSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) + + @SuppressLint("SetTextI18n") + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val (studentAndSemesters, alreadySaved) = items[position] + val student = studentAndSemesters.student + val semesters = studentAndSemesters.semesters + val diary = semesters.maxByOrNull { it.semesterId } + + with(holder.binding) { + loginItemName.text = "${student.studentName} ${diary?.diaryName.orEmpty()}" + loginItemSchool.text = student.schoolName + loginItemName.isEnabled = !alreadySaved + loginItemSchool.isEnabled = !alreadySaved + loginItemSignedIn.visibility = if (alreadySaved) View.VISIBLE else View.GONE + + with(loginItemCheck) { + isEnabled = !alreadySaved + keyListener = null + isChecked = checkedList[position] ?: false } - } - } - private class SymbolsHeaderViewHolder( - private val binding: ItemLoginStudentSelectHeaderSymbolBinding, - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: LoginStudentSelectItem.SymbolHeader) { - with(binding) { - loginStudentSelectHeaderSymbolValue.text = buildString { - append(root.context.getString(R.string.mobile_device_symbol)) - append(": ") - append(item.humanReadableName ?: item.symbol.symbol) - if (!item.humanReadableName.isNullOrBlank()) { - append(" (${item.symbol.symbol})") - } - } - loginStudentSelectHeaderSymbolUsername.text = item.symbol.userName - loginStudentSelectHeaderSymbolUsername.isVisible = item.symbol.userName.isNotBlank() - loginStudentSelectHeaderSymbolError.text = item.symbol.error?.message - loginStudentSelectHeaderSymbolError.isVisible = item.symbol.error != null - loginStudentSelectHeaderSymbolError.maxLines = when { - item.isErrorExpanded -> Int.MAX_VALUE - else -> 2 - } - - if (item.symbol.error != null) { - root.setOnClickListener { item.onClick(item.symbol) } - } else root.setOnClickListener(null) - } - } - } - - private class SchoolHeaderViewHolder( - private val binding: ItemLoginStudentSelectHeaderSchoolBinding, - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: LoginStudentSelectItem.SchoolHeader) { - with(binding) { - loginStudentSelectHeaderSchoolName.text = buildString { - append(item.unit.schoolName.trim()) - if (item.unit.schoolShortName.isNotBlank()) { - append(" (") - append(item.unit.schoolShortName) - append(")") - } - } - loginStudentSelectHeaderSchoolDetails.isVisible = item.unit.students.isEmpty() - loginStudentSelectHeaderSchoolError.text = item.unit.error?.message - loginStudentSelectHeaderSchoolError.isVisible = item.unit.error != null - loginStudentSelectHeaderSchoolError.maxLines = when { - item.isErrorExpanded -> Int.MAX_VALUE - else -> 2 - } - - if (item.unit.error != null) { - root.setOnClickListener { item.onClick(item.unit) } - } else root.setOnClickListener(null) - } - } - } - - private class StudentViewHolder( - private val binding: ItemLoginStudentSelectStudentBinding, - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: LoginStudentSelectItem.Student) { - val student = item.student - val semesters = student.semesters - val diary = semesters.maxByOrNull { it.semesterId } - - with(binding) { - loginItemName.text = "${student.studentName} ${student.studentSurname}" - loginItemName.isEnabled = item.isEnabled - loginItemSignedIn.text = if (!item.isEnabled) { - root.context.getString(R.string.login_signed_in) - } else diary?.diaryName + root.setOnClickListener { + onClickListener(studentAndSemesters, alreadySaved) with(loginItemCheck) { - keyListener = null - isEnabled = item.isEnabled - isChecked = item.isSelected || !item.isEnabled - } - - root.isEnabled = item.isEnabled - root.setOnClickListener { - item.onClick(item) + if (isEnabled) { + isChecked = !isChecked + checkedList[position] = isChecked + } } } } } - private class HelpViewHolder( - private val binding: ItemLoginStudentSelectHelpBinding, - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: LoginStudentSelectItem.Help) { - with(binding) { - loginStudentSelectHelpSymbol.isVisible = item.isSymbolButtonVisible - loginStudentSelectHelpSymbol.setOnClickListener { item.onEnterSymbolClick() } - loginStudentSelectHelpMail.setOnClickListener { item.onContactUsClick() } - loginStudentSelectHelpDiscord.setOnClickListener { item.onDiscordClick() } - } - } - } - - private object Differ : ItemCallback() { - - override fun areItemsTheSame( - oldItem: LoginStudentSelectItem, newItem: LoginStudentSelectItem - ): Boolean = when { - oldItem is LoginStudentSelectItem.EmptySymbolsHeader && newItem is LoginStudentSelectItem.EmptySymbolsHeader -> true - oldItem is LoginStudentSelectItem.SymbolHeader && newItem is LoginStudentSelectItem.SymbolHeader -> { - oldItem.symbol == newItem.symbol - } - - oldItem is LoginStudentSelectItem.Student && newItem is LoginStudentSelectItem.Student -> { - oldItem.student == newItem.student - } - - else -> oldItem == newItem - } - - override fun areContentsTheSame( - oldItem: LoginStudentSelectItem, newItem: LoginStudentSelectItem - ): Boolean = oldItem == newItem - } + class ItemViewHolder(val binding: ItemLoginStudentSelectBinding) : + RecyclerView.ViewHolder(binding.root) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt index 4eb60265..e71fc0f6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt @@ -2,23 +2,19 @@ package io.github.wulkanowy.ui.modules.login.studentselect import android.os.Bundle import android.view.View -import androidx.core.os.bundleOf -import androidx.core.view.isVisible +import android.view.View.GONE +import android.view.View.VISIBLE +import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.FragmentLoginStudentSelectBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder -import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportDialog -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo +import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.serializable +import java.io.Serializable import javax.inject.Inject @AndroidEntryPoint @@ -35,99 +31,89 @@ class LoginStudentSelectFragment : @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - - private lateinit var symbolsNames: Array - private lateinit var symbolsValues: Array - - override val symbols: Map by lazy { - symbolsValues.zip(symbolsNames).toMap() - } - companion object { - private const val ARG_LOGIN = "LOGIN" - private const val ARG_STUDENTS = "STUDENTS" + const val SAVED_STUDENTS = "STUDENTS" - fun newInstance(loginData: LoginData, registerUser: RegisterUser) = - LoginStudentSelectFragment().apply { - arguments = bundleOf( - ARG_LOGIN to loginData, - ARG_STUDENTS to registerUser, - ) - } + fun newInstance() = LoginStudentSelectFragment() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentLoginStudentSelectBinding.bind(view) - - symbolsNames = resources.getStringArray(R.array.symbols) - symbolsValues = resources.getStringArray(R.array.symbols_values) - - presenter.onAttachView( - view = this, - loginData = requireArguments().serializable(ARG_LOGIN), - registerUser = requireArguments().serializable(ARG_STUDENTS), - ) + presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_STUDENTS)) } override fun initView() { - (requireActivity() as LoginActivity).showActionBar(true) + loginAdapter.onClickListener = presenter::onItemSelected with(binding) { loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() } - loginStudentSelectRecycler.adapter = loginAdapter + loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() } + loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() } + + with(loginStudentSelectRecycler) { + layoutManager = LinearLayoutManager(context) + adapter = loginAdapter + } } } - override fun updateData(data: List) { - loginAdapter.submitList(data) + override fun updateData(data: List>) { + with(loginAdapter) { + items = data + notifyDataSetChanged() + } } - override fun navigateToSymbol(loginData: LoginData) { - (requireActivity() as LoginActivity).navigateToSymbolFragment(loginData) - } - - override fun navigateToNext() { - (requireActivity() as LoginActivity).navigateToNotifications() + override fun openMainView() { + activity?.let { startActivity(MainActivity.getStartIntent(context = it, clear = true)) } } override fun showProgress(show: Boolean) { - binding.loginStudentSelectProgress.isVisible = show + binding.loginStudentSelectProgress.visibility = if (show) VISIBLE else GONE } override fun showContent(show: Boolean) { - binding.loginStudentSelectContent.isVisible = show + binding.loginStudentSelectContent.visibility = if (show) VISIBLE else GONE } override fun enableSignIn(enable: Boolean) { binding.loginStudentSelectSignIn.isEnabled = enable } - override fun openDiscordInvite() { - context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) + fun onParentInitStudentSelectFragment(studentsWithSemesters: List) { + presenter.onParentInitStudentSelectView(studentsWithSemesters) } - override fun openEmail(supportInfo: LoginSupportInfo) { - LoginSupportDialog.newInstance(supportInfo).show(childFragmentManager, "support_dialog") + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putSerializable(SAVED_STUDENTS, presenter.students as Serializable) } - override fun showAdminMessage(adminMessage: AdminMessage?) { - AdminMessageViewHolder( - binding = binding.loginStudentSelectAdminMessage, - onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, - onAdminMessageClickListener = presenter::onAdminMessageSelected, - ).bind(adminMessage) - binding.loginStudentSelectAdminMessage.root.isVisible = adminMessage != null - } - - override fun openInternetBrowser(url: String) { - requireContext().openInternetBrowser(url) + override fun showContact(show: Boolean) { + binding.loginStudentSelectContact.visibility = if (show) VISIBLE else GONE } override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() } + + override fun openDiscordInvite() { + context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) + } + + override fun openEmail(lastError: String) { + context?.openEmailClient( + chooserTitle = requireContext().getString(R.string.login_email_intent_title), + email = "wulkanowyinc@gmail.com", + subject = requireContext().getString(R.string.login_email_subject), + body = requireContext().getString(R.string.login_email_text, appInfo.systemModel, + appInfo.systemVersion.toString(), + appInfo.versionName, + "Select users to log in", + lastError + ) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt deleted file mode 100644 index 1edc8e7b..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.wulkanowy.ui.modules.login.studentselect - -import io.github.wulkanowy.data.pojos.RegisterStudent -import io.github.wulkanowy.data.pojos.RegisterSymbol -import io.github.wulkanowy.data.pojos.RegisterUnit - -sealed class LoginStudentSelectItem(val type: LoginStudentSelectItemType) { - - data class EmptySymbolsHeader( - val isExpanded: Boolean, - val onClick: () -> Unit, - ) : LoginStudentSelectItem(LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER) - - data class SymbolHeader( - val symbol: RegisterSymbol, - val humanReadableName: String?, - val isErrorExpanded: Boolean, - val onClick: (RegisterSymbol) -> Unit, - ) : LoginStudentSelectItem(LoginStudentSelectItemType.SYMBOL_HEADER) - - data class SchoolHeader( - val unit: RegisterUnit, - val isErrorExpanded: Boolean, - val onClick: (RegisterUnit) -> Unit, - ) : LoginStudentSelectItem(LoginStudentSelectItemType.SCHOOL_HEADER) - - data class Student( - val symbol: RegisterSymbol, - val unit: RegisterUnit, - val student: RegisterStudent, - val isEnabled: Boolean, - val isSelected: Boolean, - val onClick: (Student) -> Unit, - ) : LoginStudentSelectItem(LoginStudentSelectItemType.STUDENT) - - data class Help( - val onEnterSymbolClick: () -> Unit, - val onContactUsClick: () -> Unit, - val onDiscordClick: () -> Unit, - val isSymbolButtonVisible: Boolean, - ) : LoginStudentSelectItem(LoginStudentSelectItemType.HELP) -} - -enum class LoginStudentSelectItemType { - EMPTY_SYMBOLS_HEADER, - SYMBOL_HEADER, - SCHOOL_HEADER, - STUDENT, - HELP, -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt index 39070cf0..dc824199 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt @@ -1,69 +1,36 @@ package io.github.wulkanowy.ui.modules.login.studentselect -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.dataOrNull -import io.github.wulkanowy.data.db.entities.AdminMessage +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.mappers.mapToStudentWithSemesters -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.pojos.RegisterStudent -import io.github.wulkanowy.data.pojos.RegisterSymbol -import io.github.wulkanowy.data.pojos.RegisterUnit -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SchoolsRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow -import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase -import io.github.wulkanowy.sdk.scrapper.exception.StudentGraduateException -import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException -import io.github.wulkanowy.services.sync.SyncManager +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginErrorHandler -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.isCurrent +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.ifNullOrBlank import kotlinx.coroutines.flow.onEach import timber.log.Timber +import java.io.Serializable import javax.inject.Inject class LoginStudentSelectPresenter @Inject constructor( studentRepository: StudentRepository, - private val schoolsRepository: SchoolsRepository, private val loginErrorHandler: LoginErrorHandler, - private val syncManager: SyncManager, - private val analytics: AnalyticsHelper, - private val appInfo: AppInfo, - private val preferencesRepository: PreferencesRepository, - private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase + private val analytics: AnalyticsHelper ) : BasePresenter(loginErrorHandler, studentRepository) { private var lastError: Throwable? = null - private lateinit var registerUser: RegisterUser - private lateinit var loginData: LoginData + var students = emptyList() - private lateinit var students: List - private var isEmptySymbolsExpanded = false - private var expandedSymbolError: RegisterSymbol? = null - private var expandedSchoolError: RegisterUnit? = null + private val selectedStudents = mutableListOf() - private val selectedStudents = mutableListOf() - - fun onAttachView( - view: LoginStudentSelectView, - loginData: LoginData, - registerUser: RegisterUser, - ) { + fun onAttachView(view: LoginStudentSelectView, students: Serializable?) { super.onAttachView(view) with(view) { initView() + showContact(false) enableSignIn(false) loginErrorHandler.onStudentDuplicate = { showMessage(it) @@ -71,213 +38,55 @@ class LoginStudentSelectPresenter @Inject constructor( } } - this.loginData = loginData - this.registerUser = registerUser - loadData() - loadAdminMessage() - } - - private fun loadData() { - resetSelectedState() - - resourceFlow { studentRepository.getSavedStudents(false) }.onEach { - students = it.dataOrNull.orEmpty() - when (it) { - is Resource.Loading -> Timber.d("Login student select students load started") - is Resource.Success -> { - getStudentsWithCurrentlyActiveSemesters() - selectedStudents.clear() - selectedStudents.addAll(getStudentsWithCurrentlyActiveSemesters()) - view?.enableSignIn(selectedStudents.isNotEmpty()) - refreshItems() - } - - is Resource.Error -> { - errorHandler.dispatch(it.error) - lastError = it.error - refreshItems() - } - } - }.launch("load_data") - } - - private fun loadAdminMessage() { - flatResourceFlow { - getAppropriateAdminMessageUseCase( - scrapperBaseUrl = registerUser.scrapperBaseUrl.orEmpty(), - type = MessageType.LOGIN_STUDENT_SELECT_MESSAGE, - ) - } - .logResourceStatus("load login admin message") - .onResourceData { view?.showAdminMessage(it) } - .onResourceError { view?.showAdminMessage(null) } - .launch("load_admin_message") - } - - private fun getStudentsWithCurrentlyActiveSemesters(): List { - val students = registerUser.symbols.flatMap { symbol -> - symbol.schools.flatMap { unit -> - unit.students.map { - createStudentItem(it, symbol, unit, students) - } - } - } - return students - .filter { it.isEnabled } - .filter { student -> - student.student.semesters.any { semester -> - semester.isCurrent() - } - } - } - - private fun createItems(): List = buildList { - val notEmptySymbols = registerUser.symbols.filter { it.shouldShowOnTop() } - val emptySymbols = registerUser.symbols.filter { !it.shouldShowOnTop() } - - if (emptySymbols.isNotEmpty() && notEmptySymbols.isNotEmpty() && emptySymbols.any { it.symbol == loginData.userEnteredSymbol }) { - add(createEmptySymbolItem(emptySymbols.first { it.symbol == loginData.userEnteredSymbol })) - } - - addAll(createNotEmptySymbolItems(notEmptySymbols, students)) - addAll(createEmptySymbolItems(emptySymbols, notEmptySymbols.isNotEmpty())) - - val helpItem = LoginStudentSelectItem.Help( - onEnterSymbolClick = ::onEnterSymbol, - onContactUsClick = ::onEmailClick, - onDiscordClick = ::onDiscordClick, - isSymbolButtonVisible = "login" !in loginData.baseUrl, - ) - add(helpItem) - } - - private fun RegisterSymbol.shouldShowOnTop(): Boolean { - return schools.isNotEmpty() || error is StudentGraduateException - } - - private fun createNotEmptySymbolItems( - notEmptySymbols: List, - students: List, - ) = buildList { - notEmptySymbols.forEach { registerSymbol -> - val symbolHeader = LoginStudentSelectItem.SymbolHeader( - symbol = registerSymbol, - humanReadableName = view?.symbols?.get(registerSymbol.symbol), - isErrorExpanded = expandedSymbolError == registerSymbol, - onClick = ::onSymbolItemClick, - ) - add(symbolHeader) - - registerSymbol.schools.forEach { registerUnit -> - val schoolHeader = LoginStudentSelectItem.SchoolHeader( - unit = registerUnit, - isErrorExpanded = expandedSchoolError == registerUnit, - onClick = ::onUnitItemClick, - ) - add(schoolHeader) - - registerUnit.students.forEach { - add(createStudentItem(it, registerSymbol, registerUnit, students)) - } - } + if (students is List<*> && students.isNotEmpty()) { + loadData(students.filterIsInstance()) } } - private fun createStudentItem( - student: RegisterStudent, - symbol: RegisterSymbol, - school: RegisterUnit, - students: List, - ) = LoginStudentSelectItem.Student( - symbol = symbol, - unit = school, - student = student, - onClick = ::onItemSelected, - isEnabled = students.none { - it.student.email == registerUser.login - && it.student.symbol == symbol.symbol - && it.student.studentId == student.studentId - && it.student.schoolSymbol == school.schoolId - && it.student.classId == student.classId - }, - isSelected = selectedStudents - .filter { it.symbol.symbol == symbol.symbol } - .filter { it.unit.schoolId == school.schoolId } - .filter { it.student.studentId == student.studentId } - .filter { it.student.classId == student.classId } - .size == 1, - ) - - private fun createEmptySymbolItems( - emptySymbols: List, - isNotEmptySymbolsExist: Boolean, - ) = buildList { - val filteredEmptySymbols = emptySymbols.filter { - it.error !is InvalidSymbolException - }.ifEmpty { emptySymbols.takeIf { !isNotEmptySymbolsExist }.orEmpty() } - - if (filteredEmptySymbols.isNotEmpty() && isNotEmptySymbolsExist) { - val emptyHeader = LoginStudentSelectItem.EmptySymbolsHeader( - isExpanded = isEmptySymbolsExpanded, - onClick = ::onEmptySymbolsToggle, - ) - add(emptyHeader) - if (isEmptySymbolsExpanded) { - filteredEmptySymbols.forEach { - add(createEmptySymbolItem(it)) - } - } - } - - if (filteredEmptySymbols.isNotEmpty() && !isNotEmptySymbolsExist) { - filteredEmptySymbols.forEach { - add(createEmptySymbolItem(it)) - } - } - } - - private fun createEmptySymbolItem(registerSymbol: RegisterSymbol) = - LoginStudentSelectItem.SymbolHeader( - symbol = registerSymbol, - humanReadableName = view?.symbols?.get(registerSymbol.symbol), - isErrorExpanded = expandedSymbolError == registerSymbol, - onClick = ::onSymbolItemClick, - ) - fun onSignIn() { registerStudents(selectedStudents) } - private fun onEmptySymbolsToggle() { - isEmptySymbolsExpanded = !isEmptySymbolsExpanded - - refreshItems() + fun onParentInitStudentSelectView(studentsWithSemesters: List) { + loadData(studentsWithSemesters) + if (studentsWithSemesters.size == 1) registerStudents(studentsWithSemesters) } - private fun onItemSelected(item: LoginStudentSelectItem.Student) { - if (!item.isEnabled) return + fun onItemSelected(studentWithSemester: StudentWithSemesters, alreadySaved: Boolean) { + if (alreadySaved) return selectedStudents - .removeAll { - it.student.studentId == item.student.studentId && - it.student.classId == item.student.classId && - it.unit.schoolId == item.unit.schoolId && - it.symbol.symbol == item.symbol.symbol - } - .let { if (!it) selectedStudents.add(item) } + .removeAll { it == studentWithSemester } + .let { if (!it) selectedStudents.add(studentWithSemester) } view?.enableSignIn(selectedStudents.isNotEmpty()) - refreshItems() } - private fun onSymbolItemClick(symbol: RegisterSymbol) { - expandedSymbolError = if (symbol != expandedSymbolError) symbol else null - refreshItems() + private fun compareStudents(a: Student, b: Student): Boolean { + return a.email == b.email + && a.symbol == b.symbol + && a.studentId == b.studentId + && a.schoolSymbol == b.schoolSymbol + && a.classId == b.classId } - private fun onUnitItemClick(unit: RegisterUnit) { - expandedSchoolError = if (unit != expandedSchoolError) unit else null - refreshItems() + private fun loadData(studentsWithSemesters: List) { + resetSelectedState() + this.students = studentsWithSemesters + + flowWithResource { studentRepository.getSavedStudents(false) }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Login student select students load started") + Status.SUCCESS -> view?.updateData(studentsWithSemesters.map { studentWithSemesters -> + studentWithSemesters to it.data!!.any { item -> compareStudents(studentWithSemesters.student, item.student) } + }) + Status.ERROR -> { + errorHandler.dispatch(it.error!!) + lastError = it.error + view?.updateData(studentsWithSemesters.map { student -> student to false }) + } + } + }.launch() } private fun resetSelectedState() { @@ -285,93 +94,54 @@ class LoginStudentSelectPresenter @Inject constructor( view?.enableSignIn(false) } - private fun refreshItems() { - view?.updateData(createItems()) - } - - private fun registerStudents(students: List) { - val filteredStudents = students.filterIsInstance() - val studentsWithSemesters = filteredStudents.map { item -> - item.student.mapToStudentWithSemesters( - user = registerUser, - symbol = item.symbol, - scrapperDomainSuffix = loginData.domainSuffix, - unit = item.unit, - colors = appInfo.defaultColorsForAvatar, - ) - } - resourceFlow { - studentRepository.saveStudents(studentsWithSemesters) - schoolsRepository.logSchoolLogin(loginData, studentsWithSemesters) - } - .logResourceStatus("registration") - .onEach { - when (it) { - is Resource.Loading -> view?.run { - showProgress(true) - showContent(false) - } - - is Resource.Success -> { - syncManager.startOneTimeSyncWorker(quiet = true) - view?.navigateToNext() - logRegisterEvent(studentsWithSemesters) - } - - is Resource.Error -> { - view?.apply { - showProgress(false) - showContent(true) - } - lastError = it.error - loginErrorHandler.dispatch(it.error) - logRegisterEvent(studentsWithSemesters, it.error) - } + private fun registerStudents(studentsWithSemesters: List) { + flowWithResource { + val savedStudents = studentRepository.saveStudents(studentsWithSemesters) + val firstRegistered = studentsWithSemesters.first().apply { student.id = savedStudents.first() } + studentRepository.switchStudent(firstRegistered) + }.onEach { + when (it.status) { + Status.LOADING -> view?.run { + Timber.i("Registration started") + showProgress(true) + showContent(false) } - }.launch("register") + Status.SUCCESS -> { + Timber.i("Registration result: Success") + view?.openMainView() + logRegisterEvent(studentsWithSemesters) + } + Status.ERROR -> { + Timber.i("Registration result: An exception occurred ") + view?.apply { + showProgress(false) + showContent(true) + showContact(true) + } + lastError = it.error + loginErrorHandler.dispatch(it.error!!) + logRegisterEvent(studentsWithSemesters, it.error) + } + } + }.launch("register") } - private fun onEnterSymbol() { - view?.navigateToSymbol(loginData) - } - - private fun onDiscordClick() { + fun onDiscordClick() { view?.openDiscordInvite() } - private fun onEmailClick() { - view?.openEmail( - LoginSupportInfo( - loginData = loginData, - registerUser = registerUser, - lastErrorMessage = lastError?.message, - enteredSymbol = loginData.userEnteredSymbol, - ) - ) + fun onEmailClick() { + view?.openEmail(lastError?.message.ifNullOrBlank { "empty" }) } - private fun logRegisterEvent( - studentsWithSemesters: List, - error: Throwable? = null - ) { + private fun logRegisterEvent(studentsWithSemesters: List, error: Throwable? = null) { studentsWithSemesters.forEach { student -> analytics.logEvent( "registration_student_select", "success" to (error != null), "scrapperBaseUrl" to student.student.scrapperBaseUrl, "symbol" to student.student.symbol, - "error" to (error?.message?.ifBlank { "No message" } ?: "No error") - ) + "error" to (error?.message?.ifBlank { "No message" } ?: "No error")) } } - - fun onAdminMessageSelected(url: String?) { - url?.let { view?.openInternetBrowser(it) } - } - - fun onAdminMessageDismissed(adminMessage: AdminMessage) { - preferencesRepository.dismissedAdminMessageIds += adminMessage.id - - view?.showAdminMessage(null) - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt index 4d0ef9e9..f2acd76c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt @@ -1,21 +1,15 @@ package io.github.wulkanowy.ui.modules.login.studentselect -import io.github.wulkanowy.data.db.entities.AdminMessage +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo interface LoginStudentSelectView : BaseView { - val symbols: Map - fun initView() - fun updateData(data: List) + fun updateData(data: List>) - fun navigateToSymbol(loginData: LoginData) - - fun navigateToNext() + fun openMainView() fun showProgress(show: Boolean) @@ -23,11 +17,9 @@ interface LoginStudentSelectView : BaseView { fun enableSignIn(enable: Boolean) + fun showContact(show: Boolean) + fun openDiscordInvite() - fun openEmail(supportInfo: LoginSupportInfo) - - fun showAdminMessage(adminMessage: AdminMessage?) - - fun openInternetBrowser(url: String) + fun openEmail(lastError: String) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportDialog.kt deleted file mode 100644 index 4be2dbaa..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportDialog.kt +++ /dev/null @@ -1,149 +0,0 @@ -package io.github.wulkanowy.ui.modules.login.support - -import android.os.Bundle -import android.util.Patterns -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.core.os.bundleOf -import androidx.core.widget.doOnTextChanged -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.databinding.DialogLoginSupportBinding -import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException -import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.openEmailClient -import io.github.wulkanowy.utils.serializable -import javax.inject.Inject - -@AndroidEntryPoint -class LoginSupportDialog : BaseDialogFragment() { - - @Inject - lateinit var appInfo: AppInfo - - @Inject - lateinit var preferencesRepository: PreferencesRepository - - private lateinit var supportInfo: LoginSupportInfo - - companion object { - private const val ARGUMENT_KEY = "info" - - fun newInstance(info: LoginSupportInfo) = LoginSupportDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to info) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setStyle(STYLE_NO_FRAME, R.style.WulkanowyTheme_NoActionBar) - supportInfo = requireArguments().serializable(ARGUMENT_KEY) - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - val binding = DialogLoginSupportBinding.inflate(inflater) - .apply { binding = this } - binding.dialogLoginSupportToolbar.setNavigationOnClickListener { dismiss() } - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - with(binding) { - dialogLoginSupportSchoolInput.doOnTextChanged { _, _, _, _ -> - with(dialogLoginSupportSchoolLayout) { - isErrorEnabled = false - error = null - } - } - dialogLoginSupportSubmit.setOnClickListener { onSubmitClick() } - } - } - - private fun onSubmitClick() { - when { - binding.dialogLoginSupportSchoolInput.text.isNullOrBlank() -> { - with(binding.dialogLoginSupportSchoolLayout) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - Patterns.EMAIL_ADDRESS.matcher( - binding.dialogLoginSupportSchoolInput.text.toString() - ).matches() -> { - with(binding.dialogLoginSupportSchoolLayout) { - isErrorEnabled = true - error = getString(R.string.login_support_school_invalid) - } - } - - else -> { - openEmailClientWithFilledTemplate() - dismiss() - } - } - } - - private fun openEmailClientWithFilledTemplate() { - with(binding) { - context?.openEmailClient( - chooserTitle = requireContext().getString(R.string.login_email_intent_title), - email = "wulkanowyinc@gmail.com", - subject = requireContext().getString(R.string.login_email_subject), - body = requireContext().getString( - R.string.login_email_text, - "${appInfo.systemManufacturer} ${appInfo.systemModel}", - appInfo.systemVersion.toString(), - "${appInfo.versionName}-${appInfo.buildFlavor}", - supportInfo.loginData.let { "${it.baseUrl}/${it.defaultSymbol}/${it.userEnteredSymbol}" }, - preferencesRepository.installationId, - getLastErrorFromStudentSelectScreen(), - dialogLoginSupportSchoolInput.text.takeIf { !it.isNullOrBlank() } - ?: return@with, - dialogLoginSupportAdditionalInput.text, - ) - ) - } - } - - private fun getLastErrorFromStudentSelectScreen(): String { - if (!supportInfo.lastErrorMessage.isNullOrBlank()) { - return supportInfo.lastErrorMessage!! - } - if (supportInfo.registerUser?.symbols.isNullOrEmpty()) { - return "" - } - - return "\n" + supportInfo.registerUser?.symbols?.filterNot { - (it.error is AccountPermissionException || it.error is InvalidSymbolException) && - it.symbol != supportInfo.enteredSymbol - }?.joinToString(";\n") { symbol -> - buildString { - append(" -") - append(symbol.symbol) - append("(${symbol.error?.message?.let { it.take(46) + "..." } ?: symbol.schools.size})") - if (symbol.schools.isNotEmpty()) { - append(": ") - } - append(symbol.schools.joinToString(", ") { unit -> - buildString { - append(unit.schoolShortName) - append("(${unit.error?.message?.let { it.take(46) + "..." } ?: unit.students.size})") - } - }) - } - } + "\nPozostałe: " + supportInfo.registerUser?.symbols?.filter { - it.error is AccountPermissionException || it.error is InvalidSymbolException - }?.joinToString(", ") { it.symbol } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportInfo.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportInfo.kt deleted file mode 100644 index 3f101dd6..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/support/LoginSupportInfo.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.ui.modules.login.support - -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.ui.modules.login.LoginData -import java.io.Serializable - -data class LoginSupportInfo( - val loginData: LoginData, - val registerUser: RegisterUser?, - val lastErrorMessage: String?, - val enteredSymbol: String?, -) : Serializable diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt index a813e7c0..e2c37db6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt @@ -7,26 +7,17 @@ import android.view.View.VISIBLE import android.view.inputmethod.EditorInfo.IME_ACTION_DONE import android.view.inputmethod.EditorInfo.IME_NULL import android.widget.ArrayAdapter -import androidx.core.os.bundleOf -import androidx.core.text.parseAsHtml -import androidx.core.view.isVisible import androidx.core.widget.doOnTextChanged import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.FragmentLoginSymbolBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.dashboard.viewholders.AdminMessageViewHolder import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportDialog -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.hideSoftInput +import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.serializable import io.github.wulkanowy.utils.showSoftInput import javax.inject.Inject @@ -40,36 +31,24 @@ class LoginSymbolFragment : @Inject lateinit var appInfo: AppInfo - @Inject - lateinit var preferencesRepository: PreferencesRepository - companion object { private const val SAVED_LOGIN_DATA = "LOGIN_DATA" - fun newInstance(loginData: LoginData) = LoginSymbolFragment().apply { - arguments = bundleOf(SAVED_LOGIN_DATA to loginData) - } + fun newInstance() = LoginSymbolFragment() } - override val symbolValue: String? get() = binding.loginSymbolName.text?.toString() - override val symbolNameError: CharSequence? get() = binding.loginSymbolNameLayout.error override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentLoginSymbolBinding.bind(view) - presenter.onAttachView( - view = this, - loginData = requireArguments().serializable(SAVED_LOGIN_DATA), - ) + presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_LOGIN_DATA)) } override fun initView() { - (requireActivity() as LoginActivity).showActionBar(true) - with(binding) { - loginSymbolSignIn.setOnClickListener { presenter.attemptLogin() } + loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) } loginSymbolFaq.setOnClickListener { presenter.onFaqClick() } loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() } @@ -79,20 +58,13 @@ class LoginSymbolFragment : setOnEditorActionListener { _, id, _ -> if (id == IME_ACTION_DONE || id == IME_NULL) loginSymbolSignIn.callOnClick() else false } - setAdapter( - ArrayAdapter( - context, - android.R.layout.simple_list_item_1, - resources.getStringArray(R.array.symbols_values) - ) - ) + setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values))) } } } - override fun setLoginToHeading(login: String) { - binding.loginSymbolHeader.text = - getString(R.string.login_header_symbol, login).parseAsHtml() + fun onParentInitSymbolFragment(loginData: Triple) { + presenter.onParentInitSymbolView(loginData) } override fun setErrorSymbolIncorrect() { @@ -102,28 +74,10 @@ class LoginSymbolFragment : } } - override fun setErrorSymbolInvalid() { - with(binding.loginSymbolNameLayout) { - requestFocus() - error = getString(R.string.login_invalid_symbol) - } - } - - override fun setErrorSymbolDefinitelyInvalid() { - with(binding.loginSymbolNameLayout) { - requestFocus() - error = getString(R.string.login_invalid_symbol_definitely) - } - } - override fun setErrorSymbolRequire() { - setErrorSymbol(getString(R.string.error_field_required)) - } - - override fun setErrorSymbol(message: String) { - with(binding.loginSymbolNameLayout) { + binding.loginSymbolNameLayout.apply { requestFocus() - error = message + error = getString(R.string.login_field_required) } } @@ -154,8 +108,8 @@ class LoginSymbolFragment : binding.loginSymbolContainer.visibility = if (show) VISIBLE else GONE } - override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) { - (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser) + override fun notifyParentAccountLogged(studentsWithSemesters: List) { + (activity as? LoginActivity)?.onSymbolFragmentAccountLogged(studentsWithSemesters) } override fun onSaveInstanceState(outState: Bundle) { @@ -173,26 +127,21 @@ class LoginSymbolFragment : } override fun openFaqPage() { - context?.openInternetBrowser( - "https://wulkanowy.github.io/czesto-zadawane-pytania/co-to-jest-symbol", - ::showMessage + context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania/co-to-jest-symbol", ::showMessage) + } + + override fun openEmail(host: String, lastError: String) { + context?.openEmailClient( + chooserTitle = requireContext().getString(R.string.login_email_intent_title), + email = "wulkanowyinc@gmail.com", + subject = requireContext().getString(R.string.login_email_subject), + body = requireContext().getString(R.string.login_email_text, + "${appInfo.systemManufacturer} ${appInfo.systemModel}", + appInfo.systemVersion.toString(), + appInfo.versionName, + "$host/${binding.loginSymbolName.text}", + lastError + ) ) } - - override fun openSupportDialog(supportInfo: LoginSupportInfo) { - LoginSupportDialog.newInstance(supportInfo).show(childFragmentManager, "support_dialog") - } - - override fun showAdminMessage(adminMessage: AdminMessage?) { - AdminMessageViewHolder( - binding = binding.loginSymbolAdminMessage, - onAdminMessageDismissClickListener = presenter::onAdminMessageDismissed, - onAdminMessageClickListener = presenter::onAdminMessageSelected, - ).bind(adminMessage) - binding.loginSymbolAdminMessage.root.isVisible = adminMessage != null - } - - override fun openInternetBrowser(url: String) { - requireContext().openInternetBrowser(url) - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt index 8de2994a..9f19539a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt @@ -1,161 +1,96 @@ package io.github.wulkanowy.ui.modules.login.symbol -import io.github.wulkanowy.data.Resource -import io.github.wulkanowy.data.dataOrNull -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.enums.MessageType -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.pojos.RegisterUser -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow -import io.github.wulkanowy.domain.adminmessage.GetAppropriateAdminMessageUseCase -import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol -import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.modules.login.LoginData import io.github.wulkanowy.ui.modules.login.LoginErrorHandler -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.ifNullOrBlank import kotlinx.coroutines.flow.onEach import timber.log.Timber +import java.io.Serializable import javax.inject.Inject class LoginSymbolPresenter @Inject constructor( studentRepository: StudentRepository, private val loginErrorHandler: LoginErrorHandler, - private val analytics: AnalyticsHelper, - private val preferencesRepository: PreferencesRepository, - private val getAppropriateAdminMessageUseCase: GetAppropriateAdminMessageUseCase, + private val analytics: AnalyticsHelper ) : BasePresenter(loginErrorHandler, studentRepository) { private var lastError: Throwable? = null - lateinit var loginData: LoginData + var loginData: Triple? = null - private var registerUser: RegisterUser? = null - - fun onAttachView(view: LoginSymbolView, loginData: LoginData) { + @Suppress("UNCHECKED_CAST") + fun onAttachView(view: LoginSymbolView, savedLoginData: Serializable?) { super.onAttachView(view) - this.loginData = loginData - loginErrorHandler.onBadCredentials = { - view.setErrorSymbol(it.orEmpty()) - } - with(view) { + view.run { initView() showContact(false) - setLoginToHeading(loginData.login) - clearAndFocusSymbol() - showSoftKeyboard() } - - loadAdminMessage() - } - - private fun loadAdminMessage() { - flatResourceFlow { - getAppropriateAdminMessageUseCase( - scrapperBaseUrl = loginData.baseUrl, - type = MessageType.LOGIN_SYMBOL_MESSAGE, - ) + if (savedLoginData is Triple<*, *, *>) { + loginData = savedLoginData as Triple } - .logResourceStatus("load login admin message") - .onResourceData { view?.showAdminMessage(it) } - .onResourceError { view?.showAdminMessage(null) } - .launch("load_admin_message") } fun onSymbolTextChanged() { view?.apply { if (symbolNameError != null) clearSymbolError() } } - fun attemptLogin() { - if (view?.symbolValue.isNullOrBlank()) { + fun attemptLogin(symbol: String) { + if (loginData == null) throw IllegalArgumentException("Login data is null") + + if (symbol.isBlank()) { view?.setErrorSymbolRequire() return } - if (isFormDefinitelyInvalid()) { - view?.setErrorSymbolDefinitelyInvalid() - return - } - loginData = loginData.copy( - userEnteredSymbol = view?.symbolValue?.getNormalizedSymbol(), - ) - resourceFlow { - studentRepository.getUserSubjectsFromScrapper( - email = loginData.login, - password = loginData.password, - scrapperBaseUrl = loginData.baseUrl, - domainSuffix = loginData.domainSuffix, - symbol = loginData.userEnteredSymbol.orEmpty(), - ) - }.onEach { user -> - registerUser = user.dataOrNull - when (user) { - is Resource.Loading -> view?.run { + flowWithResource { studentRepository.getStudentsScrapper(loginData!!.first, loginData!!.second, loginData!!.third, symbol) }.onEach { + when (it.status) { + Status.LOADING -> view?.run { Timber.i("Login with symbol started") hideSoftKeyboard() showProgress(true) showContent(false) } - - is Resource.Success -> { - when (user.data.symbols.size) { - 0 -> { + Status.SUCCESS -> { + view?.run { + if (it.data!!.isEmpty()) { Timber.i("Login with symbol result: Empty student list") - view?.run { - setErrorSymbolIncorrect() - showContact(true) - } - } - - else -> { - val enteredSymbolDetails = user.data.symbols - .firstOrNull() - ?.takeIf { it.symbol == loginData.userEnteredSymbol } - - if (enteredSymbolDetails?.error is InvalidSymbolException) { - showInvalidSymbolError() - } else { - Timber.i("Login with symbol result: Success") - view?.navigateToStudentSelect(loginData, requireNotNull(user.data)) - } + setErrorSymbolIncorrect() + view?.showContact(true) + } else { + Timber.i("Login with symbol result: Success") + notifyParentAccountLogged(it.data) } } analytics.logEvent( "registration_symbol", "success" to true, - "scrapperBaseUrl" to loginData.baseUrl, - "symbol" to view?.symbolValue, + "students" to it.data!!.size, + "scrapperBaseUrl" to loginData?.third, + "symbol" to symbol, "error" to "No error" ) } - - is Resource.Error -> { + Status.ERROR -> { Timber.i("Login with symbol result: An exception occurred") analytics.logEvent( "registration_symbol", "success" to false, "students" to -1, - "scrapperBaseUrl" to loginData.baseUrl, - "symbol" to view?.symbolValue, - "error" to user.error.message.ifNullOrBlank { "No message" } + "scrapperBaseUrl" to loginData?.third, + "symbol" to symbol, + "error" to it.error!!.message.ifNullOrBlank { "No message" } ) - loginErrorHandler.dispatch(user.error) - lastError = user.error + loginErrorHandler.dispatch(it.error) + lastError = it.error view?.showContact(true) - if (user.error is InvalidSymbolException) { - showInvalidSymbolError() - } } } - }.onResourceNotLoading { + }.afterLoading { view?.apply { showProgress(false) showContent(true) @@ -163,17 +98,11 @@ class LoginSymbolPresenter @Inject constructor( }.launch("login") } - private fun isFormDefinitelyInvalid(): Boolean { - val definitelyInvalidSymbols = listOf("vulcan", "uonet", "wulkanowy", "standardowa") - val normalizedSymbol = view?.symbolValue.orEmpty().getNormalizedSymbol() - - return normalizedSymbol in definitelyInvalidSymbols - } - - private fun showInvalidSymbolError() { - view?.run { - setErrorSymbolInvalid() - showContact(true) + fun onParentInitSymbolView(loginData: Triple) { + this.loginData = loginData + view?.apply { + clearAndFocusSymbol() + showSoftKeyboard() } } @@ -182,23 +111,6 @@ class LoginSymbolPresenter @Inject constructor( } fun onEmailClick() { - view?.openSupportDialog( - LoginSupportInfo( - loginData = loginData, - registerUser = registerUser, - lastErrorMessage = lastError?.message, - enteredSymbol = view?.symbolValue, - ) - ) - } - - fun onAdminMessageSelected(url: String?) { - url?.let { view?.openInternetBrowser(it) } - } - - fun onAdminMessageDismissed(adminMessage: AdminMessage) { - preferencesRepository.dismissedAdminMessageIds += adminMessage.id - - view?.showAdminMessage(null) + view?.openEmail(loginData?.third.orEmpty(), lastError?.message.ifNullOrBlank { "empty" }) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt index 2fc91024..830c77d1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt @@ -1,31 +1,18 @@ package io.github.wulkanowy.ui.modules.login.symbol -import io.github.wulkanowy.data.db.entities.AdminMessage -import io.github.wulkanowy.data.pojos.RegisterUser +import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.login.LoginData -import io.github.wulkanowy.ui.modules.login.support.LoginSupportInfo interface LoginSymbolView : BaseView { - val symbolValue: String? - val symbolNameError: CharSequence? fun initView() - fun setLoginToHeading(login: String) - fun setErrorSymbolIncorrect() - fun setErrorSymbolInvalid() - - fun setErrorSymbolDefinitelyInvalid() - fun setErrorSymbolRequire() - fun setErrorSymbol(message: String) - fun clearSymbolError() fun clearAndFocusSymbol() @@ -38,15 +25,11 @@ interface LoginSymbolView : BaseView { fun showContent(show: Boolean) - fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) + fun notifyParentAccountLogged(studentsWithSemesters: List) fun showContact(show: Boolean) fun openFaqPage() - fun openSupportDialog(supportInfo: LoginSupportInfo) - - fun showAdminMessage(adminMessage: AdminMessage?) - - fun openInternetBrowser(url: String) + fun openEmail(host: String, lastError: String) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberFragment.kt index a6c75c1d..0f1d836d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberFragment.kt @@ -9,16 +9,13 @@ import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.databinding.FragmentLuckyNumberBinding import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.luckynumber.history.LuckyNumberHistoryFragment -import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint class LuckyNumberFragment : BaseFragment(R.layout.fragment_lucky_number), LuckyNumberView, - MainView.TitledView, MainView.MainChildView { + MainView.TitledView { @Inject lateinit var presenter: LuckyNumberPresenter @@ -41,10 +38,7 @@ class LuckyNumberFragment : override fun initView() { with(binding) { - luckyNumberSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - luckyNumberSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - luckyNumberSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) - luckyNumberHistoryButton.setOnClickListener { openLuckyNumberHistory() } + luckyNumberSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } luckyNumberErrorRetry.setOnClickListener { presenter.onRetry() } luckyNumberErrorDetails.setOnClickListener { presenter.onDetailsClick() } } @@ -82,18 +76,6 @@ class LuckyNumberFragment : binding.luckyNumberContent.visibility = if (show) VISIBLE else GONE } - override fun openLuckyNumberHistory() { - (activity as? MainActivity)?.pushView(LuckyNumberHistoryFragment.newInstance()) - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onViewReselected() - } - - override fun popView() { - (activity as? MainActivity)?.popView() - } - override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberPresenter.kt index 2039624b..cfd793f2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberPresenter.kt @@ -1,11 +1,14 @@ package io.github.wulkanowy.ui.modules.luckynumber -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.repositories.LuckyNumberRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -31,45 +34,47 @@ class LuckyNumberPresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() luckyNumberRepository.getLuckyNumber(student, forceRefresh) - } - .logResourceStatus("load lucky number") - .onResourceData { - if (it != null) { - view?.apply { - updateData(it) - showContent(true) - showEmpty(false) - showErrorView(false) - } - } else { - view?.run { - showContent(false) - showEmpty(true) - showErrorView(false) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading lucky number started") + Status.SUCCESS -> { + if (it.data != null) { + Timber.i("Loading lucky number result: Success") + view?.apply { + updateData(it.data) + showContent(true) + showEmpty(false) + showErrorView(false) + } + analytics.logEvent( + "load_item", + "type" to "lucky_number", + "number" to it.data.luckyNumber + ) + } else { + Timber.i("Loading lucky number result: No lucky number found") + view?.run { + showContent(false) + showEmpty(true) + showErrorView(false) + } } } - } - .onResourceSuccess { - if (it != null) { - analytics.logEvent( - "load_item", - "type" to "lucky_number", - "number" to it.luckyNumber - ) + Status.ERROR -> { + Timber.i("Loading lucky number result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceNotLoading { - view?.run { - hideRefresh() - showProgress(false) - enableSwipe(true) - } + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -99,9 +104,4 @@ class LuckyNumberPresenter @Inject constructor( fun onDetailsClick() { view?.showErrorDetailsDialog(lastError) } - - fun onViewReselected() { - Timber.i("Luckynumber view is reselected") - view?.popView() - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberView.kt index 3d34ebc8..a680c83e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/LuckyNumberView.kt @@ -24,8 +24,4 @@ interface LuckyNumberView : BaseView { fun enableSwipe(enable: Boolean) fun showContent(show: Boolean) - - fun openLuckyNumberHistory() - - fun popView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryAdapter.kt deleted file mode 100644 index 9c718af4..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryAdapter.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.ui.modules.luckynumber.history - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.databinding.ItemLuckyNumberHistoryBinding -import io.github.wulkanowy.utils.capitalise -import io.github.wulkanowy.utils.toFormattedString -import io.github.wulkanowy.utils.weekDayName -import javax.inject.Inject - -class LuckyNumberHistoryAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = emptyList() - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( - ItemLuckyNumberHistoryBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - @SuppressLint("DefaultLocale") - override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val item = items[position] - with(holder.binding) { - luckyNumberHistoryWeekName.text = item.date.weekDayName.capitalise() - luckyNumberHistoryDate.text = item.date.toFormattedString() - luckyNumberHistory.text = item.luckyNumber.toString() - } - } - - class ItemViewHolder(val binding: ItemLuckyNumberHistoryBinding) : RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryFragment.kt deleted file mode 100644 index a78ce5dd..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryFragment.kt +++ /dev/null @@ -1,129 +0,0 @@ -package io.github.wulkanowy.ui.modules.luckynumber.history - -import android.os.Bundle -import android.view.View -import android.view.View.GONE -import android.view.View.VISIBLE -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.databinding.FragmentLuckyNumberHistoryBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear -import io.github.wulkanowy.utils.openMaterialDatePicker -import java.time.LocalDate -import javax.inject.Inject - -@AndroidEntryPoint -class LuckyNumberHistoryFragment : - BaseFragment(R.layout.fragment_lucky_number_history), - LuckyNumberHistoryView, - MainView.TitledView { - - @Inject - lateinit var presenter: LuckyNumberHistoryPresenter - - @Inject - lateinit var luckyNumberHistoryAdapter: LuckyNumberHistoryAdapter - - companion object { - fun newInstance() = LuckyNumberHistoryFragment() - } - - override val titleStringId: Int - get() = R.string.lucky_number_history_title - - override val isViewEmpty get() = luckyNumberHistoryAdapter.items.isEmpty() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentLuckyNumberHistoryBinding.bind(view) - messageContainer = binding.luckyNumberHistoryRecycler - presenter.onAttachView(this) - } - - override fun initView() { - with(binding.luckyNumberHistoryRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = luckyNumberHistoryAdapter - addItemDecoration(DividerItemDecoration(context)) - } - - with(binding) { - luckyNumberHistoryNavDate.setOnClickListener { presenter.onPickDate() } - luckyNumberHistoryErrorRetry.setOnClickListener { presenter.onRetry() } - luckyNumberHistoryErrorDetails.setOnClickListener { presenter.onDetailsClick() } - - luckyNumberHistoryPreviousButton.setOnClickListener { presenter.onPreviousWeek() } - luckyNumberHistoryNextButton.setOnClickListener { presenter.onNextWeek() } - - luckyNumberHistoryNavContainer.elevation = requireContext().dpToPx(3f) - } - } - - override fun updateData(data: List) { - with(luckyNumberHistoryAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun clearData() { - with(luckyNumberHistoryAdapter) { - items = emptyList() - notifyDataSetChanged() - } - } - - override fun showEmpty(show: Boolean) { - binding.luckyNumberHistoryEmpty.visibility = if (show) VISIBLE else GONE - } - - override fun showErrorView(show: Boolean) { - binding.luckyNumberHistoryError.visibility = if (show) VISIBLE else GONE - } - - override fun setErrorDetails(message: String) { - binding.luckyNumberHistoryErrorMessage.text = message - } - - override fun updateNavigationWeek(date: String) { - binding.luckyNumberHistoryNavDate.text = date - } - - override fun showProgress(show: Boolean) { - binding.luckyNumberHistoryProgress.visibility = if (show) VISIBLE else GONE - } - - override fun showPreButton(show: Boolean) { - binding.luckyNumberHistoryPreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE - } - - override fun showNextButton(show: Boolean) { - binding.luckyNumberHistoryNextButton.visibility = if (show) VISIBLE else View.INVISIBLE - } - - override fun showDatePickerDialog(selectedDate: LocalDate) { - openMaterialDatePicker( - selected = selectedDate, - rangeStart = selectedDate.firstSchoolDayInSchoolYear, - rangeEnd = LocalDate.now().plusWeeks(1), - onDateSelected = { - presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth) - } - ) - } - - override fun showContent(show: Boolean) { - binding.luckyNumberHistoryRecycler.visibility = if (show) VISIBLE else GONE - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryPresenter.kt deleted file mode 100644 index fc753950..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryPresenter.kt +++ /dev/null @@ -1,155 +0,0 @@ -package io.github.wulkanowy.ui.modules.luckynumber.history - -import io.github.wulkanowy.data.repositories.LuckyNumberRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.* -import kotlinx.coroutines.flow.* -import timber.log.Timber -import java.time.LocalDate -import javax.inject.Inject - -class LuckyNumberHistoryPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val semesterRepository: SemesterRepository, - private val luckyNumberRepository: LuckyNumberRepository, - private val analytics: AnalyticsHelper -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var lastError: Throwable - - var currentDate: LocalDate = LocalDate.now().previousOrSameSchoolDay - - override fun onAttachView(view: LuckyNumberHistoryView) { - super.onAttachView(view) - view.run { - initView() - reloadNavigation() - showContent(false) - } - Timber.i("Lucky number history view was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData() - if (currentDate.isHolidays) setBaseDateOnHolidays() - } - - private fun setBaseDateOnHolidays() { - flow { - val student = studentRepository.getCurrentStudent() - emit(semesterRepository.getCurrentSemester(student)) - } - .catch { Timber.i("Loading semester result: An exception occurred") } - .onEach { - currentDate = currentDate.getLastSchoolDayIfHoliday(it.schoolYear) - reloadNavigation() - } - .launch("holidays") - } - - private fun loadData() { - flow { - val student = studentRepository.getCurrentStudent() - emitAll( - luckyNumberRepository.getLuckyNumberHistory( - student = student, - start = currentDate.monday, - end = currentDate.sunday - ) - ) - } - .onEach { - if (!it.isNullOrEmpty()) { - view?.apply { - updateData(it) - showContent(true) - showEmpty(false) - showErrorView(false) - showProgress(false) - } - } else { - view?.run { - showContent(false) - showEmpty(true) - showErrorView(false) - showProgress(false) - } - } - - analytics.logEvent( - "load_items", - "type" to "lucky_number_history", - ) - } - .catch { errorHandler.dispatch(it) } - .launchIn(presenterScope) - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - } else showError(message, error) - } - } - - private fun reloadView(date: LocalDate) { - currentDate = date - Timber.i("Reload lucky number history view with the date ${currentDate.toFormattedString()}") - view?.apply { - showProgress(true) - showContent(false) - showEmpty(false) - showErrorView(false) - clearData() - reloadNavigation() - } - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData() - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - private fun reloadNavigation() { - view?.apply { - showPreButton(!currentDate.minusDays(7).isHolidays) - showNextButton(!currentDate.plusDays(7).isHolidays) - updateNavigationWeek( - "${currentDate.monday.toFormattedString("dd.MM")} - " + - currentDate.sunday.toFormattedString("dd.MM") - ) - } - } - - fun onDateSet(year: Int, month: Int, day: Int) { - reloadView(LocalDate.of(year, month, day)) - loadData() - } - - fun onPickDate() { - view?.showDatePickerDialog(currentDate) - } - - fun onPreviousWeek() { - reloadView(currentDate.minusDays(7)) - loadData() - } - - fun onNextWeek() { - reloadView(currentDate.plusDays(7)) - loadData() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryView.kt deleted file mode 100644 index 7b9b0294..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumber/history/LuckyNumberHistoryView.kt +++ /dev/null @@ -1,36 +0,0 @@ -package io.github.wulkanowy.ui.modules.luckynumber.history - -import io.github.wulkanowy.data.db.entities.LuckyNumber -import io.github.wulkanowy.ui.base.BaseView -import java.time.LocalDate - -interface LuckyNumberHistoryView : BaseView { - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun clearData() - - fun showEmpty(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun updateNavigationWeek(date: String) - - fun showProgress(show: Boolean) - - fun showPreButton(show: Boolean) - - fun showNextButton(show: Boolean) - - fun showDatePickerDialog(selectedDate: LocalDate) - - fun showContent(show: Boolean) - - fun onDestroyView() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt index a2d23e54..692615d9 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt @@ -1,13 +1,17 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget -import android.appwidget.AppWidgetManager.* +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.content.Intent +import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.base.WidgetConfigureAdapter @@ -34,9 +38,8 @@ class LuckyNumberWidgetConfigureActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setResult(RESULT_CANCELED) - setContentView( - ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root - ) + setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root) + intent.extras.let { presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID)) } @@ -51,9 +54,24 @@ class LuckyNumberWidgetConfigureActivity : configureAdapter.onClickListener = presenter::onItemSelect } - override fun updateData(data: List, selectedStudentId: Long) { + override fun showThemeDialog() { + var items = arrayOf( + getString(R.string.widget_timetable_theme_light), + getString(R.string.widget_timetable_theme_dark) + ) + if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += (getString(R.string.widget_timetable_theme_system)) + + dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher) + .setTitle(R.string.widget_timetable_theme_title) + .setOnDismissListener { presenter.onDismissThemeView() } + .setSingleChoiceItems(items, -1) { _, which -> + presenter.onThemeSelect(which) + } + .show() + } + + override fun updateData(data: List>) { with(configureAdapter) { - selectedId = selectedStudentId items = data notifyDataSetChanged() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt index 7e53dad0..574120b3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt @@ -1,13 +1,14 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget -import io.github.wulkanowy.data.Resource +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getStudentWidgetKey +import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getThemeWidgetKey +import io.github.wulkanowy.utils.flowWithResource import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -31,24 +32,38 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor( fun onItemSelect(student: Student) { selectedStudent = student + view?.showThemeDialog() + } + + fun onThemeSelect(index: Int) { + appWidgetId?.let { + sharedPref.putLong(getThemeWidgetKey(it), index.toLong()) + } registerStudent(selectedStudent) } + fun onDismissThemeView() { + view?.finishView() + } + private fun loadData() { - resourceFlow { studentRepository.getSavedStudents(false) }.onEach { - when (it) { - is Resource.Loading -> Timber.d("Lucky number widget configure students data load") - is Resource.Success -> { - val selectedStudentId = appWidgetId?.let { id -> - sharedPref.getLong(getStudentWidgetKey(id), 0) - } ?: -1 + flowWithResource { studentRepository.getSavedStudents(false) }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Lucky number widget configure students data load") + Status.SUCCESS -> { + val widgetId = appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) } when { - it.data.isEmpty() -> view?.openLoginView() - it.data.size == 1 -> onItemSelect(it.data.single().student) - else -> view?.updateData(it.data, selectedStudentId) + it.data!!.isEmpty() -> view?.openLoginView() + it.data.size == 1 -> { + selectedStudent = it.data.single().student + view?.showThemeDialog() + } + else -> view?.updateData(it.data.map { entity -> + entity.student to (entity.student.id == widgetId) + }) } } - is Resource.Error -> errorHandler.dispatch(it.error) + Status.ERROR -> errorHandler.dispatch(it.error!!) } }.launch() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt index df13b993..c8c348ed 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt @@ -1,13 +1,15 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget -import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseView interface LuckyNumberWidgetConfigureView : BaseView { fun initView() - fun updateData(data: List, selectedStudentId: Long) + fun showThemeDialog() + + fun updateData(data: List>) fun updateLuckyNumberWidget(widgetId: Int) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt index e6de1781..b7f4b740 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt @@ -1,24 +1,26 @@ package io.github.wulkanowy.ui.modules.luckynumberwidget import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT +import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH import android.appwidget.AppWidgetProvider import android.content.Context import android.content.res.Configuration import android.os.Bundle -import android.util.TypedValue.COMPLEX_UNIT_SP -import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import android.widget.RemoteViews import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.dataOrThrow import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.repositories.LuckyNumberRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.toFirstResult -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.PendingIntentCompat +import io.github.wulkanowy.data.exceptions.NoCurrentStudentException +import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.toFirstResult import kotlinx.coroutines.runBlocking import timber.log.Timber import javax.inject.Inject @@ -36,99 +38,93 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() { lateinit var sharedPref: SharedPrefProvider companion object { - private const val LUCKY_NUMBER_WIDGET_MAX_SIZE = 196 - - private const val LUCKY_NUMBER_PENDING_INTENT_ID = 300 - private const val LUCKY_NUMBER_HISTORY_PENDING_INTENT_ID = 301 fun getStudentWidgetKey(appWidgetId: Int) = "lucky_number_widget_student_$appWidgetId" + + fun getThemeWidgetKey(appWidgetId: Int) = "lucky_number_widget_theme_$appWidgetId" + + fun getHeightWidgetKey(appWidgetId: Int) = "lucky_number_widget_height_$appWidgetId" + + fun getWidthWidgetKey(appWidgetId: Int) = "lucky_number_widget_width_$appWidgetId" } - override fun onUpdate( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetIds: IntArray? - ) { + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray?) { super.onUpdate(context, appWidgetManager, appWidgetIds) + appWidgetIds?.forEach { appWidgetId -> - val appIntent = PendingIntent.getActivity( - context, - LUCKY_NUMBER_PENDING_INTENT_ID, - SplashActivity.getStartIntent(context, Destination.LuckyNumber), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) + val luckyNumber = getLuckyNumber(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId) + val appIntent = PendingIntent.getActivity(context, MainView.Section.LUCKY_NUMBER.id, + MainActivity.getStartIntent(context, MainView.Section.LUCKY_NUMBER, true), FLAG_UPDATE_CURRENT) - val historyIntent = PendingIntent.getActivity( - context, - LUCKY_NUMBER_HISTORY_PENDING_INTENT_ID, - SplashActivity.getStartIntent(context, Destination.LuckyNumberHistory), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) + val remoteView = RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context)).apply { + setTextViewText(R.id.luckyNumberWidgetNumber, luckyNumber?.luckyNumber?.toString() ?: "#") + setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent) + } - appWidgetIds?.forEach { widgetId -> - val studentId = sharedPref.getLong(getStudentWidgetKey(widgetId), 0) - val luckyNumber = getLuckyNumber(studentId, widgetId)?.luckyNumber?.toString() - val remoteView = RemoteViews(context.packageName, R.layout.widget_luckynumber) - .apply { - setTextViewText(R.id.luckyNumberWidgetValue, luckyNumber ?: "-") - setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent) - setOnClickPendingIntent(R.id.luckyNumberWidgetHistoryButton, historyIntent) - } - - resizeWidget(context, appWidgetManager.getAppWidgetOptions(widgetId), remoteView) - appWidgetManager.updateAppWidget(widgetId, remoteView) - } - } - - override fun onAppWidgetOptionsChanged( - context: Context?, - appWidgetManager: AppWidgetManager?, - appWidgetId: Int, - newOptions: Bundle? - ) { - super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions) - - if (context == null || newOptions == null || appWidgetManager == null) { - return - } - - val remoteView = RemoteViews(context.packageName, R.layout.widget_luckynumber) - resizeWidget(context, newOptions, remoteView) - appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteView) - } - - private fun resizeWidget(context: Context, options: Bundle, remoteViews: RemoteViews) { - val (width, height) = options.getWidgetSize(context) - val size = minOf(width, height, LUCKY_NUMBER_WIDGET_MAX_SIZE).toFloat() - resizeWidgetContents(size, remoteViews) - Timber.v("LuckyNumberWidget resized: ${width}x${height} ($size)") - } - - private fun resizeWidgetContents(size: Float, remoteViews: RemoteViews) { - var historyButtonVisibility = View.VISIBLE - var luckyNumberTextSize = 72f - - if (size < 150) { - luckyNumberTextSize = 44f - historyButtonVisibility = View.GONE - } - if (size < 75) { - luckyNumberTextSize = 26f - } - - remoteViews.apply { - setTextViewTextSize(R.id.luckyNumberWidgetValue, COMPLEX_UNIT_SP, luckyNumberTextSize) - setViewVisibility(R.id.luckyNumberWidgetHistoryButton, historyButtonVisibility) + setStyles(remoteView, appWidgetId) + appWidgetManager.updateAppWidget(appWidgetId, remoteView) } } override fun onDeleted(context: Context?, appWidgetIds: IntArray?) { super.onDeleted(context, appWidgetIds) appWidgetIds?.forEach { appWidgetId -> - sharedPref.delete(getStudentWidgetKey(appWidgetId)) + with(sharedPref) { + delete(getHeightWidgetKey(appWidgetId)) + delete(getStudentWidgetKey(appWidgetId)) + delete(getThemeWidgetKey(appWidgetId)) + delete(getWidthWidgetKey(appWidgetId)) + } } } + override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle?) { + super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions) + + val remoteView = RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context)) + + setStyles(remoteView, appWidgetId, newOptions) + appWidgetManager.updateAppWidget(appWidgetId, remoteView) + } + + private fun setStyles(views: RemoteViews, appWidgetId: Int, options: Bundle? = null) { + val width = options?.getInt(OPTION_APPWIDGET_MIN_WIDTH) ?: sharedPref.getLong(getWidthWidgetKey(appWidgetId), 74).toInt() + val height = options?.getInt(OPTION_APPWIDGET_MAX_HEIGHT) ?: sharedPref.getLong(getHeightWidgetKey(appWidgetId), 74).toInt() + + with(sharedPref) { + putLong(getWidthWidgetKey(appWidgetId), width.toLong()) + putLong(getHeightWidgetKey(appWidgetId), height.toLong()) + } + + val rows = getCellsForSize(height) + val cols = getCellsForSize(width) + + Timber.d("New lucky number widget measurement: %dx%d", width, height) + Timber.d("Widget size: $cols x $rows") + + when { + 1 == cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = false) + 1 == cols && 1 < rows -> views.setVisibility(imageTop = true, imageLeft = false) + 1 < cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = true) + 1 == cols && 1 == rows -> views.setVisibility(imageTop = true, imageLeft = false) + 2 == cols && 1 == rows -> views.setVisibility(imageTop = false, imageLeft = true) + else -> views.setVisibility(imageTop = false, imageLeft = false, title = true) + } + } + + private fun RemoteViews.setVisibility(imageTop: Boolean, imageLeft: Boolean, title: Boolean = false) { + setViewVisibility(R.id.luckyNumberWidgetImageTop, if (imageTop) VISIBLE else GONE) + setViewVisibility(R.id.luckyNumberWidgetImageLeft, if (imageLeft) VISIBLE else GONE) + setViewVisibility(R.id.luckyNumberWidgetTitle, if (title) VISIBLE else GONE) + setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE) + } + + private fun getCellsForSize(size: Int): Int { + var n = 2 + while (74 * n - 30 < size) ++n + return n - 1 + } + private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking { try { val students = studentRepository.getSavedStudents() @@ -140,38 +136,28 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } } - else -> null } - if (currentStudent != null) { - luckyNumberRepository.getLuckyNumber( - student = currentStudent, - forceRefresh = false, - isFromAppWidget = true - ) - .toFirstResult() - .dataOrThrow - } else null + currentStudent?.let { + luckyNumberRepository.getLuckyNumber(it, false).toFirstResult().data + } } catch (e: Exception) { - Timber.e(e, "An error has occurred in lucky number provider") + if (e.cause !is NoCurrentStudentException) { + Timber.e(e, "An error has occurred in lucky number provider") + } null } } - private fun Bundle.getWidgetSize(context: Context): Pair { - val minWidth = getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH) - val maxWidth = getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH) - val minHeight = getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT) - val maxHeight = getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT) + private fun getCorrectLayoutId(appWidgetId: Int, context: Context): Int { + val savedTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + val isSystemDarkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES - val orientation = context.resources.configuration.orientation - val isPortrait = orientation == Configuration.ORIENTATION_PORTRAIT - - return if (isPortrait) { - minWidth to maxHeight + return if (savedTheme == 1L || (savedTheme == 2L && isSystemDarkMode)) { + R.layout.widget_luckynumber_dark } else { - maxWidth to minHeight + R.layout.widget_luckynumber } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt index e64aa9b0..25b41aab 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt @@ -1,63 +1,55 @@ package io.github.wulkanowy.ui.modules.main +import android.annotation.SuppressLint import android.content.Context import android.content.Intent +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.graphics.drawable.Icon import android.os.Build +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP import android.os.Bundle import android.view.Menu import android.view.MenuItem -import android.view.ViewGroup.MarginLayoutParams -import androidx.activity.OnBackPressedCallback -import androidx.activity.addCallback +import androidx.annotation.RequiresApi +import androidx.core.content.getSystemService import androidx.core.view.ViewCompat -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.isVisible -import androidx.core.view.updateLayoutParams import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope -import androidx.preference.Preference -import androidx.preference.PreferenceFragmentCompat -import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.aurelhubert.ahbottomnavigation.AHBottomNavigation.TitleState.ALWAYS_SHOW +import com.aurelhubert.ahbottomnavigation.AHBottomNavigationItem import com.google.android.material.elevation.ElevationOverlayProvider import com.ncapdevi.fragnav.FragNavController import com.ncapdevi.fragnav.FragNavController.Companion.HIDE import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.databinding.ActivityMainBinding import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog -import io.github.wulkanowy.ui.modules.auth.AuthDialog -import io.github.wulkanowy.ui.modules.captcha.CaptchaDialog -import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem +import io.github.wulkanowy.ui.modules.account.AccountDialog +import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment +import io.github.wulkanowy.ui.modules.exam.ExamFragment +import io.github.wulkanowy.ui.modules.grade.GradeFragment +import io.github.wulkanowy.ui.modules.homework.HomeworkFragment +import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment +import io.github.wulkanowy.ui.modules.message.MessageFragment +import io.github.wulkanowy.ui.modules.more.MoreFragment +import io.github.wulkanowy.ui.modules.note.NoteFragment +import io.github.wulkanowy.ui.modules.timetable.TimetableFragment import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.InAppReviewHelper -import io.github.wulkanowy.utils.InAppUpdateHelper -import io.github.wulkanowy.utils.createNameInitialsDrawable +import io.github.wulkanowy.utils.UpdateHelper import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.nickOrName +import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.safelyPopFragments import io.github.wulkanowy.utils.setOnViewChangeListener -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import timber.log.Timber import javax.inject.Inject -import kotlin.time.Duration.Companion.seconds @AndroidEntryPoint -class MainActivity : BaseActivity(), MainView, - PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { +class MainActivity : BaseActivity(), MainView { @Inject override lateinit var presenter: MainPresenter @@ -66,34 +58,24 @@ class MainActivity : BaseActivity(), MainVie lateinit var analytics: AnalyticsHelper @Inject - lateinit var inAppUpdateHelper: InAppUpdateHelper - - @Inject - lateinit var inAppReviewHelper: InAppReviewHelper + lateinit var updateHelper: UpdateHelper @Inject lateinit var appInfo: AppInfo - private var onBackCallback: OnBackPressedCallback? = null - - private var accountMenu: MenuItem? = null - private val overlayProvider by lazy { ElevationOverlayProvider(this) } - private val navController = - FragNavController(supportFragmentManager, R.id.main_fragment_container) - - private val captchaVerificationEvent = MutableSharedFlow() + private val navController = FragNavController(supportFragmentManager, R.id.mainFragmentContainer) companion object { + const val EXTRA_START_MENU = "extraStartMenu" - private const val EXTRA_START_DESTINATION = "start_destination_json" - - fun getStartIntent( - context: Context, - destination: Destination? = null, - ) = Intent(context, MainActivity::class.java).apply { - destination?.let { putExtra(EXTRA_START_DESTINATION, Json.encodeToString(it)) } + fun getStartIntent(context: Context, startMenu: MainView.Section? = null, clear: Boolean = false): Intent { + return Intent(context, MainActivity::class.java) + .apply { + if (clear) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK + startMenu?.let { putExtra(EXTRA_START_MENU, it.id) } + } } } @@ -101,140 +83,120 @@ class MainActivity : BaseActivity(), MainVie override val currentStackSize get() = navController.currentStack?.size - override val currentViewTitle - get() = (navController.currentFrag as? MainView.TitledView)?.titleStringId - ?.let { getString(it) } + override val currentViewTitle get() = (navController.currentFrag as? MainView.TitledView)?.titleStringId?.let { getString(it) } override val currentViewSubtitle get() = (navController.currentFrag as? MainView.TitledView)?.subtitleString - private var savedInstanceState: Bundle? = null + override var startMenuIndex = 0 + override var startMenuMoreIndex = -1 + + private val moreMenuFragments = mapOf( + MainView.Section.MESSAGE.id to MessageFragment.newInstance(), + MainView.Section.HOMEWORK.id to HomeworkFragment.newInstance(), + MainView.Section.NOTE.id to NoteFragment.newInstance(), + MainView.Section.LUCKY_NUMBER.id to LuckyNumberFragment.newInstance() + ) + + @SuppressLint("NewApi") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityMainBinding.inflate(layoutInflater).apply { binding = this }.root) setSupportActionBar(binding.mainToolbar) + messageContainer = binding.mainFragmentContainer + updateHelper.messageContainer = binding.mainFragmentContainer - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - WindowCompat.setDecorFitsSystemWindows(window, false) - binding.mainAppBar.isLifted = true + presenter.onAttachView(this, MainView.Section.values().singleOrNull { it.id == intent.getIntExtra(EXTRA_START_MENU, -1) }) + + with(navController) { + initialize(startMenuIndex, savedInstanceState) + pushFragment(moreMenuFragments[startMenuMoreIndex]) } - initializeFragmentContainer() - - this.savedInstanceState = savedInstanceState - messageContainer = binding.mainMessageContainer - messageAnchor = binding.mainMessageContainer - inAppUpdateHelper.messageContainer = binding.mainFragmentContainer - onBackCallback = onBackPressedDispatcher.addCallback(this, enabled = false) { - presenter.onBackPressed() - } - - val destination = intent.getStringExtra(EXTRA_START_DESTINATION) - ?.takeIf { savedInstanceState == null } - - presenter.onAttachView(this, destination) - inAppUpdateHelper.checkAndInstallUpdates() + updateHelper.checkAndInstallUpdates(this) } override fun onResume() { super.onResume() - inAppUpdateHelper.onResume() - presenter.updateSdkMappings() + updateHelper.onResume(this) } - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.action_menu_main, menu) - accountMenu = menu.findItem(R.id.mainMenuAccount) + @SuppressLint("NewApi") + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + updateHelper.onActivityResult(requestCode, resultCode) + if (appInfo.systemVersion >= Build.VERSION_CODES.N_MR1) initShortcuts() + } - presenter.onActionMenuCreated() + @RequiresApi(Build.VERSION_CODES.N_MR1) + fun initShortcuts() { + val shortcutsList = mutableListOf() + + listOf( + Triple(getString(R.string.grade_title), R.drawable.ic_shortcut_grade, MainView.Section.GRADE), + Triple(getString(R.string.attendance_title), R.drawable.ic_shortcut_attendance, MainView.Section.ATTENDANCE), + Triple(getString(R.string.exam_title), R.drawable.ic_shortcut_exam, MainView.Section.EXAM), + Triple(getString(R.string.timetable_title), R.drawable.ic_shortcut_timetable, MainView.Section.TIMETABLE), + Triple(getString(R.string.message_title), R.drawable.ic_shortcut_message, MainView.Section.MESSAGE) + ).forEach { (title, icon, enum) -> + shortcutsList.add(ShortcutInfo.Builder(applicationContext, title) + .setShortLabel(title) + .setLongLabel(title) + .setIcon(Icon.createWithResource(applicationContext, icon)) + .setIntents(arrayOf( + Intent(applicationContext, MainActivity::class.java).setAction(Intent.ACTION_VIEW), + Intent(applicationContext, MainActivity::class.java).putExtra(EXTRA_START_MENU, enum.id) + .setAction(Intent.ACTION_VIEW).addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK))) + .build()) + } + + getSystemService()?.dynamicShortcuts = shortcutsList + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.action_menu_main, menu) return true } - override fun initView( - startMenuIndex: Int, - rootAppMenuItems: List, - rootUpdatedDestinations: List - ) { - initializeToolbar() - initializeBottomNavigation(startMenuIndex, rootAppMenuItems) - initializeNavController(startMenuIndex, rootUpdatedDestinations) - initializeCaptchaVerificationEvent() - } + override fun initView() { + with(binding.mainToolbar) { + if (SDK_INT >= LOLLIPOP) stateListAnimator = null + setBackgroundColor(overlayProvider.compositeOverlayWithThemeSurfaceColorIfNeeded(dpToPx(4f))) + } + + with(binding.mainBottomNav) { + addItems(listOf( + AHBottomNavigationItem(R.string.grade_title, R.drawable.ic_main_grade, 0), + AHBottomNavigationItem(R.string.attendance_title, R.drawable.ic_main_attendance, 0), + AHBottomNavigationItem(R.string.exam_title, R.drawable.ic_main_exam, 0), + AHBottomNavigationItem(R.string.timetable_title, R.drawable.ic_main_timetable, 0), + AHBottomNavigationItem(R.string.more_title, R.drawable.ic_main_more, 0) + )) + accentColor = getThemeAttrColor(R.attr.colorPrimary) + inactiveColor = getThemeAttrColor(R.attr.colorOnSurface, 153) + defaultBackgroundColor = overlayProvider.compositeOverlayWithThemeSurfaceColorIfNeeded(dpToPx(8f)) + titleState = ALWAYS_SHOW + currentItem = startMenuIndex + isBehaviorTranslationEnabled = false + setTitleTextSizeInSp(10f, 10f) + setOnTabSelectedListener(presenter::onTabSelected) + } - private fun initializeNavController( - startMenuIndex: Int, - rootUpdatedDestinations: List - ) { with(navController) { - setOnViewChangeListener { destinationView -> - presenter.onViewChange(destinationView) - analytics.setCurrentScreen( - this@MainActivity, - destinationView::class.java.simpleName - ) + setOnViewChangeListener { section, name -> + analytics.setCurrentScreen(this@MainActivity, name) + presenter.onViewChange(section) } fragmentHideStrategy = HIDE - rootFragments = rootUpdatedDestinations.map { it.destinationFragment } - - initialize(startMenuIndex, savedInstanceState) - } - savedInstanceState = null - } - - private fun initializeToolbar() { - with(binding.mainToolbar) { - stateListAnimator = null - setBackgroundColor( - overlayProvider.compositeOverlayWithThemeSurfaceColorIfNeeded(dpToPx(4f)) + rootFragments = listOf( + GradeFragment.newInstance(), + AttendanceFragment.newInstance(), + ExamFragment.newInstance(), + TimetableFragment.newInstance(), + MoreFragment.newInstance() ) } } - private fun initializeBottomNavigation( - startMenuIndex: Int, - rootAppMenuItems: List - ) { - with(binding.mainBottomNav) { - with(menu) { - rootAppMenuItems.forEachIndexed { index, item -> - add(Menu.NONE, index, Menu.NONE, item.title) - .setIcon(item.icon) - } - add(Menu.NONE, 4, Menu.NONE, R.string.more_title) - .setIcon(R.drawable.ic_main_more) - } - selectedItemId = startMenuIndex - setOnItemSelectedListener { - this@MainActivity.presenter.onTabSelected(it.itemId, false) - } - setOnItemReselectedListener { - this@MainActivity.presenter.onTabSelected(it.itemId, true) - } - } - } - - private fun initializeFragmentContainer() { - ViewCompat.setOnApplyWindowInsetsListener(binding.mainFragmentContainer) { view, insets -> - val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars()) - - view.updateLayoutParams { - bottomMargin = if (binding.mainBottomNav.isVisible) 0 else bottomInsets.bottom - } - WindowInsetsCompat.CONSUMED - } - } - - override fun onPreferenceStartFragment( - caller: PreferenceFragmentCompat, - pref: Preference - ): Boolean { - val fragment = supportFragmentManager.fragmentFactory.instantiate( - classLoader, - pref.fragment.toString() - ) - pushView(fragment) - return true - } - override fun onOptionsItemSelected(item: MenuItem): Boolean { return if (item.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected() else false @@ -245,8 +207,6 @@ class MainActivity : BaseActivity(), MainVie } override fun switchMenuView(position: Int) { - if (supportFragmentManager.isStateSaved) return - analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName) navController.switchTab(position) } @@ -263,17 +223,12 @@ class MainActivity : BaseActivity(), MainVie supportActionBar?.setDisplayHomeAsUpEnabled(show) } - override fun showAccountPicker(studentWithSemesters: List) { - showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters)) + override fun showAccountPicker() { + navController.showDialogFragment(AccountDialog.newInstance()) } - override fun showBottomNavigation(show: Boolean) { - binding.mainBottomNav.isVisible = show - binding.mainFragmentContainer.requestApplyInsets() - } - - override fun openMoreDestination(destination: Destination) { - pushView(destination.destinationFragment) + override fun showActionBarElevation(show: Boolean) { + ViewCompat.setElevation(binding.mainToolbar, if (show) dpToPx(4f) else 0f) } override fun notifyMenuViewReselected() { @@ -285,81 +240,27 @@ class MainActivity : BaseActivity(), MainVie (navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentChanged() } - @Suppress("DEPRECATION") fun showDialogFragment(dialog: DialogFragment) { - if (supportFragmentManager.isStateSaved) return - - //Deprecated method is used here to avoid fragnav bug - if (navController.currentDialogFrag?.fragmentManager == null) { - FragNavController::class.java.getDeclaredField("mCurrentDialogFrag").apply { - isAccessible = true - set(navController, null) - } - } - navController.showDialogFragment(dialog) } fun pushView(fragment: Fragment) { - if (supportFragmentManager.isStateSaved) return - analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName) navController.pushFragment(fragment) - onBackCallback?.isEnabled = !isRootView } override fun popView(depth: Int) { - if (supportFragmentManager.isStateSaved) return - analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName) navController.safelyPopFragments(depth) - onBackCallback?.isEnabled = !isRootView } - override fun showStudentAvatar(student: Student) { - accountMenu?.run { - icon = createNameInitialsDrawable(student.nickOrName, student.avatarColor, 0.44f) - title = getString(R.string.main_account_picker) - } - } - - override fun showInAppReview() { - inAppReviewHelper.showInAppReview(this) - } - - override fun showAppSupport() { - MaterialAlertDialogBuilder(this) - .setTitle(R.string.main_support_title) - .setMessage(R.string.main_support_description) - .setPositiveButton(R.string.main_support_positive) { _, _ -> presenter.onEnableAdsSelected() } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .setOnDismissListener { } - .show() - } - - @OptIn(FlowPreview::class) - private fun initializeCaptchaVerificationEvent() { - captchaVerificationEvent - .debounce(1.seconds) - .onEach { url -> - Timber.d("Showing captcha dialog for: $url") - showDialogFragment(CaptchaDialog.newInstance(url)) - } - .launchIn(lifecycleScope) - } - - override fun onCaptchaVerificationRequired(url: String?) { - lifecycleScope.launch { - captchaVerificationEvent.emit(url) - } - } - - override fun showAuthDialog() { - showDialogFragment(AuthDialog.newInstance()) + override fun onBackPressed() { + presenter.onBackPressed { super.onBackPressed() } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) navController.onSaveInstanceState(outState) + intent.removeExtra(EXTRA_START_MENU) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt index 6a072718..cc525c29 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt @@ -1,105 +1,43 @@ package io.github.wulkanowy.ui.modules.main -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.WulkanowyRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.BaseView import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.account.AccountView -import io.github.wulkanowy.ui.modules.account.accountdetails.AccountDetailsView -import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView -import io.github.wulkanowy.utils.AdsHelper +import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE +import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE +import io.github.wulkanowy.ui.modules.main.MainView.Section.SCHOOL import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.AppInfo -import kotlinx.coroutines.launch -import kotlinx.serialization.json.Json import timber.log.Timber -import java.time.Duration -import java.time.Instant import javax.inject.Inject class MainPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, - private val preferencesRepository: PreferencesRepository, - private val wulkanowyRepository: WulkanowyRepository, + private val prefRepository: PreferencesRepository, private val syncManager: SyncManager, - private val analytics: AnalyticsHelper, - private val json: Json, - private val adsHelper: AdsHelper, - private val appInfo: AppInfo + private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { - private var studentsWitSemesters: List? = null - - private val rootAppMenuItems = preferencesRepository.appMenuItemOrder - .sortedBy { it.order } - .take(4) - - private val rootDestinationTypeList = rootAppMenuItems.map { it.destinationType } - .plus(Destination.Type.MORE) - - private val Destination?.startMenuIndex - get() = when { - this == null -> 0 - destinationType in rootDestinationTypeList -> { - rootDestinationTypeList.indexOf(destinationType) - } - - else -> 4 - } - - fun onAttachView(view: MainView, initDestinationJson: String?) { + fun onAttachView(view: MainView, initMenu: MainView.Section?) { super.onAttachView(view) - - val initDestination: Destination? = initDestinationJson?.let { json.decodeFromString(it) } - - val startMenuIndex = initDestination.startMenuIndex - val destinations = rootDestinationTypeList.map { - if (it == initDestination?.destinationType) initDestination else it.defaultDestination - } - - view.initView(startMenuIndex, rootAppMenuItems, destinations) - if (initDestination != null && startMenuIndex == 4) { - view.openMoreDestination(initDestination) + view.apply { + getProperViewIndexes(initMenu).let { (main, more) -> + startMenuIndex = main + startMenuMoreIndex = more + } + initView() + Timber.i("Main view was initialized with $startMenuIndex menu index and $startMenuMoreIndex more index") } syncManager.startPeriodicSyncWorker() - - checkAppSupport() - updateCurrentStudentAuthStatus() - - analytics.logEvent("app_open", "destination" to initDestination.toString()) - Timber.i("Main view was initialized with $initDestination") + analytics.logEvent("app_open", "destination" to initMenu?.name) } - fun onActionMenuCreated() { - if (!studentsWitSemesters.isNullOrEmpty()) { - showCurrentStudentAvatar() - return - } - - resourceFlow { studentRepository.getSavedStudents(false) } - .logResourceStatus("load student avatar") - .onResourceSuccess { - studentsWitSemesters = it - showCurrentStudentAvatar() - } - .onResourceError(errorHandler::dispatch) - .launch("avatar") - } - - fun onViewChange(destinationView: BaseView) { + fun onViewChange(section: MainView.Section?) { view?.apply { - showBottomNavigation(shouldShowBottomNavigation(destinationView)) + showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL) currentViewTitle?.let { setViewTitle(it) } currentViewSubtitle?.let { setViewSubTitle(it.ifBlank { null }) } currentStackSize?.let { @@ -109,19 +47,9 @@ class MainPresenter @Inject constructor( } } - private fun shouldShowBottomNavigation(destination: BaseView) = when (destination) { - is AccountView, - is StudentInfoView, - is AccountDetailsView -> false - - else -> true - } - fun onAccountManagerSelected(): Boolean { - if (studentsWitSemesters.isNullOrEmpty()) return true - Timber.i("Select account manager") - view?.showAccountPicker(studentsWitSemesters!!) + view?.showAccountPicker() return true } @@ -131,9 +59,12 @@ class MainPresenter @Inject constructor( return true } - fun onBackPressed() { + fun onBackPressed(default: () -> Unit) { Timber.i("Back pressed in main view") - view?.popView() + view?.run { + if (isRootView) default() + else popView() + } } fun onTabSelected(index: Int, wasSelected: Boolean): Boolean { @@ -145,67 +76,16 @@ class MainPresenter @Inject constructor( } else { notifyMenuViewChanged() switchMenuView(index) - checkInAppReview() true } } == true } - fun onEnableAdsSelected() { - preferencesRepository.isAdsEnabled = true - adsHelper.initialize() - } - - private fun checkInAppReview() { - preferencesRepository.inAppReviewCount++ - - if (preferencesRepository.inAppReviewDate == null) { - preferencesRepository.inAppReviewDate = Instant.now() - } - - if (!preferencesRepository.isAppReviewDone && preferencesRepository.inAppReviewCount >= 50 && - Instant.now().minus(Duration.ofDays(14)).isAfter(preferencesRepository.inAppReviewDate) - ) { - view?.showInAppReview() - preferencesRepository.isAppReviewDone = true - } - } - - private fun checkAppSupport() { - if (!preferencesRepository.isAppSupportShown && !preferencesRepository.isAdsEnabled - && appInfo.buildFlavor == "play" - ) { - presenterScope.launch { - val student = runCatching { studentRepository.getCurrentStudent(false) } - .onFailure { Timber.e(it) } - .getOrElse { return@launch } - - if (Instant.now().minus(Duration.ofDays(28)).isAfter(student.registrationDate)) { - preferencesRepository.isAppSupportShown = true - view?.showAppSupport() - } - } - } - } - - private fun showCurrentStudentAvatar() { - val currentStudent = - studentsWitSemesters?.singleOrNull { it.student.isCurrent }?.student ?: return - - view?.showStudentAvatar(currentStudent) - } - - private fun updateCurrentStudentAuthStatus() { - presenterScope.launch { - runCatching { studentRepository.updateCurrentStudentAuthStatus() } - .onFailure { errorHandler.dispatch(it) } - } - } - - fun updateSdkMappings() { - presenterScope.launch { - runCatching { wulkanowyRepository.fetchMapping() } - .onFailure { Timber.e(it) } + private fun getProperViewIndexes(initMenu: MainView.Section?): Pair { + return when (initMenu?.id) { + in 0..3 -> initMenu!!.id to -1 + in 4..10 -> 4 to initMenu!!.id + else -> prefRepository.startMenuIndex to -1 } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt index 70a94fc8..97b556e3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainView.kt @@ -1,13 +1,13 @@ package io.github.wulkanowy.ui.modules.main -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.db.entities.StudentWithSemesters import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.settings.appearance.menuorder.AppMenuItem interface MainView : BaseView { + var startMenuIndex: Int + + var startMenuMoreIndex: Int + val isRootView: Boolean val currentViewTitle: String? @@ -16,19 +16,15 @@ interface MainView : BaseView { val currentStackSize: Int? - fun initView( - startMenuIndex: Int, - rootAppMenuItems: List, - rootUpdatedDestinations: List - ) + fun initView() fun switchMenuView(position: Int) fun showHomeArrow(show: Boolean) - fun showAccountPicker(studentWithSemesters: List) + fun showAccountPicker() - fun showBottomNavigation(show: Boolean) + fun showActionBarElevation(show: Boolean) fun notifyMenuViewReselected() @@ -40,14 +36,6 @@ interface MainView : BaseView { fun popView(depth: Int = 1) - fun showStudentAvatar(student: Student) - - fun showInAppReview() - - fun showAppSupport() - - fun openMoreDestination(destination: Destination) - interface MainChildView { fun onFragmentReselected() @@ -63,4 +51,19 @@ interface MainView : BaseView { get() = "" set(_) {} } + + enum class Section(val id: Int) { + GRADE(0), + ATTENDANCE(1), + EXAM(2), + TIMETABLE(3), + MORE(4), + MESSAGE(5), + HOMEWORK(6), + NOTE(7), + LUCKY_NUMBER(8), + SETTINGS(9), + ABOUT(10), + SCHOOL(11) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt index 02bc13a1..16e0184a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageFragment.kt @@ -4,20 +4,14 @@ import android.os.Bundle import android.view.View import android.view.View.INVISIBLE import android.view.View.VISIBLE -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.core.view.updateLayoutParams -import androidx.core.view.updateMargins -import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED -import io.github.wulkanowy.data.enums.MessageFolder.SENT -import io.github.wulkanowy.data.enums.MessageFolder.TRASHED +import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED +import io.github.wulkanowy.data.repositories.message.MessageFolder.SENT +import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED import io.github.wulkanowy.databinding.FragmentMessageBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter -import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment @@ -27,18 +21,12 @@ import javax.inject.Inject @AndroidEntryPoint class MessageFragment : BaseFragment(R.layout.fragment_message), - MessageView, MainView.TitledView, MainView.MainChildView { + MessageView, MainView.TitledView { @Inject lateinit var presenter: MessagePresenter - private val pagerAdapter by lazy { - BaseFragmentPagerAdapter( - fragmentManager = childFragmentManager, - pagesCount = 3, - lifecycle = lifecycle, - ) - } + private val pagerAdapter by lazy { BaseFragmentPagerAdapter(childFragmentManager) } companion object { fun newInstance() = MessageFragment() @@ -51,39 +39,30 @@ class MessageFragment : BaseFragment(R.layout.fragment_m override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentMessageBinding.bind(view) - messageContainer = binding.messageViewPager presenter.onAttachView(this) } override fun initView() { + with(pagerAdapter) { + containerId = binding.messageViewPager.id + addFragmentsWithTitle(mapOf( + MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox), + MessageTabFragment.newInstance(SENT) to getString(R.string.message_sent), + MessageTabFragment.newInstance(TRASHED) to getString(R.string.message_trash) + )) + } + with(binding.messageViewPager) { adapter = pagerAdapter offscreenPageLimit = 2 setOnSelectPageListener(presenter::onPageSelected) } - with(pagerAdapter) { - containerId = binding.messageViewPager.id - titleFactory = { - when (it) { - 0 -> getString(R.string.message_inbox) - 1 -> getString(R.string.message_sent) - 2 -> getString(R.string.message_trash) - else -> throw IllegalStateException() - } - } - itemFactory = { - when (it) { - 0 -> MessageTabFragment.newInstance(RECEIVED) - 1 -> MessageTabFragment.newInstance(SENT) - 2 -> MessageTabFragment.newInstance(TRASHED) - else -> throw IllegalStateException() - } - } - TabLayoutMediator(binding.messageTabLayout, binding.messageViewPager, this).attach() + with(binding.messageTabLayout) { + setupWithViewPager(binding.messageViewPager) + setElevationCompat(context.dpToPx(4f)) } - binding.messageTabLayout.elevation = requireContext().dpToPx(4f) binding.openSendMessageButton.setOnClickListener { presenter.onSendMessageButtonClicked() } } @@ -98,72 +77,22 @@ class MessageFragment : BaseFragment(R.layout.fragment_m binding.messageProgress.visibility = if (show) VISIBLE else INVISIBLE } - override fun showMessage(messageId: Int) { - showMessage(getString(messageId)) - } - - override fun showNewMessage(show: Boolean) { - binding.openSendMessageButton.run { - if (show) show() else hide() - } - } - - override fun showTabLayout(show: Boolean) { - binding.messageTabLayout.isVisible = show - - with(binding.messageViewPager) { - isUserInputEnabled = show - updateLayoutParams { - updateMargins(top = if (show) requireContext().dpToPx(48f).toInt() else 0) - } - } - } - - fun onChildFragmentShowActionMode(show: Boolean) { - presenter.onChildViewShowActionMode(show) - } - fun onChildFragmentLoaded() { presenter.onChildViewLoaded() } - fun onChildFragmentShowNewMessage(show: Boolean) { - presenter.onChildViewShowNewMessage(show) - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onFragmentReselected() - } - - override fun onFragmentChanged() { - if (::presenter.isInitialized) presenter.onFragmentChanged() + override fun notifyChildMessageDeleted(tabId: Int) { + (pagerAdapter.getFragmentInstance(tabId) as? MessageTabFragment)?.onParentDeleteMessage() } override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) { - (pagerAdapter.getFragmentInstance(index) as? MessageTabFragment) - ?.onParentLoadData(forceRefresh) - } - - override fun notifyChildrenFinishActionMode() { - repeat(3) { - (pagerAdapter.getFragmentInstance(it) as? MessageTabFragment) - ?.onParentFinishActionMode() - } - } - - override fun notifyChildParentReselected(index: Int) { - (pagerAdapter.getFragmentInstance(index) as? MessageTabFragment) - ?.onParentReselected() + (pagerAdapter.getFragmentInstance(index) as? MessageTabFragment)?.onParentLoadData(forceRefresh) } override fun openSendMessage() { context?.let { it.startActivity(SendMessageActivity.getStartIntent(it)) } } - override fun popView() { - (activity as? MainActivity)?.popView() - } - override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt index 37a2d422..0fb454b3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessagePresenter.kt @@ -1,40 +1,30 @@ package io.github.wulkanowy.ui.modules.message -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject class MessagePresenter @Inject constructor( errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val preferencesRepository: PreferencesRepository, + studentRepository: StudentRepository ) : BasePresenter(errorHandler, studentRepository) { override fun onAttachView(view: MessageView) { super.onAttachView(view) - presenterScope.launch { + launch { + delay(150) view.initView() Timber.i("Message view was initialized") loadData() } - - showIncognitoModeReminderMessage() - } - - private fun showIncognitoModeReminderMessage() { - if (preferencesRepository.isIncognitoMode) { - view?.showMessage(R.string.message_incognito_mode_on) - } } fun onPageSelected(index: Int) { loadChild(index) - view?.notifyChildrenFinishActionMode() } private fun loadData() { @@ -46,18 +36,6 @@ class MessagePresenter @Inject constructor( view?.notifyChildLoadData(index, forceRefresh) } - fun onFragmentChanged() { - view?.notifyChildrenFinishActionMode() - } - - fun onFragmentReselected() { - Timber.i("Message view is reselected") - view?.run { - popView() - notifyChildParentReselected(currentPageIndex) - } - } - fun onChildViewLoaded() { view?.apply { showContent(true) @@ -65,14 +43,6 @@ class MessagePresenter @Inject constructor( } } - fun onChildViewShowNewMessage(show: Boolean) { - view?.showNewMessage(show) - } - - fun onChildViewShowActionMode(show: Boolean) { - view?.showTabLayout(!show) - } - fun onSendMessageButtonClicked() { view?.openSendMessage() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt index 7fdc6e18..2aa4d78e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/MessageView.kt @@ -1,6 +1,5 @@ package io.github.wulkanowy.ui.modules.message -import androidx.annotation.StringRes import io.github.wulkanowy.ui.base.BaseView interface MessageView : BaseView { @@ -13,19 +12,9 @@ interface MessageView : BaseView { fun showProgress(show: Boolean) - fun showMessage(@StringRes messageId: Int) - - fun showNewMessage(show: Boolean) - - fun showTabLayout(show: Boolean) - fun notifyChildLoadData(index: Int, forceRefresh: Boolean) - fun notifyChildrenFinishActionMode() - - fun notifyChildParentReselected(index: Int) + fun notifyChildMessageDeleted(tabId: Int) fun openSendMessage() - - fun popView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt deleted file mode 100644 index 59f6d288..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt +++ /dev/null @@ -1,81 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.mailboxchooser - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.DiffUtil.ItemCallback -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.MailboxType -import io.github.wulkanowy.databinding.ItemMailboxChooserBinding -import javax.inject.Inject - -class MailboxChooserAdapter @Inject constructor() : - ListAdapter(Differ) { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( - ItemMailboxChooserBinding.inflate( - LayoutInflater.from(parent.context), parent, false - ) - ) - - override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - holder.bind(getItem(position)) - } - - class ItemViewHolder( - private val binding: ItemMailboxChooserBinding, - ) : RecyclerView.ViewHolder(binding.root) { - - fun bind(item: MailboxChooserItem) { - with(binding) { - mailboxItemName.text = item.mailbox?.getFirstLine() - ?: root.resources.getString(R.string.message_chip_all_mailboxes) - mailboxItemSchool.text = item.mailbox?.getSecondLine() - mailboxItemSchool.isVisible = !item.isAll - - root.setOnClickListener { item.onClickListener(item.mailbox) } - } - } - - private fun Mailbox.getFirstLine() = buildString { - if (studentName.isNotBlank() && studentName != userName) { - append(studentName) - append(" - ") - } - append(userName) - } - - private fun Mailbox.getSecondLine() = buildString { - append(schoolNameShort) - append(" - ") - append(getMailboxType(type)) - } - - private fun getMailboxType(type: MailboxType): String = when (type) { - MailboxType.STUDENT -> R.string.message_mailbox_type_student - MailboxType.PARENT -> R.string.message_mailbox_type_parent - MailboxType.GUARDIAN -> R.string.message_mailbox_type_guardian - MailboxType.EMPLOYEE -> R.string.message_mailbox_type_employee - MailboxType.UNKNOWN -> null - }.let { it?.let { it1 -> binding.root.resources.getString(it1) }.orEmpty() } - } - - private object Differ : ItemCallback() { - override fun areItemsTheSame( - oldItem: MailboxChooserItem, - newItem: MailboxChooserItem - ): Boolean { - return oldItem.mailbox?.globalKey == newItem.mailbox?.globalKey - } - - override fun areContentsTheSame( - oldItem: MailboxChooserItem, - newItem: MailboxChooserItem - ): Boolean { - return oldItem == newItem - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt deleted file mode 100644 index 11d3c6c1..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt +++ /dev/null @@ -1,74 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.mailboxchooser - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.fragment.app.setFragmentResult -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.databinding.DialogMailboxChooserBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.parcelableArray -import javax.inject.Inject - -@AndroidEntryPoint -class MailboxChooserDialog : BaseDialogFragment(), MailboxChooserView { - - @Inject - lateinit var presenter: MailboxChooserPresenter - - @Inject - lateinit var mailboxAdapter: MailboxChooserAdapter - - companion object { - const val LISTENER_KEY = "mailbox_selected" - const val MAILBOX_KEY = "selected_mailbox" - const val REQUIRED_KEY = "is_mailbox_required" - - fun newInstance(mailboxes: List, isMailboxRequired: Boolean, folder: String) = - MailboxChooserDialog().apply { - arguments = bundleOf( - MAILBOX_KEY to mailboxes.toTypedArray(), - REQUIRED_KEY to isMailboxRequired, - LISTENER_KEY to folder, - ) - } - } - - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogMailboxChooserBinding.inflate(layoutInflater).apply { binding = this }.root - ) - .create() - } - - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView( - view = this, - requireMailbox = requireArguments().getBoolean(REQUIRED_KEY, false), - mailboxes = requireArguments().parcelableArray(MAILBOX_KEY).orEmpty().toList(), - ) - } - - override fun initView() { - binding.accountQuickDialogRecycler.adapter = mailboxAdapter - } - - override fun submitData(items: List) { - mailboxAdapter.submitList(items) - } - - override fun onMailboxSelected(item: Mailbox?) { - setFragmentResult( - requestKey = requireArguments().getString(LISTENER_KEY).orEmpty(), - result = bundleOf(MAILBOX_KEY to item), - ) - dismiss() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt deleted file mode 100644 index 6923cf08..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.mailboxchooser - -import io.github.wulkanowy.data.db.entities.Mailbox - -data class MailboxChooserItem( - val mailbox: Mailbox? = null, - val isAll: Boolean = false, - val onClickListener: (Mailbox?) -> Unit, -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt deleted file mode 100644 index 5bd7c84a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt +++ /dev/null @@ -1,38 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.mailboxchooser - -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import timber.log.Timber -import javax.inject.Inject - -class MailboxChooserPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository -) : BasePresenter(errorHandler, studentRepository) { - - fun onAttachView(view: MailboxChooserView, mailboxes: List, requireMailbox: Boolean) { - super.onAttachView(view) - - view.initView() - Timber.i("Mailbox chooser view was initialized") - view.submitData(getMailboxItems(mailboxes, requireMailbox)) - } - - private fun getMailboxItems( - mailboxes: List, - requireMailbox: Boolean, - ): List = buildList { - if (!requireMailbox) { - add(MailboxChooserItem(isAll = true, onClickListener = ::onMailboxSelect)) - } - addAll(mailboxes.map { - MailboxChooserItem(mailbox = it, isAll = false, onClickListener = ::onMailboxSelect) - }) - } - - fun onMailboxSelect(item: Mailbox?) { - view?.onMailboxSelected(item) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt deleted file mode 100644 index 2e20ee81..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.mailboxchooser - -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.ui.base.BaseView - -interface MailboxChooserView : BaseView { - - fun initView() - - fun submitData(items: List) - - fun onMailboxSelected(item: Mailbox?) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt index b83f7e23..206a7460 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt @@ -1,10 +1,9 @@ package io.github.wulkanowy.ui.modules.message.preview +import android.annotation.SuppressLint import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT -import androidx.core.text.parseAsHtml import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Message @@ -34,8 +33,7 @@ class MessagePreviewAdapter @Inject constructor() : private var attachments: List = emptyList() - override fun getItemCount() = - if (messageWithAttachment == null) 0 else attachments.size + 1 + if (attachments.isNotEmpty()) 1 else 0 + override fun getItemCount() = if (messageWithAttachment == null) 0 else attachments.size + 1 + if (attachments.isNotEmpty()) 1 else 0 override fun getItemViewType(position: Int) = when (position) { 0 -> ViewType.MESSAGE.id @@ -47,65 +45,28 @@ class MessagePreviewAdapter @Inject constructor() : val inflater = LayoutInflater.from(parent.context) return when (viewType) { - ViewType.MESSAGE.id -> MessageViewHolder( - ItemMessagePreviewBinding.inflate(inflater, parent, false) - ) - - ViewType.DIVIDER.id -> DividerViewHolder( - ItemMessageDividerBinding.inflate(inflater, parent, false) - ) - - ViewType.ATTACHMENT.id -> AttachmentViewHolder( - ItemMessageAttachmentBinding.inflate(inflater, parent, false) - ) - + ViewType.MESSAGE.id -> MessageViewHolder(ItemMessagePreviewBinding.inflate(inflater, parent, false)) + ViewType.DIVIDER.id -> DividerViewHolder(ItemMessageDividerBinding.inflate(inflater, parent, false)) + ViewType.ATTACHMENT.id -> AttachmentViewHolder(ItemMessageAttachmentBinding.inflate(inflater, parent, false)) else -> throw IllegalStateException() } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { - is MessageViewHolder -> bindMessage( - holder, - requireNotNull(messageWithAttachment).message - ) - - is AttachmentViewHolder -> bindAttachment( - holder, - requireNotNull(messageWithAttachment).attachments[position - 2] - ) + is MessageViewHolder -> bindMessage(holder, requireNotNull(messageWithAttachment).message) + is AttachmentViewHolder -> bindAttachment(holder, requireNotNull(messageWithAttachment).attachments[position - 2]) } } + @SuppressLint("SetTextI18n") private fun bindMessage(holder: MessageViewHolder, message: Message) { - val context = holder.binding.root.context - val recipientCount = (message.unreadBy ?: 0) + (message.readBy ?: 0) - val isReceived = message.unreadBy == null - - val readText = when { - recipientCount > 1 -> { - context.getString(R.string.message_read_by, message.readBy, recipientCount) - } - - message.readBy == 1 || (isReceived && !message.unread) -> { - context.getString(R.string.message_read, context.getString(R.string.all_yes)) - } - - else -> context.getString(R.string.message_read, context.getString(R.string.all_no)) - } - with(holder.binding) { - messagePreviewSubject.text = message.subject.ifBlank { - context.getString(R.string.message_no_subject) - } - messagePreviewDate.text = context.getString( - R.string.message_date, - message.date.toFormattedString("yyyy-MM-dd HH:mm:ss") - ) - messagePreviewRead.text = readText - messagePreviewContent.text = message.content.parseAsHtml(FROM_HTML_MODE_COMPACT) + messagePreviewSubject.text = message.subject.ifBlank { root.context.getString(R.string.message_no_subject) } + messagePreviewDate.text = root.context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")) + messagePreviewContent.text = message.content messagePreviewFromSender.text = message.sender - messagePreviewToRecipient.text = message.recipients + messagePreviewToRecipient.text = message.recipient } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt index 8e7c7276..b35731ca 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.message.preview +import android.os.Build import android.os.Bundle import android.print.PrintAttributes import android.print.PrintManager @@ -12,9 +13,8 @@ import android.view.View.VISIBLE import android.webkit.WebResourceRequest import android.webkit.WebView import android.webkit.WebViewClient -import androidx.annotation.StringRes +import androidx.annotation.RequiresApi import androidx.core.content.getSystemService -import androidx.core.os.bundleOf import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R @@ -25,7 +25,7 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity -import io.github.wulkanowy.utils.serializable +import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.shareText import javax.inject.Inject @@ -40,56 +40,41 @@ class MessagePreviewFragment : @Inject lateinit var previewAdapter: MessagePreviewAdapter + @Inject + lateinit var appInfo: AppInfo + private var menuReplyButton: MenuItem? = null private var menuForwardButton: MenuItem? = null - private var menuRestoreButton: MenuItem? = null - private var menuDeleteButton: MenuItem? = null - private var menuDeleteForeverButton: MenuItem? = null - private var menuShareButton: MenuItem? = null private var menuPrintButton: MenuItem? = null - private var menuMuteButton: MenuItem? = null - override val titleStringId: Int get() = R.string.message_title override val deleteMessageSuccessString: String get() = getString(R.string.message_delete_success) - override val muteMessageSuccessString: String - get() = getString(R.string.message_mute_success) - - override val unmuteMessageSuccessString: String - get() = getString(R.string.message_unmute_success) - - override val restoreMessageSuccessString: String - get() = getString(R.string.message_restore_success) - override val messageNoSubjectString: String get() = getString(R.string.message_no_subject) override val printHTML: String - get() = requireContext().assets.open("message-print-page.html").bufferedReader() - .use { it.readText() } - - override val messageNotExists: String - get() = getString(R.string.message_not_exists) + get() = requireContext().assets.open("message-print-page.html").bufferedReader().use { it.readText() } companion object { - private const val MESSAGE_ARG_KEY = "message" + const val MESSAGE_ID_KEY = "message_id" - fun newInstance(message: Message) = MessagePreviewFragment().apply { - arguments = bundleOf(MESSAGE_ARG_KEY to message) + fun newInstance(message: Message): MessagePreviewFragment { + return MessagePreviewFragment().apply { + arguments = Bundle().apply { putSerializable(MESSAGE_ID_KEY, message) } + } } } - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -99,10 +84,7 @@ class MessagePreviewFragment : super.onViewCreated(view, savedInstanceState) binding = FragmentMessagePreviewBinding.bind(view) messageContainer = binding.messagePreviewContainer - presenter.onAttachView( - view = this, - message = requireArguments().serializable(MESSAGE_ARG_KEY), - ) + presenter.onAttachView(this, (savedInstanceState ?: arguments)?.getSerializable(MESSAGE_ID_KEY) as? Message) } override fun initView() { @@ -118,27 +100,19 @@ class MessagePreviewFragment : inflater.inflate(R.menu.action_menu_message_preview, menu) menuReplyButton = menu.findItem(R.id.messagePreviewMenuReply) menuForwardButton = menu.findItem(R.id.messagePreviewMenuForward) - menuRestoreButton = menu.findItem(R.id.messagePreviewMenuRestore) menuDeleteButton = menu.findItem(R.id.messagePreviewMenuDelete) - menuDeleteForeverButton = menu.findItem(R.id.messagePreviewMenuDeleteForever) menuShareButton = menu.findItem(R.id.messagePreviewMenuShare) menuPrintButton = menu.findItem(R.id.messagePreviewMenuPrint) - menuMuteButton = menu.findItem(R.id.messagePreviewMenuMute) presenter.onCreateOptionsMenu() - - menu.findItem(R.id.mainMenuAccount).isVisible = false } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.messagePreviewMenuReply -> presenter.onReply() R.id.messagePreviewMenuForward -> presenter.onForward() - R.id.messagePreviewMenuRestore -> presenter.onMessageRestore() R.id.messagePreviewMenuDelete -> presenter.onMessageDelete() - R.id.messagePreviewMenuDeleteForever -> presenter.onMessageDelete() R.id.messagePreviewMenuShare -> presenter.onShare() R.id.messagePreviewMenuPrint -> presenter.onPrint() - R.id.messagePreviewMenuMute -> presenter.onMute() else -> false } } @@ -150,11 +124,6 @@ class MessagePreviewFragment : } } - override fun updateMuteToggleButton(isMuted: Boolean) { - menuMuteButton?.setTitle(if (isMuted) R.string.message_unmute else R.string.message_mute) - - } - override fun showProgress(show: Boolean) { binding.messagePreviewProgress.visibility = if (show) VISIBLE else GONE } @@ -163,15 +132,20 @@ class MessagePreviewFragment : binding.messagePreviewRecycler.visibility = if (show) VISIBLE else GONE } - override fun showOptions(show: Boolean, isReplayable: Boolean, isRestorable: Boolean) { - menuReplyButton?.isVisible = show && isReplayable + override fun showOptions(show: Boolean) { + menuReplyButton?.isVisible = show menuForwardButton?.isVisible = show - menuRestoreButton?.isVisible = show && isRestorable - menuDeleteButton?.isVisible = show && !isRestorable - menuDeleteForeverButton?.isVisible = show && isRestorable + menuDeleteButton?.isVisible = show menuShareButton?.isVisible = show - menuPrintButton?.isVisible = show - menuMuteButton?.isVisible = show && isReplayable + menuPrintButton?.isVisible = show && appInfo.systemVersion >= Build.VERSION_CODES.LOLLIPOP + } + + override fun setDeletedOptionsLabels() { + menuDeleteButton?.setTitle(R.string.message_delete_forever) + } + + override fun setNotDeletedOptionsLabels() { + menuDeleteButton?.setTitle(R.string.message_move_to_bin) } override fun showErrorView(show: Boolean) { @@ -186,10 +160,6 @@ class MessagePreviewFragment : binding.messagePreviewErrorRetry.setOnClickListener { callback() } } - override fun showMessage(@StringRes messageId: Int) { - showMessage(getString(messageId)) - } - override fun openMessageReply(message: Message?) { context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message, true)) } } @@ -202,12 +172,12 @@ class MessagePreviewFragment : context?.shareText(text, subject) } + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) override fun printDocument(html: String, jobName: String) { val webView = WebView(requireContext()) webView.webViewClient = object : WebViewClient() { - override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = - false + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false override fun onPageFinished(view: WebView, url: String) { createWebPrintJob(view, jobName) @@ -217,6 +187,7 @@ class MessagePreviewFragment : webView.loadDataWithBaseURL("file:///android_asset/", html, "text/HTML", "UTF-8", null) } + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) private fun createWebPrintJob(webView: WebView, jobName: String) { activity?.getSystemService()?.let { printManager -> val printAdapter = webView.createPrintDocumentAdapter(jobName) @@ -233,6 +204,11 @@ class MessagePreviewFragment : (activity as MainActivity).popView() } + override fun onSaveInstanceState(outState: Bundle) { + outState.putSerializable(MESSAGE_ID_KEY, presenter.message) + super.onSaveInstanceState(outState) + } + override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt index 3b3b2b42..039c7f14 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt @@ -1,49 +1,47 @@ package io.github.wulkanowy.ui.modules.message.preview import android.annotation.SuppressLint -import androidx.core.text.parseAsHtml -import io.github.wulkanowy.R +import android.os.Build +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.db.entities.MessageWithAttachment -import io.github.wulkanowy.data.enums.MessageFolder -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.db.entities.MessageAttachment +import io.github.wulkanowy.data.repositories.message.MessageFolder +import io.github.wulkanowy.data.repositories.message.MessageRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.toFormattedString -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject -import kotlin.time.Duration.Companion.seconds class MessagePreviewPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, private val messageRepository: MessageRepository, - private val preferencesRepository: PreferencesRepository, - private val analytics: AnalyticsHelper + private val analytics: AnalyticsHelper, + private var appInfo: AppInfo ) : BasePresenter(errorHandler, studentRepository) { - private var messageWithAttachments: MessageWithAttachment? = null + var message: Message? = null + + var attachments: List? = null private lateinit var lastError: Throwable private var retryCallback: () -> Unit = {} - fun onAttachView(view: MessagePreviewView, message: Message) { + fun onAttachView(view: MessagePreviewView, message: Message?) { super.onAttachView(view) view.initView() errorHandler.showErrorMessage = ::showErrorViewOnError - loadData(message) + this.message = message + loadData(requireNotNull(message)) } private fun onMessageLoadRetry(message: Message) { @@ -58,194 +56,139 @@ class MessagePreviewPresenter @Inject constructor( view?.showErrorDetailsDialog(lastError) } - private fun loadData(messageToLoad: Message) { - flatResourceFlow { - val student = studentRepository.getCurrentStudent() - messageRepository.getMessage( - student = student, - message = messageToLoad, - markAsRead = !preferencesRepository.isIncognitoMode, - ) - } - .logResourceStatus("message ${messageToLoad.messageId} preview") - .onResourceData { - if (it != null) { - messageWithAttachments = it + private fun loadData(message: Message) { + flowWithResourceIn { + val student = studentRepository.getStudentById(message.studentId) + messageRepository.getMessage(student, message, true) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading message ${message.messageId} preview started") + Status.SUCCESS -> { + Timber.i("Loading message ${message.messageId} preview result: Success ") + checkNotNull(it.data, { "Can't find message in local db! Probably no longer exist in this folder" }) + this@MessagePreviewPresenter.message = it.data.message + this@MessagePreviewPresenter.attachments = it.data.attachments view?.apply { - setMessageWithAttachment(it) - showContent(true) + setMessageWithAttachment(it.data) initOptions() - updateMuteToggleButton(isMuted = it.mutedMessageSender != null) - if (preferencesRepository.isIncognitoMode && it.message.unread) { - showMessage(R.string.message_incognito_description) - } } - } else { - delay(1.seconds) - view?.run { - showMessage(messageNotExists) - popView() - } - } - }.onResourceSuccess { - if (it != null) { analytics.logEvent( "load_item", "type" to "message_preview", - "length" to it.message.content.length + "length" to it.data.message.content.length ) } - }.onResourceNotLoading { view?.showProgress(false) }.onResourceError { - retryCallback = { onMessageLoadRetry(messageToLoad) } - errorHandler.dispatch(it) - }.launch() + Status.ERROR -> { + Timber.i("Loading message ${message.messageId} preview result: An exception occurred ") + retryCallback = { onMessageLoadRetry(message) } + errorHandler.dispatch(it.error!!) + } + } + }.afterLoading { + view?.showProgress(false) + }.launch() } fun onReply(): Boolean { - return if (messageWithAttachments?.message != null) { - view?.openMessageReply(messageWithAttachments?.message) + return if (message != null) { + view?.openMessageReply(message) true } else false } fun onForward(): Boolean { - return if (messageWithAttachments?.message != null) { - view?.openMessageForward(messageWithAttachments?.message) + return if (message != null) { + view?.openMessageForward(message) true } else false } fun onShare(): Boolean { - val message = messageWithAttachments?.message ?: return false - val subject = message.subject.ifBlank { view?.messageNoSubjectString.orEmpty() } + message?.let { + var text = "Temat: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}\n" + when (it.sender.isNotEmpty()) { + true -> "Od: ${it.sender}\n" + false -> "Do: ${it.recipient}\n" + } + "Data: ${it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${it.content}" - val text = buildString { - appendLine("Temat: $subject") - appendLine("Od: ${message.sender}") - appendLine("Do: ${message.recipients}") - appendLine("Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}") + attachments?.let { attachments -> + if (attachments.isNotEmpty()) { + text += "\n\nZałączniki:" - appendLine() - - appendLine(message.content.parseAsHtml()) - - if (!messageWithAttachments?.attachments.isNullOrEmpty()) { - appendLine() - appendLine("Załączniki:") - - append( - messageWithAttachments?.attachments.orEmpty() - .joinToString(separator = "\n") { attachment -> - "${attachment.filename}: ${attachment.url}" - }) + attachments.forEach { attachment -> + text += "\n${attachment.filename}: ${attachment.url}" + } + } } - } - view?.shareText( - subject = "FW: $subject", - text = text, - ) - return true + view?.shareText(text, "FW: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}") + return true + } + return false } @SuppressLint("NewApi") fun onPrint(): Boolean { - val message = messageWithAttachments?.message ?: return false - val subject = message.subject.ifBlank { view?.messageNoSubjectString.orEmpty() } - - val dateString = message.date.toFormattedString("yyyy-MM-dd HH:mm:ss") - - val infoContent = buildString { - append("

Data wysłania

$dateString
") - - append("

Od

${message.sender}
") - append("

DO

${message.recipients}
") - } - val messageContent = "

${message.content}

".replace(Regex("[\\n\\r]{2,}"), "

") - .replace(Regex("[\\n\\r]"), "
") - - val jobName = buildString { - append("Wiadomość ") - append("od ${message.correspondents}") - append("do ${message.correspondents}") - append(" $dateString: $subject | Wulkanowy") - } - - view?.apply { - val html = printHTML.replace("%SUBJECT%", subject).replace("%CONTENT%", messageContent) - .replace("%INFO%", infoContent) - printDocument(html, jobName) - } - - return true - } - - private fun restoreMessage() { - val message = messageWithAttachments?.message ?: return - - view?.run { - showContent(false) - showProgress(true) - showOptions( - show = false, - isReplayable = false, - isRestorable = false, - ) - showErrorView(false) - } - Timber.i("Restore message ${message.messageGlobalKey}") - presenterScope.launch { - runCatching { - val student = studentRepository.getCurrentStudent(decryptPass = true) - val mailbox = messageRepository.getMailboxByStudent(student) - messageRepository.restoreMessages(student, mailbox, listOfNotNull(message)) + if (appInfo.systemVersion < Build.VERSION_CODES.LOLLIPOP) return false + message?.let { + val dateString = it.date.toFormattedString("yyyy-MM-dd HH:mm:ss") + val infoContent = "

Data wysłania

$dateString
" + when { + it.sender.isNotEmpty() -> "

Od

${it.sender}
" + else -> "

Do

${it.recipient}
" } - .onFailure { - retryCallback = { onMessageRestore() } - errorHandler.dispatch(it) - } - .onSuccess { - view?.run { - showMessage(restoreMessageSuccessString) - popView() - } - } - view?.showProgress(false) + + val messageContent = "

${it.content}

" + .replace(Regex("[\\n\\r]{2,}"), "

") + .replace(Regex("[\\n\\r]"), "
") + + val jobName = "Wiadomość " + when { + it.sender.isNotEmpty() -> "od ${it.sender}" + else -> "do ${it.recipient}" + } + " $dateString: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }} | Wulkanowy" + + view?.apply { + val html = printHTML + .replace("%SUBJECT%", it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }) + .replace("%CONTENT%", messageContent) + .replace("%INFO%", infoContent) + printDocument(html, jobName) + } + return true } + return false } private fun deleteMessage() { - messageWithAttachments?.message ?: return + message ?: return view?.run { showContent(false) showProgress(true) - showOptions( - show = false, - isReplayable = false, - isRestorable = false, - ) + showOptions(false) showErrorView(false) } - Timber.i("Delete message ${messageWithAttachments?.message?.messageGlobalKey}") - - presenterScope.launch { - runCatching { - val student = studentRepository.getCurrentStudent(decryptPass = true) - messageRepository.deleteMessage(student, messageWithAttachments?.message!!) - }.onFailure { - retryCallback = { onMessageDelete() } - errorHandler.dispatch(it) - }.onSuccess { - view?.run { - showMessage(deleteMessageSuccessString) - popView() + flowWithResource { + val student = studentRepository.getCurrentStudent() + messageRepository.deleteMessage(student, message!!) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Message ${message?.id} delete started") + Status.SUCCESS -> { + Timber.d("Message ${message?.id} delete success") + view?.run { + showMessage(deleteMessageSuccessString) + popView() + } + } + Status.ERROR -> { + Timber.d("Message ${message?.id} delete failed") + retryCallback = { onMessageDelete() } + errorHandler.dispatch(it.error!!) } } - + }.afterLoading { view?.showProgress(false) - } + }.launch("delete") } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -258,11 +201,6 @@ class MessagePreviewPresenter @Inject constructor( } } - fun onMessageRestore(): Boolean { - restoreMessage() - return true - } - fun onMessageDelete(): Boolean { deleteMessage() return true @@ -270,40 +208,18 @@ class MessagePreviewPresenter @Inject constructor( private fun initOptions() { view?.apply { - showOptions( - show = messageWithAttachments?.message != null, - isReplayable = messageWithAttachments?.message?.folderId == MessageFolder.RECEIVED.id, - isRestorable = messageWithAttachments?.message?.folderId == MessageFolder.TRASHED.id, - ) + showOptions(message != null) + message?.let { + when (it.folderId == MessageFolder.TRASHED.id) { + true -> setDeletedOptionsLabels() + false -> setNotDeletedOptionsLabels() + } + } + } } fun onCreateOptionsMenu() { initOptions() } - - fun onMute(): Boolean { - val message = messageWithAttachments?.message ?: return false - val isMuted = messageWithAttachments?.mutedMessageSender != null - - presenterScope.launch { - runCatching { - when (isMuted) { - true -> { - messageRepository.unmuteMessage(message.correspondents) - view?.run { showMessage(unmuteMessageSuccessString) } - } - - false -> { - messageRepository.muteMessage(message.correspondents) - view?.run { showMessage(muteMessageSuccessString) } - } - } - }.onFailure { - errorHandler.dispatch(it) - } - } - view?.updateMuteToggleButton(isMuted) - return true - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt index ee0b6ce0..fa6d735e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt @@ -1,6 +1,7 @@ package io.github.wulkanowy.ui.modules.message.preview -import androidx.annotation.StringRes +import android.os.Build +import androidx.annotation.RequiresApi import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.MessageWithAttachment import io.github.wulkanowy.ui.base.BaseView @@ -9,24 +10,14 @@ interface MessagePreviewView : BaseView { val deleteMessageSuccessString: String - val muteMessageSuccessString: String - - val unmuteMessageSuccessString: String - - val restoreMessageSuccessString: String - val messageNoSubjectString: String val printHTML: String - val messageNotExists: String - fun initView() fun setMessageWithAttachment(item: MessageWithAttachment) - fun updateMuteToggleButton(isMuted: Boolean) - fun showProgress(show: Boolean) fun showContent(show: Boolean) @@ -37,7 +28,11 @@ interface MessagePreviewView : BaseView { fun setErrorRetryCallback(callback: () -> Unit) - fun showOptions(show: Boolean, isReplayable: Boolean, isRestorable: Boolean) + fun showOptions(show: Boolean) + + fun setDeletedOptionsLabels() + + fun setNotDeletedOptionsLabels() fun openMessageReply(message: Message?) @@ -45,9 +40,8 @@ interface MessagePreviewView : BaseView { fun shareText(text: String, subject: String) - fun popView() - + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) fun printDocument(html: String, jobName: String) - fun showMessage(@StringRes messageId: Int) + fun popView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChipItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChipItem.kt index bd14bc89..dd2d2b9b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChipItem.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/RecipientChipItem.kt @@ -2,9 +2,7 @@ package io.github.wulkanowy.ui.modules.message.send import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.materialchipsinput.ChipItem -import kotlinx.serialization.Serializable -@Serializable data class RecipientChipItem( override val title: String, diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt index 0ba82f1a..59944d41 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt @@ -4,40 +4,27 @@ import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.graphics.Rect -import android.os.Build import android.os.Bundle -import android.text.Spanned import android.view.Menu import android.view.MenuItem import android.view.TouchDelegate import android.view.View.GONE import android.view.View.VISIBLE -import android.view.ViewGroup import android.widget.Toast import android.widget.Toast.LENGTH_LONG -import androidx.core.text.parseAsHtml -import androidx.core.text.toHtml -import androidx.core.view.* -import androidx.core.widget.doOnTextChanged -import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Mailbox import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.databinding.ActivitySendMessageBinding import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog -import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.LISTENER_KEY -import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.MAILBOX_KEY import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.hideSoftInput -import io.github.wulkanowy.utils.nullableSerializable import io.github.wulkanowy.utils.showSoftInput import javax.inject.Inject @AndroidEntryPoint -class SendMessageActivity : BaseActivity(), - SendMessageView { +class SendMessageActivity : BaseActivity(), SendMessageView { @Inject override lateinit var presenter: SendMessagePresenter @@ -45,8 +32,6 @@ class SendMessageActivity : BaseActivity + override val formRecipientsData: List + get() = binding.sendMessageTo.addedChipItems as List - override lateinit var formSubjectValue: String + override val formSubjectValue: String + get() = binding.sendMessageSubject.text.toString() - override lateinit var formContentValue: String + override val formContentValue: String + get() = binding.sendMessageMessageContent.text.toString() override val messageRequiredRecipients: String get() = getString(R.string.message_required_recipients) @@ -82,50 +65,14 @@ class SendMessageActivity : BaseActivity= Build.VERSION_CODES.R) { - WindowCompat.setDecorFitsSystemWindows(window, false) - binding.sendAppBar.isLifted = true - } - initializeMessageContainer() - messageContainer = binding.sendMessageContainer - formRecipientsData = binding.sendMessageTo.addedChipItems as List - formSubjectValue = binding.sendMessageSubject.text.toString() - formContentValue = - binding.sendMessageMessageContent.text.toString().parseAsHtml().toString() - binding.sendMessageFrom.setOnClickListener { presenter.onOpenMailboxChooser() } - - presenter.onAttachView( - view = this, - reason = intent.nullableSerializable(EXTRA_REASON), - message = intent.nullableSerializable(EXTRA_MESSAGE), - reply = intent.nullableSerializable(EXTRA_REPLY) - ) - supportFragmentManager.setFragmentResultListener(LISTENER_KEY, this) { _, bundle -> - presenter.onMailboxSelected(bundle.nullableSerializable(MAILBOX_KEY)) - } + presenter.onAttachView(this, intent.getSerializableExtra(EXTRA_MESSAGE) as? Message, intent.getSerializableExtra(EXTRA_REPLY) as? Boolean) } @SuppressLint("ClickableViewAccessibility") @@ -133,44 +80,11 @@ class SendMessageActivity : BaseActivity presenter.onTouchScroll() } - sendMessageTo.onChipAddListener = { onRecipientChange() } sendMessageTo.onTextChangeListener = presenter::onRecipientsTextChange - sendMessageSubject.doOnTextChanged { text, _, _, _ -> onMessageSubjectChange(text) } - sendMessageMessageContent.doOnTextChanged { text, _, _, _ -> onMessageContentChange(text) } } } - private fun initializeMessageContainer() { - ViewCompat.setOnApplyWindowInsetsListener(binding.sendMessageScroll) { view, insets -> - val navigationBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars()) - val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime()) - - view.updateLayoutParams { - bottomMargin = if (imeInsets.bottom > navigationBarInsets.bottom) { - imeInsets.bottom - } else { - navigationBarInsets.bottom - } - } - WindowInsetsCompat.CONSUMED - } - } - - private fun onMessageSubjectChange(text: CharSequence?) { - formSubjectValue = text.toString() - presenter.onMessageContentChange() - } - - private fun onMessageContentChange(text: CharSequence?) { - formContentValue = (text as Spanned).toHtml() - presenter.onMessageContentChange() - } - - private fun onRecipientChange() { - presenter.onMessageContentChange() - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { + override fun onCreateOptionsMenu(menu: Menu?): Boolean { menuInflater.inflate(R.menu.action_menu_send_message, menu) return true } @@ -184,8 +98,8 @@ class SendMessageActivity : BaseActivity) { @@ -217,7 +131,7 @@ class SendMessageActivity : BaseActivity) { - MailboxChooserDialog.newInstance( - mailboxes = mailboxes, - isMailboxRequired = true, - folder = LISTENER_KEY, - ).show(supportFragmentManager, "chooser") - } - override fun popView() { finish() } @@ -265,8 +171,7 @@ class SendMessageActivity : BaseActivity presenter.restoreMessageParts() } - .setNegativeButton(R.string.all_no) { _, _ -> presenter.clearDraft() } - .show() - } - - @Suppress("UNCHECKED_CAST") - override fun clearDraft() { - formRecipientsData = binding.sendMessageTo.addedChipItems as List - presenter.clearDraft() - } - - override fun getMessageBackupDialogString() = - resources.getString(R.string.message_restore_dialog) - - override fun getMessageBackupDialogStringWithRecipients(recipients: String) = - resources.getString(R.string.message_restore_dialog_with_recipients, recipients) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt index 6155baea..e06c4963 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt @@ -1,81 +1,55 @@ package io.github.wulkanowy.ui.modules.message.send -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.MailboxType +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Recipient -import io.github.wulkanowy.data.pojos.MessageDraft -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.RecipientRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.message.MessageRepository +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.recipient.RecipientRepository +import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource import io.github.wulkanowy.utils.toFormattedString -import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.consumeAsFlow -import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject class SendMessagePresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, + private val semesterRepository: SemesterRepository, private val messageRepository: MessageRepository, + private val reportingUnitRepository: ReportingUnitRepository, private val recipientRepository: RecipientRepository, private val preferencesRepository: PreferencesRepository, private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { - private val messageUpdateChannel = Channel() - - private var message: Message? = null - private var isReplay: Boolean? = null - - private var mailboxes: List = emptyList() - private var selectedMailbox: Mailbox? = null - - fun onAttachView(view: SendMessageView, reason: String?, message: Message?, reply: Boolean?) { + fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) { super.onAttachView(view) view.initView() - initializeSubjectStream() - this.message = message - this.isReplay = reply - Timber.i("Send message view was initialized") loadData(message, reply) with(view) { - if (messageRepository.draftMessage != null && reply == null) { - view.showMessageBackupDialog() - } - reason?.let { - setSubject("Usprawiedliwienie") - setContent(it) - } message?.let { - setSubject( - when (reply) { - true -> "RE: " - else -> "FW: " - } + message.subject - ) + setSubject(when (reply) { + true -> "RE: " + else -> "FW: " + } + message.subject) if (preferencesRepository.fillMessageContent || reply != true) { - setContent(buildString { - if (reply == true) { - append("

") - } - - append("Od: ${message.sender}
") - append("Do: ${message.recipients}
") - append("Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}

") - append(message.content) - }) + setContent( + when (reply) { + true -> "\n\n" + else -> "" + } + when (message.sender.isNotEmpty()) { + true -> "Od: ${message.sender}\n" + false -> "Do: ${message.recipient}\n" + } + "Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${message.content}") } } } @@ -118,209 +92,115 @@ class SendMessagePresenter @Inject constructor( return false } - fun onOpenMailboxChooser() { - view?.showMailboxChooser(mailboxes) - } - - fun onMailboxSelected(mailbox: Mailbox?) { - selectedMailbox = mailbox - - loadData(message, isReplay) - } - private fun loadData(message: Message?, reply: Boolean?) { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() - - if (selectedMailbox == null && mailboxes.isEmpty()) { - selectedMailbox = messageRepository.getMailboxByStudent(student) - mailboxes = messageRepository.getMailboxes(student, false).toFirstResult() - .dataOrNull.orEmpty() - } + val semester = semesterRepository.getCurrentSemester(student) + val unit = reportingUnitRepository.getReportingUnit(student, semester.unitId) Timber.i("Loading recipients started") - val recipients = createChips( - recipients = recipientRepository.getRecipients( - student = student, - mailbox = selectedMailbox, - type = MailboxType.EMPLOYEE, - ) - ) + val recipients = when { + unit != null -> recipientRepository.getRecipients(student, 2, unit) + else -> listOf() + }.let { createChips(it) } Timber.i("Loading recipients result: Success, fetched %d recipients", recipients.size) Timber.i("Loading message recipients started") val messageRecipients = when { - message != null && reply == true -> recipientRepository.getMessageSender( - student = student, - message = message, - mailbox = selectedMailbox, - ) + message != null && reply == true -> recipientRepository.getMessageRecipients(student, message) else -> emptyList() }.let { createChips(it) } - Timber.i( - "Loaded message recipients to reply result: Success, fetched %d recipients", - messageRecipients.size - ) + Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", messageRecipients.size) - recipients to messageRecipients - } - .logResourceStatus("load recipients") - .onResourceLoading { - view?.run { + Triple(unit, recipients, messageRecipients) + }.onEach { + when (it.status) { + Status.LOADING -> view?.run { + Timber.i("Loading recipients started") showProgress(true) showContent(false) } - } - .onResourceNotLoading { - view?.run { showProgress(false) } - } - .onResourceError { - view?.showContent(true) - errorHandler.dispatch(it) - } - .onResourceSuccess { - it.let { (recipientChips, selectedRecipientChips) -> + Status.SUCCESS -> it.data!!.let { (reportingUnit, recipientChips, selectedRecipientChips) -> view?.run { - setMailbox(getMailboxName(selectedMailbox)) - setRecipients(recipientChips) - if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients( - selectedRecipientChips - ) - showContent(true) + if (reportingUnit != null) { + setReportingUnit(reportingUnit) + setRecipients(recipientChips) + if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(selectedRecipientChips) + showContent(true) + } else { + Timber.i("Loading recipients result: Can't find the reporting unit") + view?.showEmpty(true) + } } } + Status.ERROR -> { + Timber.i("Loading recipients result: An exception occurred") + view?.showContent(true) + errorHandler.dispatch(it.error!!) + } } - .launch() + }.afterLoading { + view?.run { showProgress(false) } + }.launch() } private fun sendMessage(subject: String, content: String, recipients: List) { - val mailbox = selectedMailbox ?: return - - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() - messageRepository.sendMessage( - student = student, - subject = subject, - content = content, - recipients = recipients, - mailbox = mailbox, - ) - }.logResourceStatus("sending message").onEach { - when (it) { - is Resource.Loading -> view?.run { + messageRepository.sendMessage(student, subject, content, recipients) + }.onEach { + when (it.status) { + Status.LOADING -> view?.run { + Timber.i("Sending message started") showSoftInput(false) showContent(false) showProgress(true) showActionBar(false) } - is Resource.Success -> { - view?.clearDraft() + Status.SUCCESS -> { + Timber.i("Sending message result: Success") view?.run { showMessage(messageSuccess) popView() } analytics.logEvent("send_message", "recipients" to recipients.size) } - is Resource.Error -> { + Status.ERROR -> { + Timber.i("Sending message result: An exception occurred") view?.run { showContent(true) showProgress(false) showActionBar(true) } - errorHandler.dispatch(it.error) + errorHandler.dispatch(it.error!!) } } }.launch("send") } private fun createChips(recipients: List): List { + fun generateCorrectSummary(recipientRealName: String): String { + val substring = recipientRealName.substringBeforeLast("-") + return when { + substring == recipientRealName -> recipientRealName + substring.indexOf("(") != -1 -> { + recipientRealName.indexOf("(") + .let { recipientRealName.substring(if (it != -1) it else 0) } + } + substring.indexOf("[") != -1 -> { + recipientRealName.indexOf("[") + .let { recipientRealName.substring(if (it != -1) it else 0) } + } + else -> recipientRealName.substringAfter("-") + }.trim() + } + return recipients.map { RecipientChipItem( - title = it.userName, - summary = buildString { - getMailboxType(it.type)?.let(::append) - if (isNotBlank()) append(" ") - - append("(${it.schoolShortName})") - }, + title = it.name, + summary = generateCorrectSummary(it.realName), recipient = it ) } } - - private fun getMailboxName(mailbox: Mailbox?): String { - mailbox ?: return "" - - // username - accountType [\n student name - ] (school short name) - return buildString { - append(mailbox.userName) - append(" - ") - append(getMailboxType(mailbox.type)) - appendLine() - - if (mailbox.type == MailboxType.PARENT) { - append(mailbox.studentName) - append(" - ") - } - - append("(${mailbox.schoolNameShort})") - } - } - - private fun getMailboxType(type: MailboxType): String? = when (type) { - MailboxType.STUDENT -> view?.mailboxStudent - MailboxType.PARENT -> view?.mailboxParent - MailboxType.GUARDIAN -> view?.mailboxGuardian - MailboxType.EMPLOYEE -> view?.mailboxEmployee - MailboxType.UNKNOWN -> null - } - - fun onMessageContentChange() { - presenterScope.launch { - messageUpdateChannel.send(Unit) - } - } - - @OptIn(FlowPreview::class) - private fun initializeSubjectStream() { - presenterScope.launch { - messageUpdateChannel.consumeAsFlow() - .debounce(250) - .catch { Timber.e(it) } - .collect { - saveDraftMessage() - Timber.i("Draft message was saved!") - } - } - } - - private fun saveDraftMessage() { - messageRepository.draftMessage = MessageDraft( - recipients = view?.formRecipientsData!!, - subject = view?.formSubjectValue!!, - content = view?.formContentValue!!, - ) - } - - fun restoreMessageParts() { - val draftMessage = messageRepository.draftMessage ?: return - view?.setSelectedRecipients(draftMessage.recipients) - view?.setSubject(draftMessage.subject) - view?.setContent(draftMessage.content) - Timber.i("Continue work on draft") - } - - fun getRecipientsNames(): String { - return messageRepository.draftMessage?.recipients.orEmpty() - .joinToString { it.recipient.userName } - } - - fun clearDraft() { - messageRepository.draftMessage = null - Timber.i("Draft cleared!") - } - - fun getMessageBackupContent(recipients: String) = - if (recipients.isEmpty()) view?.getMessageBackupDialogString() - else view?.getMessageBackupDialogStringWithRecipients(recipients) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt index e27a09d6..2839f9ce 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt @@ -1,16 +1,17 @@ package io.github.wulkanowy.ui.modules.message.send -import io.github.wulkanowy.data.db.entities.Mailbox +import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.ui.base.BaseView interface SendMessageView : BaseView { + val isDropdownListVisible: Boolean - var formRecipientsData: List + val formRecipientsData: List - var formSubjectValue: String + val formSubjectValue: String - var formContentValue: String + val formContentValue: String val messageRequiredRecipients: String @@ -18,17 +19,9 @@ interface SendMessageView : BaseView { val messageSuccess: String - val mailboxStudent: String - - val mailboxParent: String - - val mailboxGuardian: String - - val mailboxEmployee: String - fun initView() - fun setMailbox(mailbox: String) + fun setReportingUnit(unit: ReportingUnit) fun setRecipients(recipients: List) @@ -53,13 +46,4 @@ interface SendMessageView : BaseView { fun scrollToRecipients() fun popView() - - fun showMessageBackupDialog() - - fun getMessageBackupDialogString(): String - - fun getMessageBackupDialogStringWithRecipients(recipients: String): String - - fun clearDraft() - fun showMailboxChooser(mailboxes: List) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt index fadc77e6..e9b34da3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt @@ -1,194 +1,81 @@ package io.github.wulkanowy.ui.modules.message.tab -import android.annotation.SuppressLint -import android.content.res.ColorStateList import android.graphics.Typeface import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup -import android.widget.CompoundButton -import androidx.core.view.isVisible -import androidx.core.widget.ImageViewCompat import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.RecyclerView.NO_POSITION import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Message +import io.github.wulkanowy.data.repositories.message.MessageFolder import io.github.wulkanowy.databinding.ItemMessageBinding -import io.github.wulkanowy.databinding.ItemMessageChipsBinding -import io.github.wulkanowy.utils.getCompatColor -import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.toFormattedString import javax.inject.Inject -class MessageTabAdapter @Inject constructor() : RecyclerView.Adapter() { +class MessageTabAdapter @Inject constructor() : + RecyclerView.Adapter() { - lateinit var onItemClickListener: (MessageTabDataItem.MessageItem, position: Int) -> Unit + var onClickListener: (Message, position: Int) -> Unit = { _, _ -> } - lateinit var onLongItemClickListener: (MessageTabDataItem.MessageItem) -> Unit + var onChangesDetectedListener = {} - lateinit var onHeaderClickListener: (CompoundButton, Boolean) -> Unit - - lateinit var onMailboxClickListener: () -> Unit - - lateinit var onChangesDetectedListener: () -> Unit - - private var items = mutableListOf() - - fun submitData(data: List) { - val originalMessagesSize = items.count { it.viewType == MessageItemViewType.MESSAGE } - val newMessagesSize = data.count { it.viewType == MessageItemViewType.MESSAGE } - - if (originalMessagesSize != newMessagesSize) onChangesDetectedListener() + private var items = mutableListOf() + fun setDataItems(data: List) { + if (items.size != data.size) onChangesDetectedListener() val diffResult = DiffUtil.calculateDiff(MessageTabDiffUtil(items, data)) items = data.toMutableList() - diffResult.dispatchUpdatesTo(this) } - override fun getItemViewType(position: Int) = items[position].viewType.ordinal - override fun getItemCount() = items.size - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { - val inflater = LayoutInflater.from(parent.context) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( + ItemMessageBinding.inflate(LayoutInflater.from(parent.context), parent, false) + ) - return when (MessageItemViewType.entries[viewType]) { - MessageItemViewType.FILTERS -> HeaderViewHolder( - ItemMessageChipsBinding.inflate(inflater, parent, false) - ) - - MessageItemViewType.MESSAGE -> ItemViewHolder( - ItemMessageBinding.inflate(inflater, parent, false) - ) - } - } - - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - when (holder) { - is ItemViewHolder -> bindItemViewHolder(holder, position) - is HeaderViewHolder -> bindHeaderViewHolder(holder, position) - } - } - - @SuppressLint("PrivateResource") - private fun bindHeaderViewHolder(holder: HeaderViewHolder, position: Int) { - val item = items[position] as MessageTabDataItem.FilterHeader - val context = holder.binding.root.context + override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { + val item = items[position] with(holder.binding) { - chipMailbox.text = - item.selectedMailbox ?: context.getString(R.string.message_chip_all_mailboxes) - chipMailbox.chipBackgroundColor = ColorStateList.valueOf( - if (item.selectedMailbox == null) { - context.getCompatColor(R.color.m3_elevated_chip_background_color) - } else context.getThemeAttrColor(R.attr.colorPrimary, 64) - ) - chipMailbox.setTextColor( - if (item.selectedMailbox == null) { - context.getThemeAttrColor(R.attr.colorOnSurfaceVariant) - } else context.getThemeAttrColor(R.attr.colorPrimary) - ) - chipMailbox.setOnClickListener { onMailboxClickListener() } + val style = if (item.unread) Typeface.BOLD else Typeface.NORMAL - if (item.onlyUnread == null) { - chipUnread.isVisible = false - } else { - chipUnread.isVisible = true - chipUnread.isChecked = item.onlyUnread - chipUnread.setOnCheckedChangeListener(onHeaderClickListener) + messageItemAuthor.run { + text = if (item.folderId == MessageFolder.SENT.id) item.recipient else item.sender + setTypeface(null, style) } - chipUnread.isEnabled = item.isEnabled - - chipAttachments.isEnabled = item.isEnabled - chipAttachments.isChecked = item.onlyWithAttachments - chipAttachments.setOnCheckedChangeListener(onHeaderClickListener) - } - } - - private fun bindItemViewHolder(holder: ItemViewHolder, position: Int) { - val item = (items[position] as MessageTabDataItem.MessageItem) - val message = item.message - - with(holder.binding) { - val normalFont = Typeface.create("sans-serif", Typeface.NORMAL) - val boldFont = Typeface.create("sans-serif-black", Typeface.NORMAL) - - val primaryColor = root.context.getThemeAttrColor(android.R.attr.textColorPrimary) - val secondaryColor = root.context.getThemeAttrColor(android.R.attr.textColorSecondary) - - val currentFont = if (message.unread) boldFont else normalFont - val currentTextColor = if (message.unread) primaryColor else secondaryColor - - with(messageItemAuthor) { - text = message.correspondents - setTextColor(currentTextColor) - typeface = currentFont + messageItemSubject.run { + text = if (item.subject.isNotBlank()) item.subject else context.getString(R.string.message_no_subject) + setTypeface(null, style) } - with(messageItemSubject) { - text = message.subject.ifBlank { context.getString(R.string.message_no_subject) } - setTextColor(currentTextColor) - typeface = currentFont - } - with(messageItemDate) { - text = message.date.toFormattedString() - setTextColor(currentTextColor) - typeface = currentFont - } - with(messageItemAttachmentIcon) { - ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(currentTextColor)) - isVisible = message.hasAttachments - } - messageItemUnreadIndicator.isVisible = message.unread || item.isMuted - - when (item.isMuted) { - true -> messageItemUnreadIndicator.setImageResource(R.drawable.ic_notifications_off) - else -> messageItemUnreadIndicator.setImageResource(R.drawable.ic_circle_notification) + messageItemDate.run { + text = item.date.toFormattedString() + setTypeface(null, style) } + messageItemAttachmentIcon.visibility = if (item.hasAttachments) View.VISIBLE else View.GONE root.setOnClickListener { - holder.bindingAdapterPosition.let { - if (it != RecyclerView.NO_POSITION) { - onItemClickListener(item, it) - } - } - } - - root.setOnLongClickListener { - onLongItemClickListener(item) - true - } - - with(messageItemCheckbox) { - isChecked = item.isSelected - isVisible = item.isActionMode + holder.adapterPosition.let { if (it != NO_POSITION) onClickListener(item, it) } } } } class ItemViewHolder(val binding: ItemMessageBinding) : RecyclerView.ViewHolder(binding.root) - class HeaderViewHolder(val binding: ItemMessageChipsBinding) : - RecyclerView.ViewHolder(binding.root) - - private class MessageTabDiffUtil( - private val old: List, private val new: List - ) : DiffUtil.Callback() { - + private class MessageTabDiffUtil(private val old: List, private val new: List) : + DiffUtil.Callback() { override fun getOldListSize(): Int = old.size override fun getNewListSize(): Int = new.size override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { - val oldItem = old[oldItemPosition] - val newItem = new[newItemPosition] - - return if (oldItem is MessageTabDataItem.MessageItem && newItem is MessageTabDataItem.MessageItem) { - oldItem.message.messageGlobalKey == newItem.message.messageGlobalKey - } else { - oldItem.viewType == newItem.viewType - } + return old[oldItemPosition].id == new[newItemPosition].id } - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = - old[oldItemPosition] == new[newItemPosition] + override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { + return old[oldItemPosition] == new[newItemPosition] + } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt deleted file mode 100644 index ef640e04..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.wulkanowy.ui.modules.message.tab - -import io.github.wulkanowy.data.db.entities.Message - -sealed class MessageTabDataItem(val viewType: MessageItemViewType) { - - data class MessageItem( - val message: Message, - val isMuted: Boolean, - val isSelected: Boolean, - val isActionMode: Boolean - ) : MessageTabDataItem(MessageItemViewType.MESSAGE) - - data class FilterHeader( - val selectedMailbox: String?, - val onlyUnread: Boolean?, - val onlyWithAttachments: Boolean, - val isEnabled: Boolean - ) : MessageTabDataItem(MessageItemViewType.FILTERS) -} - -enum class MessageItemViewType { FILTERS, MESSAGE } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt index 12f9d323..44ad4bf1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt @@ -3,35 +3,23 @@ package io.github.wulkanowy.ui.modules.message.tab import android.os.Bundle import android.view.Menu import android.view.MenuInflater -import android.view.MenuItem import android.view.View import android.view.View.GONE import android.view.View.INVISIBLE import android.view.View.VISIBLE -import android.widget.CompoundButton -import androidx.annotation.StringRes -import androidx.appcompat.view.ActionMode import androidx.appcompat.widget.SearchView -import androidx.core.os.bundleOf -import androidx.core.view.updatePadding -import androidx.fragment.app.setFragmentResultListener import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Mailbox import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.enums.MessageFolder +import io.github.wulkanowy.data.repositories.message.MessageFolder import io.github.wulkanowy.databinding.FragmentMessageTabBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.message.MessageFragment -import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.hideSoftInput -import io.github.wulkanowy.utils.nullableSerializable +import kotlinx.coroutines.FlowPreview import javax.inject.Inject @AndroidEntryPoint @@ -42,119 +30,63 @@ class MessageTabFragment : BaseFragment(R.layout.frag lateinit var presenter: MessageTabPresenter @Inject - lateinit var messageTabAdapter: MessageTabAdapter + lateinit var tabAdapter: MessageTabAdapter companion object { - const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id" - fun newInstance(folder: MessageFolder) = MessageTabFragment().apply { - arguments = bundleOf(MESSAGE_TAB_FOLDER_ID to folder.name) + fun newInstance(folder: MessageFolder): MessageTabFragment { + return MessageTabFragment().apply { + arguments = Bundle().apply { + putString(MESSAGE_TAB_FOLDER_ID, folder.name) + } + } } } override val isViewEmpty - get() = messageTabAdapter.itemCount == 0 + get() = tabAdapter.itemCount == 0 - private var actionMode: ActionMode? = null - - private val actionModeCallback = object : ActionMode.Callback { - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { - val inflater = mode.menuInflater - inflater.inflate(R.menu.context_menu_message_tab, menu) - return true - } - - override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { - val isTrashFolder = presenter.folder == MessageFolder.TRASHED - - menu.findItem(R.id.messageTabContextMenuDelete).setVisible(!isTrashFolder) - menu.findItem(R.id.messageTabContextMenuDeleteForever).setVisible(isTrashFolder) - menu.findItem(R.id.messageTabContextMenuRestore).setVisible(isTrashFolder) - - return presenter.onPrepareActionMode() - } - - override fun onDestroyActionMode(mode: ActionMode) { - presenter.onDestroyActionMode() - actionMode = null - } - - override fun onActionItemClicked(mode: ActionMode, menu: MenuItem): Boolean { - when (menu.itemId) { - R.id.messageTabContextMenuDelete -> presenter.onActionModeSelectDelete() - R.id.messageTabContextMenuRestore -> presenter.onActionModeSelectRestore() - R.id.messageTabContextMenuDeleteForever -> presenter.onActionModeSelectDelete() - R.id.messageTabContextMenuSelectAll -> presenter.onActionModeSelectCheckAll() - } - return true - } - } - - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) } + @FlowPreview override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentMessageTabBinding.bind(view) messageContainer = binding.messageTabRecycler - - val folder = MessageFolder.valueOf( - (savedInstanceState ?: requireArguments()).getString(MESSAGE_TAB_FOLDER_ID).orEmpty() - ) - presenter.onAttachView(this, folder) + presenter.onAttachView(this, MessageFolder.valueOf( + (savedInstanceState ?: arguments)?.getString(MESSAGE_TAB_FOLDER_ID).orEmpty() + )) } override fun initView() { - with(messageTabAdapter) { - onItemClickListener = presenter::onMessageItemSelected - onLongItemClickListener = presenter::onMessageItemLongSelected - onHeaderClickListener = ::onChipChecked - onMailboxClickListener = presenter::onMailboxFilterSelected + with(tabAdapter) { + onClickListener = presenter::onMessageItemSelected onChangesDetectedListener = ::resetListPosition } with(binding.messageTabRecycler) { layoutManager = LinearLayoutManager(context) - adapter = messageTabAdapter - addItemDecoration(DividerItemDecoration(context, false)) - itemAnimator = null + adapter = tabAdapter + addItemDecoration(DividerItemDecoration(context)) } - with(binding) { - messageTabSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - messageTabSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - messageTabSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) + messageTabSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } messageTabErrorRetry.setOnClickListener { presenter.onRetry() } messageTabErrorDetails.setOnClickListener { presenter.onDetailsClick() } } - - setFragmentResultListener(requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!) { _, bundle -> - presenter.onMailboxSelected( - mailbox = bundle.nullableSerializable(MailboxChooserDialog.MAILBOX_KEY), - ) - } } - @Deprecated("Deprecated in Java") - @Suppress("DEPRECATION") override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) inflater.inflate(R.menu.action_menu_message_tab, menu) - initializeSearchView(menu) - } - - private fun initializeSearchView(menu: Menu) { - val searchView = (menu.findItem(R.id.action_search).actionView as SearchView).apply { - queryHint = getString(R.string.all_search_hint) - maxWidth = Int.MAX_VALUE - } + val searchView = menu.findItem(R.id.action_search).actionView as SearchView + searchView.queryHint = getString(R.string.all_search_hint) + searchView.maxWidth = Int.MAX_VALUE searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String) = false override fun onQueryTextChange(query: String): Boolean { @@ -164,28 +96,8 @@ class MessageTabFragment : BaseFragment(R.layout.frag }) } - override fun updateData(data: List) { - messageTabAdapter.submitData(data) - } - - override fun updateActionModeTitle(selectedMessagesSize: Int) { - actionMode?.title = resources.getQuantityString( - R.plurals.message_selected_messages_count, - selectedMessagesSize, - selectedMessagesSize - ) - } - - override fun updateSelectAllMenu(isAllSelected: Boolean) { - val menuItem = actionMode?.menu?.findItem(R.id.messageTabContextMenuSelectAll) ?: return - - if (isAllSelected) { - menuItem.setTitle(R.string.message_unselect_all) - menuItem.setIcon(R.drawable.ic_message_unselect_all) - } else { - menuItem.setTitle(R.string.message_select_all) - menuItem.setIcon(R.drawable.ic_message_select_all) - } + override fun updateData(data: List) { + tabAdapter.setDataItems(data) } override fun showProgress(show: Boolean) { @@ -220,14 +132,6 @@ class MessageTabFragment : BaseFragment(R.layout.frag binding.messageTabSwipe.isRefreshing = show } - override fun showMessage(@StringRes messageId: Int) { - showMessage(getString(messageId)) - } - - override fun notifyParentShowNewMessage(show: Boolean) { - (parentFragment as? MessageFragment)?.onChildFragmentShowNewMessage(show) - } - override fun openMessage(message: Message) { (activity as? MainActivity)?.pushView(MessagePreviewFragment.newInstance(message)) } @@ -236,55 +140,12 @@ class MessageTabFragment : BaseFragment(R.layout.frag (parentFragment as? MessageFragment)?.onChildFragmentLoaded() } - override fun notifyParentShowActionMode(show: Boolean) { - (parentFragment as? MessageFragment)?.onChildFragmentShowActionMode(show) - } - fun onParentLoadData(forceRefresh: Boolean) { presenter.onParentViewLoadData(forceRefresh) } - fun onParentFinishActionMode() { - presenter.onParentFinishActionMode() - } - - fun onParentReselected() { - presenter.onParentReselected() - } - - private fun onChipChecked(chip: CompoundButton, isChecked: Boolean) { - when (chip.id) { - R.id.chip_unread -> presenter.onUnreadFilterSelected(isChecked) - R.id.chip_attachments -> presenter.onAttachmentsFilterSelected(isChecked) - } - } - - override fun showActionMode(show: Boolean) { - if (show) { - actionMode = (activity as MainActivity?)?.startSupportActionMode(actionModeCallback) - } else { - actionMode?.finish() - } - } - - override fun showRecyclerBottomPadding(show: Boolean) { - binding.messageTabRecycler.updatePadding( - bottom = if (show) requireContext().dpToPx(64f).toInt() else 0 - ) - } - - override fun showMailboxChooser(mailboxes: List) { - (activity as? MainActivity)?.showDialogFragment( - MailboxChooserDialog.newInstance( - mailboxes = mailboxes, - isMailboxRequired = false, - folder = requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!, - ) - ) - } - - override fun hideKeyboard() { - activity?.hideSoftInput() + fun onParentDeleteMessage() { + presenter.onDeleteMessage() } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt index cda0b32b..2143a488 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt @@ -1,26 +1,29 @@ package io.github.wulkanowy.ui.modules.message.tab -import io.github.wulkanowy.R -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.Mailbox +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Message -import io.github.wulkanowy.data.db.entities.MessageWithMutedAuthor -import io.github.wulkanowy.data.enums.MessageFolder -import io.github.wulkanowy.data.repositories.MessageRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.message.MessageFolder +import io.github.wulkanowy.data.repositories.message.MessageRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import me.xdrop.fuzzywuzzy.FuzzySearch import timber.log.Timber +import java.util.Locale import javax.inject.Inject import kotlin.math.pow @@ -28,7 +31,8 @@ class MessageTabPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, private val messageRepository: MessageRepository, - private val analytics: AnalyticsHelper, + private val semesterRepository: SemesterRepository, + private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { lateinit var folder: MessageFolder @@ -37,21 +41,11 @@ class MessageTabPresenter @Inject constructor( private var lastSearchQuery = "" - private var mailboxes: List = emptyList() - private var selectedMailbox: Mailbox? = null - - private var messages = emptyList() + private var messages = emptyList() private val searchChannel = Channel() - private val messagesToDelete = mutableSetOf() - - private var onlyUnread: Boolean? = false - - private var onlyWithAttachments = false - - private var isActionMode = false - + @FlowPreview fun onAttachView(view: MessageTabView, folder: MessageFolder) { super.onAttachView(view) view.initView() @@ -62,238 +56,66 @@ class MessageTabPresenter @Inject constructor( fun onSwipeRefresh() { Timber.i("Force refreshing the $folder message") - view?.run { loadData(true) } + onParentViewLoadData(true) } fun onRetry() { view?.run { showErrorView(false) showProgress(true) - loadData(true) } + loadData(true) } fun onDetailsClick() { view?.showErrorDetailsDialog(lastError) } + fun onDeleteMessage() { + loadData(true) + } + fun onParentViewLoadData(forceRefresh: Boolean) { loadData(forceRefresh) } - fun onParentFinishActionMode() { - view?.showActionMode(false) - } - - fun onParentReselected() { - view?.run { - if (!isViewEmpty) { - resetListPosition() - } - } - } - - fun onDestroyActionMode() { - isActionMode = false - messagesToDelete.clear() - updateDataInView() - - view?.run { - enableSwipe(true) - notifyParentShowNewMessage(true) - notifyParentShowActionMode(false) - showRecyclerBottomPadding(true) - } - } - - fun onPrepareActionMode(): Boolean { - isActionMode = true - messagesToDelete.clear() - updateDataInView() - - view?.apply { - enableSwipe(false) - notifyParentShowNewMessage(false) - notifyParentShowActionMode(true) - showRecyclerBottomPadding(false) - hideKeyboard() - } - return true - } - - fun onActionModeSelectRestore() { - Timber.i("Restore ${messagesToDelete.size} messages") - val messageList = messagesToDelete.toList() - - presenterScope.launch { - view?.run { - showProgress(true) - showContent(false) - showActionMode(false) - } - runCatching { - val student = studentRepository.getCurrentStudent(true) - messageRepository.restoreMessages(student, selectedMailbox, messageList) - } - .onFailure(errorHandler::dispatch) - .onSuccess { view?.showMessage(R.string.message_messages_restored) } - } - } - - fun onActionModeSelectDelete() { - Timber.i("Delete ${messagesToDelete.size} messages") - val messageList = messagesToDelete.toList() - - presenterScope.launch { - view?.run { - showProgress(true) - showContent(false) - showActionMode(false) - } - - runCatching { - val student = studentRepository.getCurrentStudent(true) - messageRepository.deleteMessages(student, messageList) - } - .onFailure(errorHandler::dispatch) - .onSuccess { view?.showMessage(R.string.message_messages_deleted) } - } - } - - fun onActionModeSelectCheckAll() { - val messagesToSelect = getFilteredData().map { it.message } - val isAllSelected = messagesToDelete.containsAll(messagesToSelect) - - if (isAllSelected) { - messagesToDelete.clear() - view?.showActionMode(false) - } else { - messagesToDelete.addAll(messagesToSelect) - updateDataInView() - } - - view?.run { - updateSelectAllMenu(!isAllSelected) - updateActionModeTitle(messagesToDelete.size) - } - } - - fun onMessageItemLongSelected(messageItem: MessageTabDataItem.MessageItem) { - if (!isActionMode) { - view?.showActionMode(true) - - messagesToDelete.add(messageItem.message) - - view?.updateActionModeTitle(messagesToDelete.size) - updateDataInView() - } - } - - fun onMessageItemSelected(messageItem: MessageTabDataItem.MessageItem, position: Int) { - Timber.i("Select message ${messageItem.message.messageGlobalKey} item (position: $position)") - - if (!isActionMode) { - view?.run { - showActionMode(false) - openMessage(messageItem.message) - } - } else { - if (!messageItem.isSelected) { - messagesToDelete.add(messageItem.message) - } else { - messagesToDelete.remove(messageItem.message) - } - - if (messagesToDelete.isEmpty()) { - view?.showActionMode(false) - } - - val filteredData = getFilteredData().map { it.message } - - view?.run { - updateActionModeTitle(messagesToDelete.size) - updateSelectAllMenu(messagesToDelete.containsAll(filteredData)) - } - updateDataInView() - } - } - - fun onUnreadFilterSelected(isChecked: Boolean) { - view?.run { - onlyUnread = isChecked - loadData(false) - } - } - - fun onAttachmentsFilterSelected(isChecked: Boolean) { - view?.run { - onlyWithAttachments = isChecked - loadData(false) - } - } - - fun onMailboxFilterSelected() { - view?.showMailboxChooser(mailboxes) - } - - fun onMailboxSelected(mailbox: Mailbox?) { - selectedMailbox = mailbox - loadData(false) + fun onMessageItemSelected(message: Message, position: Int) { + Timber.i("Select message ${message.id} item (position: $position)") + view?.openMessage(message) } private fun loadData(forceRefresh: Boolean) { - Timber.i("Loading $folder message data started") - - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() - - if (selectedMailbox == null && mailboxes.isEmpty()) { - selectedMailbox = messageRepository.getMailboxByStudent(student) - mailboxes = messageRepository.getMailboxes(student, forceRefresh).toFirstResult() - .dataOrNull.orEmpty() - } - - messageRepository.getMessages(student, selectedMailbox, folder, forceRefresh) - } - .logResourceStatus("load $folder message") - .onResourceData { - messages = it - - val filteredData = getFilteredData() - - view?.run { - enableSwipe(true) - showErrorView(false) - showProgress(false) - showContent(true) - showEmpty(filteredData.isEmpty()) + val semester = semesterRepository.getCurrentSemester(student) + messageRepository.getMessages(student, semester, folder, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading $folder message data started") + Status.SUCCESS -> { + Timber.i("Loading $folder message result: Success") + messages = it.data!! + updateData(getFilteredData(lastSearchQuery)) + analytics.logEvent( + "load_data", + "type" to "messages", + "items" to it.data.size, + "folder" to folder.name + ) } - - updateDataInView() - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "messages", - "items" to it.size, - "folder" to folder.name - ) - } - .onResourceNotLoading { - view?.run { - showRefresh(false) - showProgress(false) - enableSwipe(true) - notifyParentDataLoaded() + Status.ERROR -> { + Timber.i("Loading $folder message result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .catch { - errorHandler.dispatch(it) - view?.notifyParentDataLoaded() + }.afterLoading { + view?.run { + showRefresh(false) + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded() } - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -303,129 +125,89 @@ class MessageTabPresenter @Inject constructor( setErrorDetails(message) showErrorView(true) showEmpty(false) - showProgress(false) } else showError(message, error) } } fun onSearchQueryTextChange(query: String) { - presenterScope.launch { + launch { searchChannel.send(query) } } - @OptIn(FlowPreview::class) + @FlowPreview private fun initializeSearchStream() { - presenterScope.launch { + launch { searchChannel.consumeAsFlow() .debounce(250) .map { query -> lastSearchQuery = query - - getFilteredData() + getFilteredData(query) } .catch { Timber.e(it) } .collect { Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${it.size}") - - view?.run { - showEmpty(it.isEmpty()) - showContent(true) - showErrorView(false) - } - - updateDataInView() + updateData(it) view?.resetListPosition() } } } - private fun getFilteredData(): List { - if (lastSearchQuery.trim().isEmpty()) { - val sortedMessages = messages.sortedByDescending { it.message.date } - return when { - (onlyUnread == true) && onlyWithAttachments -> sortedMessages.filter { - it.message.unread == onlyUnread && it.message.hasAttachments == onlyWithAttachments - } - - (onlyUnread == true) -> sortedMessages.filter { it.message.unread == onlyUnread } - onlyWithAttachments -> sortedMessages.filter { it.message.hasAttachments == onlyWithAttachments } - else -> sortedMessages - } + private fun getFilteredData(query: String): List { + return if (query.trim().isEmpty()) { + messages.sortedByDescending { it.date } } else { - val sortedMessages = messages - .map { it to calculateMatchRatio(it.message, lastSearchQuery) } - .sortedWith(compareBy> { -it.second }.thenByDescending { it.first.message.date }) - .filter { it.second > 6000 } + messages + .map { it to calculateMatchRatio(it, query) } + .sortedByDescending { it.second } + .filter { it.second > 5000 } .map { it.first } - return when { - (onlyUnread == true) && onlyWithAttachments -> sortedMessages.filter { - it.message.unread == onlyUnread && it.message.hasAttachments == onlyWithAttachments - } - - (onlyUnread == true) -> sortedMessages.filter { it.message.unread == onlyUnread } - onlyWithAttachments -> sortedMessages.filter { it.message.hasAttachments == onlyWithAttachments } - else -> sortedMessages - } } } - private fun updateDataInView() { - val data = getFilteredData() - - val list = buildList { - add( - MessageTabDataItem.FilterHeader( - onlyUnread = onlyUnread.takeIf { folder != MessageFolder.SENT }, - onlyWithAttachments = onlyWithAttachments, - isEnabled = !isActionMode, - selectedMailbox = selectedMailbox?.let { - buildString { - if (it.studentName.isNotBlank() && it.studentName != it.userName) { - append(it.studentName) - append(" - ") - } - append(it.userName) - } - }, - ) - ) - - addAll(data.map { message -> - MessageTabDataItem.MessageItem( - message = message.message, - isMuted = message.mutedMessageSender != null, - isSelected = messagesToDelete.any { it.messageGlobalKey == message.message.messageGlobalKey }, - isActionMode = isActionMode - ) - }) + private fun updateData(data: List) { + view?.run { + showEmpty(data.isEmpty()) + showContent(data.isNotEmpty()) + showErrorView(false) + updateData(data) } - - view?.updateData(list) } private fun calculateMatchRatio(message: Message, query: String): Int { - val subjectRatio = FuzzySearch.tokenSortPartialRatio(query.lowercase(), message.subject) + val subjectRatio = FuzzySearch.tokenSortPartialRatio( + query.toLowerCase(Locale.getDefault()), + message.subject + ) - val correspondentsRatio = FuzzySearch.tokenSortPartialRatio( - query.lowercase(), - message.correspondents + val senderOrRecipientRatio = FuzzySearch.tokenSortPartialRatio( + query.toLowerCase(Locale.getDefault()), + if (message.sender.isNotEmpty()) message.sender.toLowerCase(Locale.getDefault()) + else message.recipient.toLowerCase(Locale.getDefault()) ) val dateRatio = listOf( FuzzySearch.ratio( - query.lowercase(), - message.date.toFormattedString("dd.MM").lowercase() + query.toLowerCase(Locale.getDefault()), + message.date.toFormattedString("dd.MM").toLowerCase(Locale.getDefault()) ), FuzzySearch.ratio( - query.lowercase(), - message.date.toFormattedString("dd.MM.yyyy").lowercase() + query.toLowerCase(Locale.getDefault()), + message.date.toFormattedString("dd.MM.yyyy").toLowerCase(Locale.getDefault()) + ), + FuzzySearch.ratio( + query.toLowerCase(Locale.getDefault()), + message.date.toFormattedString("d MMMM").toLowerCase(Locale.getDefault()) + ), + FuzzySearch.ratio( + query.toLowerCase(Locale.getDefault()), + message.date.toFormattedString("d MMMM yyyy").toLowerCase(Locale.getDefault()) ) ).maxOrNull() ?: 0 return (subjectRatio.toDouble().pow(2) - + correspondentsRatio.toDouble().pow(2) + + senderOrRecipientRatio.toDouble().pow(2) + dateRatio.toDouble().pow(2) * 2 ).toInt() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt index 247af434..fe9b6007 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt @@ -1,7 +1,5 @@ package io.github.wulkanowy.ui.modules.message.tab -import androidx.annotation.StringRes -import io.github.wulkanowy.data.db.entities.Mailbox import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.ui.base.BaseView @@ -13,11 +11,7 @@ interface MessageTabView : BaseView { fun resetListPosition() - fun updateData(data: List) - - fun updateActionModeTitle(selectedMessagesSize: Int) - - fun updateSelectAllMenu(isAllSelected: Boolean) + fun updateData(data: List) fun showProgress(show: Boolean) @@ -27,12 +21,8 @@ interface MessageTabView : BaseView { fun showEmpty(show: Boolean) - fun showMessage(@StringRes messageId: Int) - fun showErrorView(show: Boolean) - fun notifyParentShowNewMessage(show: Boolean) - fun setErrorDetails(message: String) fun showRefresh(show: Boolean) @@ -40,14 +30,4 @@ interface MessageTabView : BaseView { fun openMessage(message: Message) fun notifyParentDataLoaded() - - fun notifyParentShowActionMode(show: Boolean) - - fun hideKeyboard() - - fun showActionMode(show: Boolean) - - fun showRecyclerBottomPadding(show: Boolean) - - fun showMailboxChooser(mailboxes: List) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceFragment.kt index 1afe773c..8065e9b6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceFragment.kt @@ -16,13 +16,12 @@ import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint class MobileDeviceFragment : BaseFragment(R.layout.fragment_mobile_device), MobileDeviceView, - MainView.TitledView, MainView.MainChildView { + MainView.TitledView { @Inject lateinit var presenter: MobileDevicePresenter @@ -57,9 +56,7 @@ class MobileDeviceFragment : } with(binding) { - mobileDevicesSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - mobileDevicesSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - mobileDevicesSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) + mobileDevicesSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } mobileDevicesErrorRetry.setOnClickListener { presenter.onRetry() } mobileDevicesErrorDetails.setOnClickListener { presenter.onDetailsClick() } mobileDeviceAddButton.setOnClickListener { presenter.onRegisterDevice() } @@ -103,8 +100,8 @@ class MobileDeviceFragment : } } - override fun showRefresh(show: Boolean) { - binding.mobileDevicesSwipe.isRefreshing = show + override fun hideRefresh() { + binding.mobileDevicesSwipe.isRefreshing = false } override fun showProgress(show: Boolean) { @@ -135,14 +132,6 @@ class MobileDeviceFragment : (activity as? MainActivity)?.showDialogFragment(MobileDeviceTokenDialog.newInstance()) } - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onFragmentReselected() - } - - override fun resetView() { - binding.mobileDevicesRecycler.smoothScrollToPosition(0) - } - override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDevicePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDevicePresenter.kt index 56785dbf..456609e4 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDevicePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDevicePresenter.kt @@ -1,13 +1,18 @@ package io.github.wulkanowy.ui.modules.mobiledevice -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.MobileDevice -import io.github.wulkanowy.data.repositories.MobileDeviceRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.mobiledevice.MobileDeviceRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -46,41 +51,39 @@ class MobileDevicePresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - Timber.i("Loading mobile devices data started") - - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) mobileDeviceRepository.getDevices(student, semester, forceRefresh) - } - .logResourceStatus("load mobile devices data") - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading mobile devices data started") + Status.SUCCESS -> { + Timber.i("Loading mobile devices result: Success") + view?.run { + updateData(it.data!!) + showContent(it.data.isNotEmpty()) + showEmpty(it.data.isEmpty()) + showErrorView(false) + } + analytics.logEvent( + "load_data", + "type" to "devices", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading mobile devices result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "devices", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -114,25 +117,25 @@ class MobileDevicePresenter @Inject constructor( } fun onUnregisterConfirmed(device: MobileDevice) { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) mobileDeviceRepository.unregisterDevice(student, semester, device) - } - .logResourceStatus("unregister device") - .onResourceSuccess { - view?.run { - showProgress(false) - enableSwipe(true) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Unregister device started") + Status.SUCCESS -> { + Timber.i("Unregister device result: Success") + view?.run { + showProgress(false) + enableSwipe(true) + } + } + Status.ERROR -> { + Timber.i("Unregister device result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceError(errorHandler::dispatch) - .launch("unregister") - } - - fun onFragmentReselected() { - if (view?.isViewEmpty == false) { - view?.resetView() - } + }.launchIn(this) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceView.kt index 973cb123..ec2d3f87 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/MobileDeviceView.kt @@ -17,7 +17,7 @@ interface MobileDeviceView : BaseView { fun showUndo(device: MobileDevice, position: Int) - fun showRefresh(show: Boolean) + fun hideRefresh() fun showProgress(show: Boolean) @@ -32,6 +32,4 @@ interface MobileDeviceView : BaseView { fun setErrorDetails(message: String) fun showTokenDialog() - - fun resetView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenDialog.kt index 2cc2a2aa..48150d8d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenDialog.kt @@ -1,17 +1,17 @@ package io.github.wulkanowy.ui.modules.mobiledevice.token -import android.app.Dialog import android.content.ClipData import android.content.ClipboardManager import android.graphics.BitmapFactory import android.os.Bundle import android.util.Base64 +import android.view.LayoutInflater import android.view.View import android.view.View.GONE import android.view.View.VISIBLE +import android.view.ViewGroup import android.widget.Toast import androidx.core.content.getSystemService -import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.pojos.MobileDeviceToken @@ -20,27 +20,26 @@ import io.github.wulkanowy.ui.base.BaseDialogFragment import javax.inject.Inject @AndroidEntryPoint -class MobileDeviceTokenDialog : BaseDialogFragment(), - MobileDeviceTokenVIew { +class MobileDeviceTokenDialog : BaseDialogFragment(), MobileDeviceTokenVIew { @Inject lateinit var presenter: MobileDeviceTokenPresenter companion object { - - fun newInstance() = MobileDeviceTokenDialog() + fun newInstance(): MobileDeviceTokenDialog = MobileDeviceTokenDialog() } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogMobileDeviceBinding.inflate(layoutInflater).apply { binding = this }.root - ) - .create() + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_TITLE, 0) } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogMobileDeviceBinding.inflate(inflater).apply { binding = this }.root + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) presenter.onAttachView(this) } @@ -49,15 +48,15 @@ class MobileDeviceTokenDialog : BaseDialogFragment(), } override fun updateData(token: MobileDeviceToken) { - with(binding.mobileDeviceDialogTokenValue) { + with(binding.mobileDeviceDialogToken) { text = token.token setOnClickListener { clickCopy(token.token) } } - with(binding.mobileDeviceDialogSymbolValue) { + with(binding.mobileDeviceDialogSymbol) { text = token.symbol setOnClickListener { clickCopy(token.symbol) } } - with(binding.mobileDeviceDialogPinValue) { + with(binding.mobileDeviceDialogPin) { text = token.pin setOnClickListener { clickCopy(token.pin) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenPresenter.kt index 875b73ad..8270693d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/mobiledevice/token/MobileDeviceTokenPresenter.kt @@ -1,12 +1,15 @@ package io.github.wulkanowy.ui.modules.mobiledevice.token -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.repositories.MobileDeviceRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.mobiledevice.MobileDeviceRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -26,29 +29,29 @@ class MobileDeviceTokenPresenter @Inject constructor( } private fun loadData() { - resourceFlow { + flowWithResource { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) mobileDeviceRepository.getToken(student, semester) - } - .logResourceStatus("load mobile device registration") - .onResourceData { - view?.run { - updateData(it) - showContent() + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Mobile device registration data started") + Status.SUCCESS -> { + Timber.i("Mobile device registration result: Success") + view?.run { + updateData(it.data!!) + showContent() + } + analytics.logEvent("device_register", "symbol" to it.data!!.token.substring(0, 3)) + } + Status.ERROR -> { + Timber.i("Mobile device registration result: An exception occurred") + view?.closeDialog() + errorHandler.dispatch(it.error!!) } } - .onResourceSuccess { - analytics.logEvent( - "device_register", - "symbol" to it.token.substring(0, 3) - ) - } - .onResourceNotLoading { view?.hideLoading() } - .onResourceError { - view?.closeDialog() - errorHandler.dispatch(it) - } - .launch() + }.afterLoading { + view?.hideLoading() + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreAdapter.kt index 23eaba7c..70587b0c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreAdapter.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.ui.modules.more +import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView @@ -8,11 +9,9 @@ import javax.inject.Inject class MoreAdapter @Inject constructor() : RecyclerView.Adapter() { - var items = emptyList() + var items = emptyList>() - var onClickListener: (moreItem: MoreItem) -> Unit = {} - - var onLongClickListener: (moreItem: MoreItem) -> Unit = {} + var onClickListener: (name: String) -> Unit = {} override fun getItemCount() = items.size @@ -21,18 +20,13 @@ class MoreAdapter @Inject constructor() : RecyclerView.Adapter(R.layout.fragment_more), @Inject lateinit var moreAdapter: MoreAdapter - @Inject - lateinit var preferencesRepository: PreferencesRepository - companion object { fun newInstance() = MoreFragment() } @@ -34,6 +39,33 @@ class MoreFragment : BaseFragment(R.layout.fragment_more), override val titleStringId: Int get() = R.string.more_title + override val messagesRes: Pair? + get() = context?.run { getString(R.string.message_title) to getCompatDrawable(R.drawable.ic_more_messages) } + + override val homeworkRes: Pair? + get() = context?.run { getString(R.string.homework_title) to getCompatDrawable(R.drawable.ic_more_homework) } + + override val noteRes: Pair? + get() = context?.run { getString(R.string.note_title) to getCompatDrawable(R.drawable.ic_more_note) } + + override val luckyNumberRes: Pair? + get() = context?.run { getString(R.string.lucky_number_title) to getCompatDrawable(R.drawable.ic_more_lucky_number) } + + override val mobileDevicesRes: Pair? + get() = context?.run { getString(R.string.mobile_devices_title) to getCompatDrawable(R.drawable.ic_more_mobile_devices) } + + override val conferencesRes: Pair? + get() = context?.run { getString(R.string.conferences_title) to getCompatDrawable(R.drawable.ic_more_conferences) } + + override val schoolAndTeachersRes: Pair? + get() = context?.run { getString(R.string.schoolandteachers_title) to getCompatDrawable((R.drawable.ic_more_schoolandteachers)) } + + override val settingsRes: Pair? + get() = context?.run { getString(R.string.settings_title) to getCompatDrawable(R.drawable.ic_more_settings) } + + override val aboutRes: Pair? + get() = context?.run { getString(R.string.about_title) to getCompatDrawable(R.drawable.ic_all_about) } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding = FragmentMoreBinding.bind(view) @@ -53,33 +85,55 @@ class MoreFragment : BaseFragment(R.layout.fragment_more), if (::presenter.isInitialized) presenter.onViewReselected() } - override fun onFragmentChanged() { - (parentFragmentManager.fragments.find { it is MessageFragment } as MessageFragment?) - ?.onFragmentChanged() - } - - override fun updateData(data: List) { + override fun updateData(data: List>) { with(moreAdapter) { items = data notifyDataSetChanged() } } - override fun popView(depth: Int) { - (activity as? MainActivity)?.popView(depth) + override fun openMessagesView() { + (activity as? MainActivity)?.pushView(MessageFragment.newInstance()) } - override fun openView(destination: Destination) { - (activity as? MainActivity)?.pushView(destination.destinationFragment) + override fun openHomeworkView() { + (activity as? MainActivity)?.pushView(HomeworkFragment.newInstance()) + } + + override fun openNoteView() { + (activity as? MainActivity)?.pushView(NoteFragment.newInstance()) + } + + override fun openLuckyNumberView() { + (activity as? MainActivity)?.pushView(LuckyNumberFragment.newInstance()) + } + + override fun openMobileDevicesView() { + (activity as? MainActivity)?.pushView(MobileDeviceFragment.newInstance()) + } + + override fun openConferencesView() { + (activity as? MainActivity)?.pushView(ConferenceFragment.newInstance()) + } + + override fun openSchoolAndTeachersView() { + (activity as? MainActivity)?.pushView(SchoolAndTeachersFragment.newInstance()) + } + + override fun openSettingsView() { + (activity as? MainActivity)?.pushView(SettingsFragment.newInstance()) + } + + override fun openAboutView() { + (activity as? MainActivity)?.pushView(AboutFragment.newInstance()) + } + + override fun popView(depth: Int) { + (activity as? MainActivity)?.popView(depth) } override fun onDestroyView() { presenter.onDetachView() super.onDestroyView() } - - override fun restartApp() { - startActivity(MainActivity.getStartIntent(requireContext())) - requireActivity().finishAffinity() - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt deleted file mode 100644 index d544f041..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreItem.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.ui.modules.more - -import io.github.wulkanowy.ui.modules.Destination - -data class MoreItem( - - val icon: Int, - - val title: Int, - - val destination: Destination -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt index 0ebaf4c7..d083c981 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MorePresenter.kt @@ -1,24 +1,16 @@ package io.github.wulkanowy.ui.modules.more -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.Destination import timber.log.Timber import javax.inject.Inject class MorePresenter @Inject constructor( errorHandler: ErrorHandler, - studentRepository: StudentRepository, - preferencesRepository: PreferencesRepository + studentRepository: StudentRepository ) : BasePresenter(errorHandler, studentRepository) { - private val moreAppMenuItem = preferencesRepository.appMenuItemOrder - .sortedBy { it.order } - .drop(4) - override fun onAttachView(view: MoreView) { super.onAttachView(view) view.initView() @@ -26,10 +18,21 @@ class MorePresenter @Inject constructor( loadData() } - fun onItemSelected(moreItem: MoreItem) { - Timber.i("Select more item \"${moreItem.destination.destinationType}\"") - - view?.openView(moreItem.destination) + fun onItemSelected(title: String) { + Timber.i("Select more item \"${title}\"") + view?.run { + when (title) { + messagesRes?.first -> openMessagesView() + homeworkRes?.first -> openHomeworkView() + noteRes?.first -> openNoteView() + luckyNumberRes?.first -> openLuckyNumberView() + mobileDevicesRes?.first -> openMobileDevicesView() + conferencesRes?.first -> openConferencesView() + schoolAndTeachersRes?.first -> openSchoolAndTeachersView() + settingsRes?.first -> openSettingsView() + aboutRes?.first -> openAboutView() + } + } } fun onViewReselected() { @@ -39,21 +42,18 @@ class MorePresenter @Inject constructor( private fun loadData() { Timber.i("Load items for more view") - val moreItems = moreAppMenuItem.map { - MoreItem( - icon = it.icon, - title = it.title, - destination = it.destinationType.defaultDestination - ) + view?.run { + updateData(listOfNotNull( + messagesRes, + homeworkRes, + noteRes, + luckyNumberRes, + mobileDevicesRes, + conferencesRes, + schoolAndTeachersRes, + settingsRes, + aboutRes + )) } - .plus( - MoreItem( - icon = R.drawable.ic_more_settings, - title = R.string.settings_title, - destination = Destination.Settings - ) - ) - - view?.updateData(moreItems) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt index 05b426d6..bb1faeda 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/more/MoreView.kt @@ -1,17 +1,49 @@ package io.github.wulkanowy.ui.modules.more +import android.graphics.drawable.Drawable import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.Destination interface MoreView : BaseView { + val messagesRes: Pair? + + val homeworkRes: Pair? + + val noteRes: Pair? + + val luckyNumberRes: Pair? + + val mobileDevicesRes: Pair? + + val conferencesRes: Pair? + + val schoolAndTeachersRes: Pair? + + val settingsRes: Pair? + + val aboutRes: Pair? + fun initView() - fun updateData(data: List) + fun updateData(data: List>) + + fun openSettingsView() + + fun openAboutView() fun popView(depth: Int) - fun openView(destination: Destination) + fun openMessagesView() - fun restartApp() + fun openHomeworkView() + + fun openNoteView() + + fun openLuckyNumberView() + + fun openMobileDevicesView() + + fun openConferencesView() + + fun openSchoolAndTeachersView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt index 0592e924..e016fe0b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt @@ -1,74 +1,67 @@ package io.github.wulkanowy.ui.modules.note import android.annotation.SuppressLint -import android.app.Dialog import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.content.ContextCompat -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint +import androidx.fragment.app.DialogFragment import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.databinding.DialogNoteBinding import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory -import io.github.wulkanowy.ui.base.BaseDialogFragment import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.serializable +import io.github.wulkanowy.utils.lifecycleAwareVariable import io.github.wulkanowy.utils.toFormattedString -@AndroidEntryPoint -class NoteDialog : BaseDialogFragment() { +class NoteDialog : DialogFragment() { + + private var binding: DialogNoteBinding by lifecycleAwareVariable() private lateinit var note: Note companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(note: Note) = NoteDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to note) + fun newInstance(exam: Note): NoteDialog { + return NoteDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - note = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + note = getSerializable(ARGUMENT_KEY) as Note + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogNoteBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogNoteBinding.inflate(inflater).apply { binding = this }.root } @SuppressLint("SetTextI18n") - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(binding) { - noteDialogDateValue.text = note.date.toFormattedString() - noteDialogCategoryValue.text = note.category - noteDialogTeacherValue.text = note.teacher - noteDialogContentValue.text = note.content + noteDialogDate.text = note.date.toFormattedString() + noteDialogCategory.text = note.category + noteDialogTeacher.text = note.teacher + noteDialogContent.text = note.content } if (note.isPointsShow) { - with(binding.noteDialogPointsValue) { + with(binding.noteDialogPoints) { text = "${if (note.points > 0) "+" else ""}${note.points}" - setTextColor( - when (NoteCategory.getByValue(note.categoryType)) { - NoteCategory.POSITIVE -> ContextCompat.getColor( - requireContext(), - R.color.note_positive - ) - NoteCategory.NEGATIVE -> ContextCompat.getColor( - requireContext(), - R.color.note_negative - ) - else -> requireContext().getThemeAttrColor(android.R.attr.textColorPrimary) - } - ) + setTextColor(when (NoteCategory.getByValue(note.categoryType)) { + NoteCategory.POSITIVE -> ContextCompat.getColor(requireContext(), R.color.note_positive) + NoteCategory.NEGATIVE -> ContextCompat.getColor(requireContext(), R.color.note_negative) + else -> requireContext().getThemeAttrColor(android.R.attr.textColorPrimary) + }) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt index cb54b384..079285a8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteFragment.kt @@ -13,12 +13,11 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint class NoteFragment : BaseFragment(R.layout.fragment_note), NoteView, - MainView.TitledView, MainView.MainChildView { + MainView.TitledView { @Inject lateinit var presenter: NotePresenter @@ -51,9 +50,7 @@ class NoteFragment : BaseFragment(R.layout.fragment_note), addItemDecoration(DividerItemDecoration(context)) } with(binding) { - noteSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - noteSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - noteSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) + noteSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } noteErrorRetry.setOnClickListener { presenter.onRetry() } noteErrorDetails.setOnClickListener { presenter.onDetailsClick() } } @@ -108,16 +105,8 @@ class NoteFragment : BaseFragment(R.layout.fragment_note), binding.noteRecycler.visibility = if (show) VISIBLE else GONE } - override fun showRefresh(show: Boolean) { - binding.noteSwipe.isRefreshing = show - } - - override fun onFragmentReselected() { - if (::presenter.isInitialized) presenter.onFragmentReselected() - } - - override fun resetView() { - binding.noteRecycler.smoothScrollToPosition(0) + override fun hideRefresh() { + binding.noteSwipe.isRefreshing = false } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt index 59a13fbb..2e8bec5d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NotePresenter.kt @@ -1,14 +1,17 @@ package io.github.wulkanowy.ui.modules.note -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Note -import io.github.wulkanowy.data.repositories.NoteRepository -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.note.NoteRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResource +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -18,7 +21,6 @@ class NotePresenter @Inject constructor( studentRepository: StudentRepository, private val noteRepository: NoteRepository, private val semesterRepository: SemesterRepository, - private val preferencesRepository: PreferencesRepository, private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { @@ -50,53 +52,39 @@ class NotePresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - if (!preferencesRepository.showNotes) { - view?.run { - enableSwipe(false) - showEmpty(false) - showContent(false) - showErrorView(false) - showProgress(false) - showEmpty(true) - } - - return - } - - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) noteRepository.getNotes(student, semester, forceRefresh) - } - .logResourceStatus("load note data") - .mapResourceData { it.sortedByDescending { note -> note.date } } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading note data started") + Status.SUCCESS -> { + Timber.i("Loading note result: Success") + view?.apply { + updateData(it.data!!.sortedByDescending { item -> item.date }) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) + } + analytics.logEvent( + "load_data", + "type" to "note", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading note result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "note", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -123,23 +111,15 @@ class NotePresenter @Inject constructor( } private fun updateNote(note: Note) { - resourceFlow { noteRepository.updateNote(note) } - .onEach { - when (it) { - is Resource.Loading -> Timber.i("Attempt to update note ${note.id}") - is Resource.Success -> Timber.i("Update note result: Success") - is Resource.Error -> { - Timber.i("Update note result: An exception occurred") - errorHandler.dispatch(it.error) - } + flowWithResource { noteRepository.updateNote(note) }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Attempt to update note ${note.id}") + Status.SUCCESS -> Timber.i("Update note result: Success") + Status.ERROR -> { + Timber.i("Update note result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .launch("update_note") - } - - fun onFragmentReselected() { - if (view?.isViewEmpty == false) { - view?.resetView() - } + }.launchIn(this) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteView.kt index b813b315..a7cbab8f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteView.kt @@ -27,9 +27,7 @@ interface NoteView : BaseView { fun showContent(show: Boolean) - fun showRefresh(show: Boolean) + fun hideRefresh() fun showNoteDialog(note: Note) - - fun resetView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt deleted file mode 100644 index 0763d4fa..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt +++ /dev/null @@ -1,64 +0,0 @@ -package io.github.wulkanowy.ui.modules.notifications - -import android.os.Bundle -import android.view.View -import androidx.activity.result.contract.ActivityResultContracts.RequestPermission -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.FragmentNotificationsBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.utils.openNotificationSettings - -@AndroidEntryPoint -class NotificationsFragment : - BaseFragment(R.layout.fragment_notifications) { - - private val permission = "android.permission.POST_NOTIFICATIONS" - - private val requestPermissionLauncher = registerForActivityResult(RequestPermission()) { - if (it) { - navigateToFinish() - } else showSettingsDialog() - } - - companion object { - fun newInstance() = NotificationsFragment() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentNotificationsBinding.bind(view) - initView() - } - - private fun initView() { - with(binding) { - notificationsSkip.setOnClickListener { navigateToFinish() } - notificationsEnable.setOnClickListener { requestPermission() } - } - } - - private fun showSettingsDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.notifications_header_title) - .setMessage(R.string.notifications_header_description) - .setNegativeButton(R.string.notifications_skip) { dialog, _ -> - dialog.dismiss() - navigateToFinish() - } - .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ -> - requireActivity().openNotificationSettings() - } - .show() - } - - private fun requestPermission() { - requestPermissionLauncher.launch(permission) - } - - private fun navigateToFinish() { - (requireActivity() as LoginActivity).navigateToFinish() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterAdapter.kt deleted file mode 100644 index 92c54f45..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterAdapter.kt +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.wulkanowy.ui.modules.notificationscenter - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListAdapter -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.Notification -import io.github.wulkanowy.databinding.ItemNotificationsCenterBinding -import io.github.wulkanowy.utils.toFormattedString -import javax.inject.Inject - -class NotificationsCenterAdapter @Inject constructor() : - ListAdapter(DiffUtilCallback()) { - - var onItemClickListener: (Notification) -> Unit = {} - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemNotificationsCenterBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = getItem(position) - - with(holder.binding) { - notificationsCenterItemTitle.text = item.title - notificationsCenterItemContent.text = item.content - notificationsCenterItemDate.text = item.date.toFormattedString("HH:mm, d MMM") - notificationsCenterItemIcon.setImageResource(item.type.icon) - - root.setOnClickListener { onItemClickListener(item) } - } - } - - class ViewHolder(val binding: ItemNotificationsCenterBinding) : - RecyclerView.ViewHolder(binding.root) - - private class DiffUtilCallback : DiffUtil.ItemCallback() { - - override fun areContentsTheSame(oldItem: Notification, newItem: Notification) = - oldItem == newItem - - override fun areItemsTheSame(oldItem: Notification, newItem: Notification) = - oldItem.id == newItem.id - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterFragment.kt deleted file mode 100644 index ca71910a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterFragment.kt +++ /dev/null @@ -1,83 +0,0 @@ -package io.github.wulkanowy.ui.modules.notificationscenter - -import android.os.Bundle -import android.view.View -import androidx.core.view.isVisible -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.Notification -import io.github.wulkanowy.databinding.FragmentNotificationsCenterBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import javax.inject.Inject - -@AndroidEntryPoint -class NotificationsCenterFragment : - BaseFragment(R.layout.fragment_notifications_center), - NotificationsCenterView, MainView.TitledView { - - @Inject - lateinit var presenter: NotificationsCenterPresenter - - @Inject - lateinit var notificationsCenterAdapter: NotificationsCenterAdapter - - companion object { - - fun newInstance() = NotificationsCenterFragment() - } - - override val titleStringId: Int - get() = R.string.notifications_center_title - - override val isViewEmpty: Boolean - get() = notificationsCenterAdapter.itemCount == 0 - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentNotificationsCenterBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - notificationsCenterAdapter.onItemClickListener = { notification -> - (requireActivity() as MainActivity).pushView(notification.destination.destinationFragment) - } - - with(binding.notificationsCenterRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = notificationsCenterAdapter - } - } - - override fun updateData(data: List) { - notificationsCenterAdapter.submitList(data) - } - - override fun showEmpty(show: Boolean) { - binding.notificationsCenterEmpty.isVisible = show - } - - override fun showProgress(show: Boolean) { - binding.notificationsCenterProgress.isVisible = show - } - - override fun showContent(show: Boolean) { - binding.notificationsCenterRecycler.isVisible = show - } - - override fun showErrorView(show: Boolean) { - binding.notificationCenterError.isVisible = show - } - - override fun setErrorDetails(message: String) { - binding.notificationCenterErrorMessage.text = message - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterPresenter.kt deleted file mode 100644 index de42e567..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterPresenter.kt +++ /dev/null @@ -1,83 +0,0 @@ -package io.github.wulkanowy.ui.modules.notificationscenter - -import io.github.wulkanowy.data.repositories.NotificationRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.emitAll -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import timber.log.Timber -import javax.inject.Inject - -class NotificationsCenterPresenter @Inject constructor( - private val notificationRepository: NotificationRepository, - errorHandler: ErrorHandler, - studentRepository: StudentRepository -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var lastError: Throwable - - override fun onAttachView(view: NotificationsCenterView) { - super.onAttachView(view) - view.initView() - Timber.i("Notifications centre view was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData() - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData() - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - private fun loadData() { - Timber.i("Loading notifications data started") - - flow { - val studentId = studentRepository.getCurrentStudent(false).id - emitAll(notificationRepository.getNotifications(studentId)) - } - .map { notificationList -> notificationList.sortedByDescending { it.date } } - .catch { Timber.i("Loading notifications result: An exception occurred: `$it`") } - .onEach { - Timber.i("Loading notifications result: Success") - - if (it.isEmpty()) { - view?.run { - showContent(false) - showProgress(false) - showEmpty(true) - } - } else { - view?.run { - showContent(true) - showProgress(false) - showEmpty(false) - updateData(it) - } - } - } - .launch() - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - } else showError(message, error) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterView.kt deleted file mode 100644 index 1bfbe75e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/notificationscenter/NotificationsCenterView.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.wulkanowy.ui.modules.notificationscenter - -import io.github.wulkanowy.data.db.entities.Notification -import io.github.wulkanowy.ui.base.BaseView - -interface NotificationsCenterView : BaseView { - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun showProgress(show: Boolean) - - fun showEmpty(show: Boolean) - - fun showContent(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) -} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt index f4fa8e01..c1c56961 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.View import android.view.View.INVISIBLE import android.view.View.VISIBLE -import com.google.android.material.tabs.TabLayoutMediator import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.databinding.FragmentSchoolandteachersBinding @@ -25,13 +24,7 @@ class SchoolAndTeachersFragment : @Inject lateinit var presenter: SchoolAndTeachersPresenter - private val pagerAdapter by lazy { - BaseFragmentPagerAdapter( - fragmentManager = childFragmentManager, - pagesCount = 2, - lifecycle = lifecycle, - ) - } + private val pagerAdapter by lazy { BaseFragmentPagerAdapter(childFragmentManager) } companion object { fun newInstance() = SchoolAndTeachersFragment() @@ -48,36 +41,24 @@ class SchoolAndTeachersFragment : } override fun initView() { + with(pagerAdapter) { + containerId = binding.schoolandteachersViewPager.id + addFragmentsWithTitle(mapOf( + SchoolFragment.newInstance() to getString(R.string.school_title), + TeacherFragment.newInstance() to getString(R.string.teachers_title) + )) + } + with(binding.schoolandteachersViewPager) { adapter = pagerAdapter offscreenPageLimit = 2 setOnSelectPageListener(presenter::onPageSelected) } - with(pagerAdapter) { - containerId = binding.schoolandteachersViewPager.id - titleFactory = { - when (it) { - 0 -> getString(R.string.school_title) - 1 -> getString(R.string.teachers_title) - else -> throw IllegalStateException() - } - } - itemFactory = { - when (it) { - 0 -> SchoolFragment.newInstance() - 1 -> TeacherFragment.newInstance() - else -> throw IllegalStateException() - } - } - TabLayoutMediator( - binding.schoolandteachersTabLayout, - binding.schoolandteachersViewPager, - this - ).attach() + with(binding.schoolandteachersTabLayout) { + setupWithViewPager(binding.schoolandteachersViewPager) + setElevationCompat(context.dpToPx(4f)) } - - binding.schoolandteachersTabLayout.elevation = requireContext().dpToPx(4f) } override fun showContent(show: Boolean) { @@ -96,8 +77,7 @@ class SchoolAndTeachersFragment : } override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) { - (pagerAdapter.getFragmentInstance(index) as? SchoolAndTeachersChildView) - ?.onParentLoadData(forceRefresh) + (pagerAdapter.getFragmentInstance(index) as? SchoolAndTeachersChildView)?.onParentLoadData(forceRefresh) } override fun onDestroyView() { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt index 43823d6b..305f4e7d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/SchoolAndTeachersPresenter.kt @@ -1,6 +1,6 @@ package io.github.wulkanowy.ui.modules.schoolandteachers -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import kotlinx.coroutines.delay @@ -15,7 +15,8 @@ class SchoolAndTeachersPresenter @Inject constructor( override fun onAttachView(view: SchoolAndTeachersView) { super.onAttachView(view) - presenterScope.launch { + launch { + delay(150) view.initView() Timber.i("Message view was initialized") loadData() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt index fba2f040..d3f11007 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt @@ -12,7 +12,6 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment -import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.openDialer import io.github.wulkanowy.utils.openNavigation import javax.inject.Inject @@ -40,9 +39,7 @@ class SchoolFragment : BaseFragment(R.layout.fragment_sch override fun initView() { with(binding) { - schoolSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - schoolSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - schoolSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) + schoolSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } schoolErrorRetry.setOnClickListener { presenter.onRetry() } schoolErrorDetails.setOnClickListener { presenter.onDetailsClick() } @@ -53,14 +50,13 @@ class SchoolFragment : BaseFragment(R.layout.fragment_sch override fun updateData(data: School) { with(binding) { - val noDataString = getString(R.string.all_no_data) - schoolName.text = data.name.ifBlank { noDataString } - schoolAddress.text = data.address.ifBlank { noDataString } + schoolName.text = data.name + schoolAddress.text = data.address.ifBlank { "-" } schoolAddressButton.visibility = if (data.address.isNotBlank()) VISIBLE else GONE - schoolTelephone.text = data.contact.ifBlank { noDataString } + schoolTelephone.text = data.contact.ifBlank { "-" } schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) VISIBLE else GONE - schoolHeadmaster.text = data.headmaster.ifBlank { noDataString } - schoolPedagogue.text = data.pedagogue.ifBlank { noDataString } + schoolHeadmaster.text = data.headmaster + schoolPedagogue.text = data.pedagogue } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt index 262398b8..554d422d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolPresenter.kt @@ -1,13 +1,15 @@ package io.github.wulkanowy.ui.modules.schoolandteachers.school -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.repositories.SchoolRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.school.SchoolRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import kotlinx.coroutines.flow.catch +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -62,48 +64,46 @@ class SchoolPresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) schoolRepository.getSchoolInfo(student, semester, forceRefresh) - } - .logResourceStatus("load school info") - .onResourceData { - if (it != null) { + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading school info started") + Status.SUCCESS -> if (it.data != null) { + Timber.i("Loading teachers result: Success") view?.run { - address = it.address.ifBlank { null } - contact = it.contact.ifBlank { null } - updateData(it) + address = it.data.address.ifBlank { null } + contact = it.data.contact.ifBlank { null } + updateData(it.data) showContent(true) showEmpty(false) showErrorView(false) } + analytics.logEvent( + "load_item", + "type" to "school" + ) } else view?.run { Timber.i("Loading school result: No school info found") showContent(!isViewEmpty) showEmpty(isViewEmpty) showErrorView(false) } - } - .onResourceSuccess { - if (it != null) { - analytics.logEvent("load_item", "type" to "school") + Status.ERROR -> { + Timber.i("Loading school result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceNotLoading { - view?.run { - hideRefresh() - showProgress(false) - enableSwipe(true) - notifyParentDataLoaded() - } + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded() } - .onResourceError(errorHandler::dispatch) - .catch { - errorHandler.dispatch(it) - view?.notifyParentDataLoaded() - } - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -114,7 +114,6 @@ class SchoolPresenter @Inject constructor( showErrorView(true) showEmpty(false) showContent(false) - showProgress(false) } else showError(message, error) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt index b052a383..5914945b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherFragment.kt @@ -14,7 +14,6 @@ import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor import javax.inject.Inject @AndroidEntryPoint @@ -52,9 +51,7 @@ class TeacherFragment : BaseFragment(R.layout.fragment_t addItemDecoration(DividerItemDecoration(context)) } with(binding) { - teacherSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - teacherSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - teacherSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) + teacherSwipe.setOnRefreshListener { presenter.onSwipeRefresh() } teacherErrorRetry.setOnClickListener { presenter.onRetry() } teacherErrorDetails.setOnClickListener { presenter.onDetailsClick() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt index fef06328..0c58317b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/teacher/TeacherPresenter.kt @@ -1,13 +1,15 @@ package io.github.wulkanowy.ui.modules.schoolandteachers.teacher -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TeacherRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.teacher.TeacherRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import kotlinx.coroutines.flow.catch +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -50,44 +52,40 @@ class TeacherPresenter @Inject constructor( } private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) teacherRepository.getTeachers(student, semester, forceRefresh) - } - .logResourceStatus("load teachers data") - .onResourceData { - view?.run { - updateData(it - .filter { item -> item.name.isNotBlank() } - .sortedBy { it.name } + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading teachers data started") + Status.SUCCESS -> { + Timber.i("Loading teachers result: Success") + view?.run { + updateData(it.data!!.filter { item -> item.name.isNotBlank() }) + showContent(it.data.isNotEmpty()) + showEmpty(it.data.isEmpty()) + showErrorView(false) + } + analytics.logEvent( + "load_data", + "type" to "teachers", + "items" to it.data!!.size ) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - showErrorView(false) + } + Status.ERROR -> { + Timber.i("Loading teachers result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "teachers", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) + notifyParentDataLoaded() } - .onResourceNotLoading { - view?.run { - hideRefresh() - showProgress(false) - enableSwipe(true) - notifyParentDataLoaded() - } - } - .onResourceError(errorHandler::dispatch) - .catch { - errorHandler.dispatch(it) - view?.notifyParentDataLoaded() - } - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -97,7 +95,6 @@ class TeacherPresenter @Inject constructor( setErrorDetails(message) showErrorView(true) showEmpty(false) - showProgress(false) } else showError(message, error) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt deleted file mode 100644 index 731488a9..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.wulkanowy.ui.modules.schoolannouncement - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.databinding.ItemSchoolAnnouncementBinding -import io.github.wulkanowy.utils.parseUonetHtml -import io.github.wulkanowy.utils.toFormattedString -import javax.inject.Inject - -class SchoolAnnouncementAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = emptyList() - - var onItemClickListener: (SchoolAnnouncement) -> Unit = {} - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemSchoolAnnouncementBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - schoolAnnouncementItemDate.text = item.date.toFormattedString() - schoolAnnouncementItemType.text = item.subject - schoolAnnouncementItemContent.text = item.content.parseUonetHtml() - with(schoolAnnouncementItemAuthor) { - text = item.author - isVisible = !item.author.isNullOrBlank() - } - - root.setOnClickListener { onItemClickListener(item) } - } - } - - class ViewHolder(val binding: ItemSchoolAnnouncementBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt deleted file mode 100644 index c1c58441..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt +++ /dev/null @@ -1,55 +0,0 @@ -package io.github.wulkanowy.ui.modules.schoolannouncement - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.databinding.DialogSchoolAnnouncementBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.parseUonetHtml -import io.github.wulkanowy.utils.serializable -import io.github.wulkanowy.utils.toFormattedString - -@AndroidEntryPoint -class SchoolAnnouncementDialog : BaseDialogFragment() { - - private lateinit var announcement: SchoolAnnouncement - - companion object { - - private const val ARGUMENT_KEY = "item" - - fun newInstance(announcement: SchoolAnnouncement) = SchoolAnnouncementDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to announcement) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - announcement = requireArguments().serializable(ARGUMENT_KEY) - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogSchoolAnnouncementBinding.inflate(layoutInflater) - .apply { binding = this }.root - ) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - with(binding) { - announcementDialogSubjectValue.text = announcement.subject - announcementDialogDateValue.text = announcement.date.toFormattedString() - announcementDialogDescriptionValue.text = announcement.content.parseUonetHtml() - - announcementDialogClose.setOnClickListener { dismiss() } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementFragment.kt deleted file mode 100644 index baf2824b..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementFragment.kt +++ /dev/null @@ -1,113 +0,0 @@ -package io.github.wulkanowy.ui.modules.schoolannouncement - -import android.os.Bundle -import android.view.View -import androidx.recyclerview.widget.LinearLayoutManager -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.databinding.FragmentSchoolAnnouncementBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.getThemeAttrColor -import javax.inject.Inject - -@AndroidEntryPoint -class SchoolAnnouncementFragment : - BaseFragment(R.layout.fragment_school_announcement), - SchoolAnnouncementView, MainView.TitledView { - - @Inject - lateinit var presenter: SchoolAnnouncementPresenter - - @Inject - lateinit var schoolAnnouncementAdapter: SchoolAnnouncementAdapter - - companion object { - fun newInstance() = SchoolAnnouncementFragment() - } - - override val titleStringId: Int - get() = R.string.school_announcement_title - - override val isViewEmpty: Boolean - get() = schoolAnnouncementAdapter.items.isEmpty() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentSchoolAnnouncementBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - with(binding.directorInformationRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = schoolAnnouncementAdapter.apply { - onItemClickListener = presenter::onItemClickListener - } - addItemDecoration(DividerItemDecoration(context)) - } - with(binding) { - directorInformationSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - directorInformationSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - directorInformationSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) - directorInformationErrorRetry.setOnClickListener { presenter.onRetry() } - directorInformationErrorDetails.setOnClickListener { presenter.onDetailsClick() } - } - } - - override fun updateData(data: List) { - with(schoolAnnouncementAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun clearData() { - with(schoolAnnouncementAdapter) { - items = listOf() - notifyDataSetChanged() - } - } - - override fun showEmpty(show: Boolean) { - binding.directorInformationEmpty.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showErrorView(show: Boolean) { - binding.directorInformationError.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun setErrorDetails(message: String) { - binding.directorInformationErrorMessage.text = message - } - - override fun showProgress(show: Boolean) { - binding.directorInformationProgress.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun enableSwipe(enable: Boolean) { - binding.directorInformationSwipe.isEnabled = enable - } - - override fun showContent(show: Boolean) { - binding.directorInformationRecycler.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showRefresh(show: Boolean) { - binding.directorInformationSwipe.isRefreshing = show - } - - override fun openSchoolAnnouncementDialog(item: SchoolAnnouncement) { - (activity as? MainActivity)?.showDialogFragment(SchoolAnnouncementDialog.newInstance(item)) - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementPresenter.kt deleted file mode 100644 index f77a8833..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementPresenter.kt +++ /dev/null @@ -1,95 +0,0 @@ -package io.github.wulkanowy.ui.modules.schoolannouncement - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import timber.log.Timber -import javax.inject.Inject - -class SchoolAnnouncementPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val analytics: AnalyticsHelper, - private val schoolAnnouncementRepository: SchoolAnnouncementRepository, -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var lastError: Throwable - - override fun onAttachView(view: SchoolAnnouncementView) { - super.onAttachView(view) - view.initView() - Timber.i("School announcement view was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData() - } - - fun onSwipeRefresh() { - Timber.i("Force refreshing the School announcement") - loadData(true) - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData(true) - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - fun onItemClickListener(item: SchoolAnnouncement) { - view?.openSchoolAnnouncementDialog(item) - } - - private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { - val student = studentRepository.getCurrentStudent() - schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh) - } - .logResourceStatus("load school announcement") - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) - } - } - .onResourceSuccess { - analytics.logEvent( - "load_school_announcement", - "items" to it.size - ) - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch("load_data") - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - } else showError(message, error) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementView.kt deleted file mode 100644 index 383d0f29..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementView.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.github.wulkanowy.ui.modules.schoolannouncement - -import io.github.wulkanowy.data.db.entities.SchoolAnnouncement -import io.github.wulkanowy.ui.base.BaseView - -interface SchoolAnnouncementView : BaseView { - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun clearData() - - fun showEmpty(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun openSchoolAnnouncementDialog(item: SchoolAnnouncement) - - fun showProgress(show: Boolean) - - fun enableSwipe(enable: Boolean) - - fun showContent(show: Boolean) - - fun showRefresh(show: Boolean) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt index f4503fad..6f4a695d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt @@ -1,16 +1,21 @@ package io.github.wulkanowy.ui.modules.settings +import android.content.Context import android.content.SharedPreferences import android.os.Bundle -import android.view.View +import androidx.appcompat.app.AlertDialog import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.PreferenceScreen +import com.thelittlefireman.appkillermanager.AppKillerManager +import com.thelittlefireman.appkillermanager.exceptions.NoActionFoundException +import com.yariksoffice.lingver.Lingver import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository +import io.github.wulkanowy.ui.base.BaseActivity +import io.github.wulkanowy.ui.base.ErrorDialog import io.github.wulkanowy.ui.modules.main.MainView -import timber.log.Timber +import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.openInternetBrowser import javax.inject.Inject @AndroidEntryPoint @@ -18,48 +23,127 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener, MainView.TitledView, SettingsView { - companion object { + @Inject + lateinit var presenter: SettingsPresenter + @Inject + lateinit var appInfo: AppInfo + + @Inject + lateinit var lingver: Lingver + + companion object { fun newInstance() = SettingsFragment() } override val titleStringId get() = R.string.settings_title - @Inject - lateinit var preferencesRepository: PreferencesRepository + override val syncSuccessString get() = getString(R.string.pref_services_message_sync_success) + + override val syncFailedString get() = getString(R.string.pref_services_message_sync_failed) + + override fun onAttach(context: Context) { + super.onAttach(context) + } + + override fun initView() { + findPreference(getString(R.string.pref_key_services_force_sync))?.run { + onPreferenceClickListener = Preference.OnPreferenceClickListener { + presenter.onSyncNowClicked() + true + } + } + findPreference(getString(R.string.pref_key_notifications_fix_issues))?.run { + isVisible = AppKillerManager.isDeviceSupported() && AppKillerManager.isAnyActionAvailable(requireContext()) + setOnPreferenceClickListener { + presenter.onFixSyncIssuesClicked() + true + } + } + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + presenter.onAttachView(this) + } override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.scheme_preferences, rootKey) + findPreference(getString(R.string.pref_key_notification_debug))?.isVisible = appInfo.isDebug + } - val prefScreen: PreferenceScreen? = findPreference("settings_preferences") - val prefDeveloper: Preference? = findPreference("mod_settings") + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + presenter.onSharedPreferenceChanged(key) + } - if (!preferencesRepository.developerMode && prefScreen != null && prefDeveloper != null) { - prefScreen.removePreference(prefDeveloper) + override fun recreateView() { + activity?.recreate() + } + + override fun updateLanguage(langCode: String) { + lingver.setLocale(requireContext(), langCode) + } + + override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) { + findPreference(serviceEnablesKey)?.run { + summary = if (isHolidays) getString(R.string.pref_services_suspended) else "" + isEnabled = !isHolidays } - - Timber.i("Settings view was initialized") } - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences, rootKey) + override fun setSyncInProgress(inProgress: Boolean) { + if (activity == null || !isAdded) return + + findPreference(getString(R.string.pref_key_services_force_sync))?.run { + isEnabled = !inProgress + summary = if (inProgress) getString(R.string.pref_services_sync_in_progress) else "" + } } - override fun showError(text: String, error: Throwable) {} + override fun showError(text: String, error: Throwable) { + (activity as? BaseActivity<*, *>)?.showError(text, error) + } - override fun showMessage(text: String) {} + override fun showMessage(text: String) { + (activity as? BaseActivity<*, *>)?.showMessage(text) + } - override fun showExpiredCredentialsDialog() {} + override fun showExpiredDialog() { + (activity as? BaseActivity<*, *>)?.showExpiredDialog() + } - override fun onCaptchaVerificationRequired(url: String?) = Unit + override fun openClearLoginView() { + (activity as? BaseActivity<*, *>)?.openClearLoginView() + } - override fun showDecryptionFailedDialog() {} + override fun showErrorDetailsDialog(error: Throwable) { + ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) + } - override fun openClearLoginView() {} + override fun showFixSyncDialog() { + AlertDialog.Builder(requireContext()) + .setTitle(R.string.pref_notify_fix_sync_issues) + .setMessage(R.string.pref_notify_fix_sync_issues_message) + .setNegativeButton(android.R.string.cancel) { _, _ -> } + .setPositiveButton(R.string.pref_notify_fix_sync_issues_settings_button) { _, _ -> + try { + AppKillerManager.doActionPowerSaving(requireContext()) + AppKillerManager.doActionAutoStart(requireContext()) + AppKillerManager.doActionNotification(requireContext()) + } catch (e: NoActionFoundException) { + requireContext().openInternetBrowser("https://dontkillmyapp.com/${AppKillerManager.getDevice()?.manufacturer}", ::showMessage) + } + } + .show() + } - override fun showErrorDetailsDialog(error: Throwable) {} + override fun onResume() { + super.onResume() + preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + } - override fun showChangePasswordSnackbar(redirectUrl: String) {} - - override fun showAuthDialog() {} + override fun onPause() { + super.onPause() + preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt similarity index 57% rename from app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt index 594e097a..e640dd60 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt @@ -1,44 +1,54 @@ -package io.github.wulkanowy.ui.modules.settings.sync +package io.github.wulkanowy.ui.modules.settings import androidx.work.WorkInfo -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import com.chuckerteam.chucker.api.ChuckerCollector +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.AnalyticsHelper import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.time.LocalDate.now import javax.inject.Inject -class SyncPresenter @Inject constructor( +class SettingsPresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, private val preferencesRepository: PreferencesRepository, + private val timetableNotificationHelper: TimetableNotificationSchedulerHelper, private val analytics: AnalyticsHelper, private val syncManager: SyncManager, -) : BasePresenter(errorHandler, studentRepository) { + private val chuckerCollector: ChuckerCollector, + private val appInfo: AppInfo +) : BasePresenter(errorHandler, studentRepository) { - override fun onAttachView(view: SyncView) { + override fun onAttachView(view: SettingsView) { super.onAttachView(view) - Timber.i("Settings sync view was initialized") + Timber.i("Settings view was initialized") view.setServicesSuspended(preferencesRepository.serviceEnableKey, now().isHolidays) view.initView() - setSyncDateInView() } - fun onSharedPreferenceChanged(key: String?) { - key ?: return + fun onSharedPreferenceChanged(key: String) { Timber.i("Change settings $key") preferencesRepository.apply { when (key) { serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startPeriodicSyncWorker() else stopSyncWorker() } servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startPeriodicSyncWorker(true) + isDebugNotificationEnableKey -> chuckerCollector.showNotification = isDebugNotificationEnable + appThemeKey -> view?.recreateView() + isUpcomingLessonsNotificationsEnableKey -> if (!isUpcomingLessonsNotificationsEnable) timetableNotificationHelper.cancelNotification() + appLanguageKey -> view?.run { + updateLanguage(if (appLanguage == "system") appInfo.systemLanguage else appLanguage) + recreateView() + } } } analytics.logEvent("setting_changed", "name" to key) @@ -47,44 +57,30 @@ class SyncPresenter @Inject constructor( fun onSyncNowClicked() { view?.run { syncManager.startOneTimeSyncWorker().onEach { workInfo -> - when (workInfo?.state) { + when (workInfo.state) { WorkInfo.State.ENQUEUED -> { setSyncInProgress(true) Timber.i("Setting sync now started") analytics.logEvent("sync_now", "status" to "started") } - WorkInfo.State.SUCCEEDED -> { showMessage(syncSuccessString) analytics.logEvent("sync_now", "status" to "success") } - WorkInfo.State.FAILED -> { - showError( - syncFailedString, - Throwable( - message = workInfo.outputData.getString("error_message"), - cause = Throwable(workInfo.outputData.getString("error_stack")) - ) - ) + showError(syncFailedString, Throwable(workInfo.outputData.getString("error"))) analytics.logEvent("sync_now", "status" to "failed") } - - else -> Timber.d("Sync now state: ${workInfo?.state}") - } - if (workInfo?.state?.isFinished == true) { - setSyncInProgress(false) - setSyncDateInView() + else -> Timber.d("Sync now state: ${workInfo.state}") } + if (workInfo.state.isFinished) setSyncInProgress(false) }.catch { Timber.e(it, "Sync now failed") }.launch("sync") } } - private fun setSyncDateInView() { - val lastSyncDate = preferencesRepository.lasSyncDate ?: return - - view?.setLastSyncDate(lastSyncDate.toFormattedString("dd.MM.yyyy HH:mm:ss")) + fun onFixSyncIssuesClicked() { + view?.showFixSyncDialog() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt index 79f91bc5..b647c0b7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt @@ -2,4 +2,21 @@ package io.github.wulkanowy.ui.modules.settings import io.github.wulkanowy.ui.base.BaseView -interface SettingsView : BaseView \ No newline at end of file +interface SettingsView : BaseView { + + val syncSuccessString: String + + val syncFailedString: String + + fun initView() + + fun recreateView() + + fun updateLanguage(langCode: String) + + fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) + + fun setSyncInProgress(inProgress: Boolean) + + fun showFixSyncDialog() +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedFragment.kt deleted file mode 100644 index 3ef1a80a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedFragment.kt +++ /dev/null @@ -1,86 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.advanced - -import android.content.SharedPreferences -import android.os.Bundle -import android.view.View -import androidx.preference.PreferenceFragmentCompat -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.base.ErrorDialog -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.AppInfo -import javax.inject.Inject - -@AndroidEntryPoint -class AdvancedFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener, - MainView.TitledView, AdvancedView { - - @Inject - lateinit var presenter: AdvancedPresenter - - @Inject - lateinit var appInfo: AppInfo - - override val titleStringId get() = R.string.pref_settings_advanced_title - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences_advanced, rootKey) - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - presenter.onSharedPreferenceChanged(key) - } - - override fun showError(text: String, error: Throwable) { - (activity as? BaseActivity<*, *>)?.showError(text, error) - } - - override fun showMessage(text: String) { - (activity as? BaseActivity<*, *>)?.showMessage(text) - } - - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun openClearLoginView() { - (activity as? BaseActivity<*, *>)?.openClearLoginView() - } - - override fun showErrorDetailsDialog(error: Throwable) { - ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - - override fun onResume() { - super.onResume() - preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) - } - - override fun onPause() { - super.onPause() - preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedPresenter.kt deleted file mode 100644 index 4bc24594..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedPresenter.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.advanced - -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import timber.log.Timber -import javax.inject.Inject - -class AdvancedPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val analytics: AnalyticsHelper, -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: AdvancedView) { - super.onAttachView(view) - Timber.i("Settings advanced view was initialized") - } - - fun onSharedPreferenceChanged(key: String?) { - key ?: return - Timber.i("Change settings $key") - analytics.logEvent("setting_changed", "name" to key) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedView.kt deleted file mode 100644 index 90c0474e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/advanced/AdvancedView.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.advanced - -import io.github.wulkanowy.ui.base.BaseView - -interface AdvancedView : BaseView diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceFragment.kt deleted file mode 100644 index 62544f83..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceFragment.kt +++ /dev/null @@ -1,122 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance - -import android.content.SharedPreferences -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SeekBarPreference -import com.yariksoffice.lingver.Lingver -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.base.ErrorDialog -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.AppInfo -import javax.inject.Inject - -@AndroidEntryPoint -class AppearanceFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener, - MainView.TitledView, AppearanceView { - - @Inject - lateinit var presenter: AppearancePresenter - - @Inject - lateinit var appInfo: AppInfo - - @Inject - lateinit var lingver: Lingver - - override val titleStringId get() = R.string.pref_settings_appearance_title - - companion object { - fun withFocusedPreference(key: String) = AppearanceFragment().apply { - arguments = bundleOf(FOCUSED_KEY to key) - } - - private const val FOCUSED_KEY = "focusedKey" - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - arguments?.getString(FOCUSED_KEY)?.let { scrollToPreference(it) } - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences_appearance, rootKey) - val attendanceTargetPref = - findPreference(requireContext().getString(R.string.pref_key_attendance_target))!! - attendanceTargetPref.setOnPreferenceChangeListener { _, newValueObj -> - val newValue = (((newValueObj as Int).toDouble() + 2.5) / 5).toInt() * 5 - attendanceTargetPref.value = - newValue.coerceIn(attendanceTargetPref.min, attendanceTargetPref.max) - - false - } - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - presenter.onSharedPreferenceChanged(key) - } - - override fun recreateView() { - activity?.recreate() - } - - override fun updateLanguage(langCode: String) { - lingver.setLocale(requireContext(), langCode) - } - - override fun updateLanguageToFollowSystem() { - lingver.setFollowSystemLocale(requireContext()) - } - - override fun showError(text: String, error: Throwable) { - (activity as? BaseActivity<*, *>)?.showError(text, error) - } - - override fun showMessage(text: String) { - (activity as? BaseActivity<*, *>)?.showMessage(text) - } - - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun openClearLoginView() { - (activity as? BaseActivity<*, *>)?.openClearLoginView() - } - - override fun showErrorDetailsDialog(error: Throwable) { - ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - - override fun onResume() { - super.onResume() - preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) - } - - override fun onPause() { - super.onPause() - preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearancePresenter.kt deleted file mode 100644 index d3410ea8..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearancePresenter.kt +++ /dev/null @@ -1,46 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance - -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.AppInfo -import timber.log.Timber -import javax.inject.Inject - -class AppearancePresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val preferencesRepository: PreferencesRepository, - private val analytics: AnalyticsHelper, - private val appInfo: AppInfo -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: AppearanceView) { - super.onAttachView(view) - Timber.i("Settings appearance view was initialized") - } - - fun onSharedPreferenceChanged(key: String?) { - key ?: return - Timber.i("Change settings $key") - - preferencesRepository.apply { - when (key) { - appThemeKey -> view?.recreateView() - appLanguageKey -> view?.run { - if (appLanguage == "system") { - updateLanguageToFollowSystem() - analytics.logEvent("language", "setting_changed" to appInfo.systemLanguage) - } else { - updateLanguage(appLanguage) - analytics.logEvent("language", "setting_changed" to appLanguage) - } - recreateView() - } - } - } - analytics.logEvent("setting_changed", "name" to key) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceView.kt deleted file mode 100644 index ecee4f42..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/AppearanceView.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance - -import io.github.wulkanowy.ui.base.BaseView - -interface AppearanceView : BaseView { - - fun recreateView() - - fun updateLanguage(langCode: String) - - fun updateLanguageToFollowSystem() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/AppMenuItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/AppMenuItem.kt deleted file mode 100644 index f522913a..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/AppMenuItem.kt +++ /dev/null @@ -1,206 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.modules.Destination -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient - -@Serializable -sealed class AppMenuItem { - - companion object { - val defaultAppMenuItemList = setOf( - DashboardAppMenuItem(), - GradeAppMenuItem(), - TimetableAppMenuItem(), - AttendanceAppMenuItem(), - ExamsAppMenuItem(), - HomeworkAppMenuItem(), - NoteAppMenuItem(), - LuckyNumberAppMenuItem(), - SchoolAnnouncementsAppMenuItem(), - SchoolAndTeachersAppMenuItem(), - MobileDevicesAppMenuItem(), - ConferenceAppMenuItem(), - MessageAppMenuItem() - ).sortedBy { it.order } - } - - // https://youtrack.jetbrains.com/issue/KT-38958 - abstract var order: Int - - abstract val icon: Int - - abstract val title: Int - - abstract val destinationType: Destination.Type - - @Serializable - data class DashboardAppMenuItem(override var order: Int = 0) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_main_dashboard - - @Transient - override val title = R.string.dashboard_title - - @Transient - override val destinationType = Destination.Type.DASHBOARD - } - - @Serializable - data class GradeAppMenuItem(override var order: Int = 1) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_main_grade - - @Transient - override val title = R.string.grade_title - - @Transient - override val destinationType = Destination.Type.GRADE - } - - @Serializable - data class AttendanceAppMenuItem(override var order: Int = 2) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_main_attendance - - @Transient - override val title = R.string.attendance_title - - @Transient - override val destinationType = Destination.Type.ATTENDANCE - } - - @Serializable - data class TimetableAppMenuItem(override var order: Int = 3) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_main_timetable - - @Transient - override val title = R.string.timetable_title - - @Transient - override val destinationType = Destination.Type.TIMETABLE - } - - @Serializable - data class MessageAppMenuItem(override var order: Int = 4) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_messages - - @Transient - override val title = R.string.message_title - - @Transient - override val destinationType = Destination.Type.MESSAGE - } - - @Serializable - data class ExamsAppMenuItem(override var order: Int = 5) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_main_exam - - @Transient - override val title = R.string.exam_title - - @Transient - override val destinationType = Destination.Type.EXAM - } - - @Serializable - data class HomeworkAppMenuItem(override var order: Int = 6) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_homework - - @Transient - override val title = R.string.homework_title - - @Transient - override val destinationType = Destination.Type.HOMEWORK - } - - @Serializable - data class NoteAppMenuItem(override var order: Int = 7) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_note - - @Transient - override val title = R.string.note_title - - @Transient - override val destinationType = Destination.Type.NOTE - } - - @Serializable - data class LuckyNumberAppMenuItem(override var order: Int = 8) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_lucky_number - - @Transient - override val title = R.string.lucky_number_title - - @Transient - override val destinationType = Destination.Type.LUCKY_NUMBER - } - - @Serializable - data class ConferenceAppMenuItem(override var order: Int = 9) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_conferences - - @Transient - override val title = R.string.conferences_title - - @Transient - override val destinationType = Destination.Type.CONFERENCE - } - - @Serializable - data class SchoolAnnouncementsAppMenuItem(override var order: Int = 10) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_all_about - - @Transient - override val title = R.string.school_announcement_title - - @Transient - override val destinationType = Destination.Type.SCHOOL_ANNOUNCEMENT - } - - @Serializable - data class SchoolAndTeachersAppMenuItem(override var order: Int = 11) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_schoolandteachers - - @Transient - override val title = R.string.schoolandteachers_title - - @Transient - override val destinationType = Destination.Type.SCHOOL_AND_TEACHERS - } - - @Serializable - data class MobileDevicesAppMenuItem(override var order: Int = 12) : AppMenuItem() { - - @Transient - override val icon = R.drawable.ic_more_mobile_devices - - @Transient - override val title = R.string.mobile_devices_title - - @Transient - override val destinationType = Destination.Type.MOBILE_DEVICE - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuItemMoveCallback.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuItemMoveCallback.kt deleted file mode 100644 index 49196fad..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuItemMoveCallback.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.RecyclerView -import java.util.* - -class MenuItemMoveCallback( - private val menuOrderAdapter: MenuOrderAdapter, - private var onUserInteractionEndListener: (List) -> Unit = {} -) : ItemTouchHelper.Callback() { - - override fun isLongPressDragEnabled() = true - - override fun isItemViewSwipeEnabled() = false - - override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - //Not implemented - } - - override fun getMovementFlags( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder - ) = makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) - - override fun onMove( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ): Boolean { - val list = menuOrderAdapter.items.toMutableList() - - Collections.swap(list, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition) - - menuOrderAdapter.submitList(list) - return true - } - - override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { - super.clearView(recyclerView, viewHolder) - - onUserInteractionEndListener(menuOrderAdapter.items.toList()) - } -} - diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderAdapter.kt deleted file mode 100644 index 6bdd2fe0..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderAdapter.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.databinding.ItemMenuOrderBinding -import javax.inject.Inject - -class MenuOrderAdapter @Inject constructor() : - RecyclerView.Adapter() { - - val items = mutableListOf() - - fun submitList(newItems: List) { - val diffResult = DiffUtil.calculateDiff(DiffCallback(newItems, items.toMutableList())) - - with(items) { - clear() - addAll(newItems) - } - - diffResult.dispatchUpdatesTo(this) - } - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemMenuOrderBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position].appMenuItem - - with(holder.binding) { - menuOrderItemTitle.setText(item.title) - menuOrderItemIcon.setImageResource(item.icon) - } - } - - class ViewHolder(val binding: ItemMenuOrderBinding) : RecyclerView.ViewHolder(binding.root) - - private class DiffCallback( - private val oldList: List, - private val newList: List - ) : DiffUtil.Callback() { - - override fun getNewListSize() = newList.size - - override fun getOldListSize() = oldList.size - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = - oldList[oldItemPosition] == newList[newItemPosition] - - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) = - oldList[oldItemPosition].appMenuItem.destinationType == newList[newItemPosition].appMenuItem.destinationType - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderDividerItemDecoration.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderDividerItemDecoration.kt deleted file mode 100644 index 21a7f5e8..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderDividerItemDecoration.kt +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import android.content.Context -import android.graphics.Canvas -import android.graphics.Rect -import android.graphics.drawable.ShapeDrawable -import android.view.View -import androidx.core.graphics.drawable.DrawableCompat -import androidx.core.view.forEach -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.R -import io.github.wulkanowy.utils.getThemeAttrColor - -class MenuOrderDividerItemDecoration(private val context: Context) : - DividerItemDecoration(context, VERTICAL) { - - private val dividerDrawable = ShapeDrawable() - .apply { - DrawableCompat.setTint(this, context.getThemeAttrColor(R.attr.colorDivider)) - } - - override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { - canvas.save() - val dividerLeft = parent.paddingLeft - val dividerRight = parent.width - parent.paddingRight - - parent.forEach { - if (parent.getChildAdapterPosition(it) == 3) { - val params = it.layoutParams as RecyclerView.LayoutParams - val dividerTop = it.bottom + params.bottomMargin - val dividerBottom = dividerTop + dividerDrawable.intrinsicHeight - - dividerDrawable.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom + 30) - dividerDrawable.draw(canvas) - } - } - - canvas.restore() - } - - override fun getItemOffsets( - outRect: Rect, view: View, parent: RecyclerView, - state: RecyclerView.State - ) { - if (parent.getChildAdapterPosition(view) == 3) { - outRect.bottom = dividerDrawable.intrinsicHeight + 30 - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderFragment.kt deleted file mode 100644 index e08fc5dd..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderFragment.kt +++ /dev/null @@ -1,101 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.activity.addCallback -import androidx.core.view.MenuProvider -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.SimpleItemAnimator -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.FragmentMenuOrderBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import javax.inject.Inject - - -@AndroidEntryPoint -class MenuOrderFragment : BaseFragment(R.layout.fragment_menu_order), - MenuOrderView, MainView.TitledView { - - @Inject - lateinit var presenter: MenuOrderPresenter - - @Inject - lateinit var menuOrderAdapter: MenuOrderAdapter - - override val titleStringId = R.string.menu_order_title - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentMenuOrderBinding.bind(view) - presenter.onAttachView(this) - } - - override fun initView() { - val itemTouchHelper = ItemTouchHelper( - MenuItemMoveCallback(menuOrderAdapter, presenter::onDragAndDropEnd) - ) - - itemTouchHelper.attachToRecyclerView(binding.menuOrderRecycler) - - with(binding.menuOrderRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = menuOrderAdapter - addItemDecoration(MenuOrderDividerItemDecoration(context)) - addItemDecoration(DividerItemDecoration(context)) - (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false - } - - requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { - presenter.onBackSelected() - } - - initializeToolbar() - } - - private fun initializeToolbar() { - requireActivity().addMenuProvider(object : MenuProvider { - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - } - - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - if (menuItem.itemId == android.R.id.home) { - presenter.onBackSelected() - return true - } - return false - } - - }, viewLifecycleOwner) - } - - override fun updateData(data: List) { - menuOrderAdapter.submitList(data) - } - - override fun restartApp() { - startActivity(MainActivity.getStartIntent(requireContext())) - requireActivity().finishAffinity() - } - - override fun popView() { - (activity as? MainActivity?)?.popView() - } - - override fun showRestartConfirmationDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.menu_order_confirm_title) - .setMessage(R.string.menu_order_confirm_content) - .setPositiveButton(R.string.menu_order_confirm_restart) { _, _ -> presenter.onConfirmRestart() } - .setNegativeButton(R.string.all_cancel) { _, _ -> presenter.onCancelRestart() } - .show() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderItem.kt deleted file mode 100644 index b82bc1bd..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderItem.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -data class MenuOrderItem( - val appMenuItem: AppMenuItem, - val order: Int -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderPresenter.kt deleted file mode 100644 index 1c90cc5e..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderPresenter.kt +++ /dev/null @@ -1,64 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import timber.log.Timber -import javax.inject.Inject - -class MenuOrderPresenter @Inject constructor( - studentRepository: StudentRepository, - errorHandler: ErrorHandler, - private val preferencesRepository: PreferencesRepository -) : BasePresenter(errorHandler, studentRepository) { - - private var updatedMenuOrderItems = emptyList() - - override fun onAttachView(view: MenuOrderView) { - super.onAttachView(view) - view.initView() - Timber.i("Menu order view was initialized") - loadData() - } - - private fun loadData() { - val savedMenuItemList = (preferencesRepository.appMenuItemOrder) - .sortedBy { it.order } - .map { MenuOrderItem(it, it.order) } - - view?.updateData(savedMenuItemList) - } - - fun onDragAndDropEnd(list: List) { - val updatedList = list.mapIndexed { index, menuOrderItem -> - menuOrderItem.copy(order = index) - } - - updatedMenuOrderItems = updatedList - view?.updateData(updatedList) - } - - fun onBackSelected() { - if (updatedMenuOrderItems.isNotEmpty()) { - view?.showRestartConfirmationDialog() - } else { - view?.popView() - } - } - - fun onConfirmRestart() { - updatedMenuOrderItems.forEach { - it.appMenuItem.apply { - order = it.order - } - } - - preferencesRepository.appMenuItemOrder = updatedMenuOrderItems.map { it.appMenuItem } - view?.restartApp() - } - - fun onCancelRestart() { - view?.popView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderView.kt deleted file mode 100644 index 264e68cc..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/appearance/menuorder/MenuOrderView.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.appearance.menuorder - -import io.github.wulkanowy.ui.base.BaseView - -interface MenuOrderView : BaseView { - - fun initView() - - fun updateData(data: List) - - fun restartApp() - - fun showRestartConfirmationDialog() - - fun popView() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsFragment.kt deleted file mode 100644 index e45a5443..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsFragment.kt +++ /dev/null @@ -1,147 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.mod_settings - -import android.content.SharedPreferences -import android.os.Bundle -import android.view.View -import androidx.appcompat.app.AlertDialog -import androidx.preference.EditTextPreference -import androidx.preference.MultiSelectListPreference -import androidx.preference.PreferenceFragmentCompat -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.base.ErrorDialog -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.AppInfo -import timber.log.Timber -import javax.inject.Inject - -@AndroidEntryPoint -class ModSettingsFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener, - MainView.TitledView, ModSettingsView { - - @Inject - lateinit var presenter: ModSettingsPresenter - - @Inject - lateinit var appInfo: AppInfo - - @Inject - lateinit var preferencesRepository: PreferencesRepository - - override val titleStringId get() = R.string.pref_mod_settings_title - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences_mod_settings, rootKey) - - val attendancePercentagePreference: EditTextPreference? = findPreference("attendance_percentage") - attendancePercentagePreference?.setOnBindEditTextListener { editText -> - editText.inputType = android.text.InputType.TYPE_CLASS_NUMBER or android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL - editText.filters = arrayOf( - android.text.InputFilter { source, _, _, dest, _, _ -> - if (source == "." && dest.isEmpty()) { - return@InputFilter "0." - } - - val input = dest.toString() + source.toString() - if (input == "100.00") { - return@InputFilter null - } - - val inputVal = input.toFloatOrNull() - if (inputVal != null && inputVal >= 0 && inputVal <= 100) { - null - } else { - "" - } - } - ) - } - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - presenter.onSharedPreferenceChanged(key) - } - - override fun showError(text: String, error: Throwable) { - (activity as? BaseActivity<*, *>)?.showError(text, error) - } - - override fun showMessage(text: String) { - (activity as? BaseActivity<*, *>)?.showMessage(text) - } - - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun openClearLoginView() { - (activity as? BaseActivity<*, *>)?.openClearLoginView() - } - - override fun showErrorDetailsDialog(error: Throwable) { - ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - - override fun onResume() { - super.onResume() - preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) - } - - override fun onPause() { - super.onPause() - preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) - } - - override fun showAttendanceSettings(items: List) { - val entries = requireContext().resources.getStringArray(R.array.mod_settings_attendance_entries) - val values = requireContext().resources.getStringArray(R.array.mod_settings_attendance_values) - val selectedItemsState = values.map { value -> items.any { it.name == value } } - - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.attendance_title) - .setMultiChoiceItems(entries, selectedItemsState.toBooleanArray()) { _, _, _ -> } - .setPositiveButton(android.R.string.ok) { dialog, _ -> - val selectedState = (dialog as AlertDialog).listView.checkedItemPositions - val selectedValues = values - .filterIndexed { index, _ -> selectedState[index] } - .map { DashboardItem.HiddenAttendanceTile.valueOf(it) } - - Timber.i("Selected attendance to hide: $selectedValues") - presenter.onAttendanceSettingsSelected(selectedValues) - } - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .show() - } - - override fun restartApp() { - startActivity(MainActivity.getStartIntent(requireContext())) - requireActivity().finishAffinity() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsPresenter.kt deleted file mode 100644 index 10bbefbc..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsPresenter.kt +++ /dev/null @@ -1,40 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.mod_settings - -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem -import io.github.wulkanowy.utils.AnalyticsHelper -import timber.log.Timber -import javax.inject.Inject - -class ModSettingsPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val analytics: AnalyticsHelper, - private val preferencesRepository: PreferencesRepository -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: ModSettingsView) { - super.onAttachView(view) - - Timber.i("Mod settings view was initialized") - } - - fun onSharedPreferenceChanged(key: String?) { - key ?: return - Timber.i("Change mod settings $key") - analytics.logEvent("setting_changed", "name" to key) - } - - fun onHiddenGradesSelected(selectedItems: List) { - preferencesRepository.hiddenGrades = selectedItems - view?.restartApp() - } - - fun onAttendanceSettingsSelected(selectedValues: List) { - preferencesRepository.hiddenAttendanceItems = selectedValues - view?.restartApp() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsView.kt deleted file mode 100644 index 0133d2a4..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/mod_settings/ModSettingsView.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.mod_settings - -import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.dashboard.DashboardItem - -interface ModSettingsView : BaseView { - fun restartApp() - fun showAttendanceSettings(items: List) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt deleted file mode 100644 index 0bf9ddad..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt +++ /dev/null @@ -1,257 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.notifications - -import android.content.Intent -import android.content.SharedPreferences -import android.content.pm.PackageManager -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.app.NotificationManagerCompat -import androidx.core.content.ContextCompat -import androidx.preference.Preference -import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreferenceCompat -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.thelittlefireman.appkillermanager.AppKillerManager -import com.thelittlefireman.appkillermanager.exceptions.NoActionFoundException -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.base.ErrorDialog -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.openInternetBrowser -import io.github.wulkanowy.utils.openNotificationSettings -import javax.inject.Inject - -@AndroidEntryPoint -class NotificationsFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener, - MainView.TitledView, NotificationsView { - - @Inject - lateinit var presenter: NotificationsPresenter - - @Inject - lateinit var appInfo: AppInfo - - override val titleStringId get() = R.string.pref_settings_notifications_title - - private val notificationsPermission = "android.permission.POST_NOTIFICATIONS" - - override val isNotificationPermissionGranted: Boolean - get() = ContextCompat.checkSelfPermission( - requireContext(), notificationsPermission - ) == PackageManager.PERMISSION_GRANTED - - override val isNotificationPiggybackPermissionGranted: Boolean - get() { - val packageNameList = - NotificationManagerCompat.getEnabledListenerPackages(requireContext()) - val appPackageName = requireContext().packageName - - return appPackageName in packageNameList - } - - private val requestPermissionLauncher = - registerForActivityResult(ActivityResultContracts.RequestPermission()) { - if (it) { - presenter.onNotificationsPermissionResult() - } else openNotificationsPermissionDialog() - } - - private val notificationSettingsPiggybackContract = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - presenter.onNotificationPiggybackPermissionResult() - } - - private val notificationSettingsExactAlarmsContract = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - presenter.onNotificationExactAlarmPermissionResult() - } - - override fun initView(showDebugNotificationSwitch: Boolean) { - findPreference(getString(R.string.pref_key_notification_debug))?.isVisible = - showDebugNotificationSwitch - - findPreference(getString(R.string.pref_key_notifications_fix_issues))?.run { - isVisible = AppKillerManager.isDeviceSupported() - && AppKillerManager.isAnyActionAvailable(requireContext()) - - setOnPreferenceClickListener { - presenter.onFixSyncIssuesClicked() - true - } - } - - findPreference(getString(R.string.pref_key_notifications_system_settings)) - ?.setOnPreferenceClickListener { - presenter.onOpenSystemSettingsClicked() - true - } - } - - override fun onCreateRecyclerView( - inflater: LayoutInflater, - parent: ViewGroup, - state: Bundle? - ): RecyclerView = super.onCreateRecyclerView(inflater, parent, state) - .also { - it.itemAnimator = null - it.layoutAnimation = null - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences_notifications, rootKey) - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - presenter.onSharedPreferenceChanged(key) - } - - override fun enableNotification(notificationKey: String, enable: Boolean) { - findPreference(notificationKey)?.run { - isEnabled = enable - summary = if (enable) null else getString(R.string.pref_notify_disabled_summary) - } - } - - override fun showError(text: String, error: Throwable) { - (activity as? BaseActivity<*, *>)?.showError(text, error) - } - - override fun showMessage(text: String) { - (activity as? BaseActivity<*, *>)?.showMessage(text) - } - - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun openClearLoginView() { - (activity as? BaseActivity<*, *>)?.openClearLoginView() - } - - override fun showErrorDetailsDialog(error: Throwable) { - ErrorDialog.newInstance(error).show(childFragmentManager, error.toString()) - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - - override fun showFixSyncDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.pref_notify_fix_sync_issues) - .setMessage(R.string.pref_notify_fix_sync_issues_message) - .setNegativeButton(android.R.string.cancel) { _, _ -> } - .setPositiveButton(R.string.pref_notify_open_system_settings) { _, _ -> - try { - AppKillerManager.doActionPowerSaving(requireContext()) - AppKillerManager.doActionAutoStart(requireContext()) - AppKillerManager.doActionNotification(requireContext()) - } catch (e: NoActionFoundException) { - requireContext().openInternetBrowser( - "https://dontkillmyapp.com/${AppKillerManager.getDevice()?.manufacturer}", - ::showMessage - ) - } - } - .show() - } - - override fun openSystemSettings() { - requireActivity().openNotificationSettings() - } - - override fun requestNotificationPermissions() { - requestPermissionLauncher.launch(notificationsPermission) - } - - override fun openNotificationsPermissionDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(R.string.notifications_header_title) - .setMessage(R.string.notifications_header_description) - .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ -> - requireActivity().openNotificationSettings() - } - .setNegativeButton(android.R.string.cancel) { _, _ -> - setNotificationPreferencesChecked(false) - } - .setOnDismissListener { setNotificationPreferencesChecked(false) } - .show() - } - - override fun openNotificationPiggyBackPermissionDialog() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.pref_notification_piggyback_popup_title)) - .setMessage(getString(R.string.pref_notification_piggyback_popup_description)) - .setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ -> - notificationSettingsPiggybackContract.launch(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) - } - .setNegativeButton(android.R.string.cancel) { _, _ -> - setNotificationPiggybackPreferenceChecked(false) - } - .setOnDismissListener { setNotificationPiggybackPreferenceChecked(false) } - .show() - } - - override fun openNotificationExactAlarmSettings() { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.pref_notification_exact_alarm_popup_title)) - .setMessage(getString(R.string.pref_notification_exact_alarm_popup_descriptions)) - .setPositiveButton(getString(R.string.pref_notification_go_to_settings)) { _, _ -> - notificationSettingsExactAlarmsContract.launch(Intent("android.settings.REQUEST_SCHEDULE_EXACT_ALARM")) - } - .setNegativeButton(android.R.string.cancel) { _, _ -> - setUpcomingLessonsNotificationPreferenceChecked(false) - } - .setOnDismissListener { setUpcomingLessonsNotificationPreferenceChecked(false) } - .show() - } - - override fun setNotificationPreferencesChecked(isChecked: Boolean) { - findPreference(getString(R.string.pref_key_notifications_enable))?.isChecked = - isChecked - } - - override fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) { - findPreference(getString(R.string.pref_key_notifications_piggyback))?.isChecked = - isChecked - } - - override fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean) { - findPreference(getString(R.string.pref_key_notifications_upcoming_lessons_enable))?.isChecked = - isChecked - } - - override fun onResume() { - super.onResume() - preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) - } - - override fun onPause() { - super.onPause() - preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt deleted file mode 100644 index b2938cf6..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt +++ /dev/null @@ -1,111 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.notifications - -import com.chuckerteam.chucker.api.ChuckerCollector -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.AppInfo -import timber.log.Timber -import javax.inject.Inject - -class NotificationsPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val preferencesRepository: PreferencesRepository, - private val timetableNotificationHelper: TimetableNotificationSchedulerHelper, - private val appInfo: AppInfo, - private val analytics: AnalyticsHelper, - private val chuckerCollector: ChuckerCollector -) : BasePresenter(errorHandler, studentRepository) { - - override fun onAttachView(view: NotificationsView) { - super.onAttachView(view) - - with(view) { - enableNotification( - notificationKey = preferencesRepository.notificationsEnableKey, - enable = preferencesRepository.isServiceEnabled - ) - initView(appInfo.isDebug) - } - - checkNotificationsPermissionState() - checkNotificationPiggybackState() - - Timber.i("Settings notifications view was initialized") - } - - fun onSharedPreferenceChanged(key: String?) { - key ?: return - Timber.i("Change settings $key") - - preferencesRepository.apply { - when (key) { - isUpcomingLessonsNotificationsEnableKey, isUpcomingLessonsNotificationsPersistentKey -> { - if (!isUpcomingLessonsNotificationsEnable) { - timetableNotificationHelper.cancelNotification() - } else if (!timetableNotificationHelper.canScheduleExactAlarms()) { - view?.openNotificationExactAlarmSettings() - } - } - notificationsEnableKey -> { - if (isNotificationsEnable && view?.isNotificationPermissionGranted == false) { - view?.requestNotificationPermissions() - } - } - isDebugNotificationEnableKey -> { - chuckerCollector.showNotification = isDebugNotificationEnable - } - isNotificationPiggybackEnabledKey -> { - if (isNotificationPiggybackEnabled && view?.isNotificationPiggybackPermissionGranted == false) { - view?.openNotificationPiggyBackPermissionDialog() - } - } - } - } - analytics.logEvent("setting_changed", "name" to key) - } - - fun onFixSyncIssuesClicked() { - view?.showFixSyncDialog() - } - - fun onOpenSystemSettingsClicked() { - view?.openSystemSettings() - } - - fun onNotificationsPermissionResult() { - view?.run { - setNotificationPreferencesChecked(isNotificationPermissionGranted) - } - } - - fun onNotificationPiggybackPermissionResult() { - view?.run { - setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted) - } - } - - fun onNotificationExactAlarmPermissionResult() { - view?.setUpcomingLessonsNotificationPreferenceChecked(timetableNotificationHelper.canScheduleExactAlarms()) - } - - private fun checkNotificationsPermissionState() { - if (preferencesRepository.isNotificationsEnable) { - view?.run { - setNotificationPreferencesChecked(isNotificationPermissionGranted) - } - } - } - - private fun checkNotificationPiggybackState() { - if (preferencesRepository.isNotificationPiggybackEnabled) { - view?.run { - setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted) - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt deleted file mode 100644 index a391681c..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.notifications - -import io.github.wulkanowy.ui.base.BaseView - -interface NotificationsView : BaseView { - - val isNotificationPermissionGranted: Boolean - - val isNotificationPiggybackPermissionGranted: Boolean - - fun initView(showDebugNotificationSwitch: Boolean) - - fun showFixSyncDialog() - - fun openSystemSettings() - - fun enableNotification(notificationKey: String, enable: Boolean) - - fun requestNotificationPermissions() - - fun openNotificationsPermissionDialog() - - fun openNotificationPiggyBackPermissionDialog() - - fun openNotificationExactAlarmSettings() - - fun setNotificationPreferencesChecked(isChecked: Boolean) - - fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) - - fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncFragment.kt deleted file mode 100644 index d5714483..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncFragment.kt +++ /dev/null @@ -1,123 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.sync - -import android.content.SharedPreferences -import android.os.Bundle -import android.view.View -import androidx.preference.Preference -import androidx.preference.PreferenceFragmentCompat -import com.google.android.material.snackbar.Snackbar -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.base.ErrorDialog -import io.github.wulkanowy.ui.modules.main.MainView -import javax.inject.Inject - -@AndroidEntryPoint -class SyncFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener, - MainView.TitledView, SyncView { - - @Inject - lateinit var presenter: SyncPresenter - - override val titleStringId get() = R.string.pref_settings_sync_title - - override val syncSuccessString get() = getString(R.string.pref_services_message_sync_success) - - override val syncFailedString get() = getString(R.string.pref_services_message_sync_failed) - - override fun initView() { - findPreference(getString(R.string.pref_key_services_force_sync))?.run { - onPreferenceClickListener = Preference.OnPreferenceClickListener { - presenter.onSyncNowClicked() - true - } - } - } - - override fun setLastSyncDate(lastSyncDate: String) { - findPreference(getString(R.string.pref_key_services_force_sync))?.run { - summary = getString(R.string.pref_services_last_full_sync_date, lastSyncDate) - } - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - presenter.onAttachView(this) - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { - setPreferencesFromResource(R.xml.scheme_preferences_sync, rootKey) - } - - override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - presenter.onSharedPreferenceChanged(key) - } - - override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) { - findPreference(serviceEnablesKey)?.run { - summary = if (isHolidays) getString(R.string.pref_services_suspended) else "" - isEnabled = !isHolidays - } - } - - override fun setSyncInProgress(inProgress: Boolean) { - if (activity == null || !isAdded) return - - findPreference(getString(R.string.pref_key_services_force_sync))?.run { - isEnabled = !inProgress - summary = if (inProgress) getString(R.string.pref_services_sync_in_progress) else "" - } - } - - override fun showError(text: String, error: Throwable) { - (activity as? BaseActivity<*, *>)?.showError(text, error) - } - - override fun showMessage(text: String) { - Snackbar.make(requireView(), text, Snackbar.LENGTH_LONG) - .apply { - anchorView = requireActivity().findViewById(R.id.main_bottom_nav) - show() - } - } - - override fun showExpiredCredentialsDialog() { - (activity as? BaseActivity<*, *>)?.showExpiredCredentialsDialog() - } - - override fun onCaptchaVerificationRequired(url: String?) { - (activity as? BaseActivity<*, *>)?.onCaptchaVerificationRequired(url) - } - - override fun showDecryptionFailedDialog() { - (activity as? BaseActivity<*, *>)?.showDecryptionFailedDialog() - } - - override fun showChangePasswordSnackbar(redirectUrl: String) { - (activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl) - } - - override fun openClearLoginView() { - (activity as? BaseActivity<*, *>)?.openClearLoginView() - } - - override fun showErrorDetailsDialog(error: Throwable) { - ErrorDialog.newInstance(error).show(childFragmentManager, "error_details") - } - - override fun showAuthDialog() { - (activity as? BaseActivity<*, *>)?.showAuthDialog() - } - - override fun onResume() { - super.onResume() - preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this) - } - - override fun onPause() { - super.onPause() - preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncView.kt deleted file mode 100644 index 6ffe156f..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/sync/SyncView.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.wulkanowy.ui.modules.settings.sync - -import io.github.wulkanowy.ui.base.BaseView - -interface SyncView : BaseView { - - val syncSuccessString: String - - val syncFailedString: String - - fun initView() - - fun setLastSyncDate(lastSyncDate: String) - - fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) - - fun setSyncInProgress(inProgress: Boolean) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt index cfb62849..7fc20d23 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashActivity.kt @@ -1,56 +1,24 @@ package io.github.wulkanowy.ui.modules.splash -import android.annotation.SuppressLint -import android.content.Context -import android.content.Intent import android.os.Bundle import android.widget.Toast import android.widget.Toast.LENGTH_LONG -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.viewbinding.ViewBinding import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.services.shortcuts.ShortcutsHelper import io.github.wulkanowy.ui.base.BaseActivity -import io.github.wulkanowy.ui.modules.Destination import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.utils.openInternetBrowser -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json import javax.inject.Inject -@SuppressLint("CustomSplashScreen") @AndroidEntryPoint class SplashActivity : BaseActivity(), SplashView { @Inject override lateinit var presenter: SplashPresenter - @Inject - lateinit var shortcutsHelper: ShortcutsHelper - - companion object { - - private const val EXTRA_START_DESTINATION = "start_destination_json" - - private const val EXTRA_EXTERNAL_URL = "external_url" - - fun getStartIntent(context: Context, destination: Destination? = null) = - Intent(context, SplashActivity::class.java).apply { - destination?.let { putExtra(EXTRA_START_DESTINATION, Json.encodeToString(it)) } - flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - } - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - installSplashScreen().setKeepOnScreenCondition { true } - shortcutsHelper.initializeShortcuts() - - val externalLink = intent?.getStringExtra(EXTRA_EXTERNAL_URL) - val startDestinationJson = intent?.getStringExtra(EXTRA_START_DESTINATION) - - presenter.onAttachView(this, externalLink, startDestinationJson) + presenter.onAttachView(this) } override fun openLoginView() { @@ -58,13 +26,8 @@ class SplashActivity : BaseActivity(), SplashView finish() } - override fun openMainView(destination: Destination?) { - startActivity(MainActivity.getStartIntent(this, destination)) - finish() - } - - override fun openExternalUrlAndFinish(url: String) { - openInternetBrowser(url, ::showMessage) + override fun openMainView() { + startActivity(MainActivity.getStartIntent(this)) finish() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt index 767c885c..d16ca4a8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashPresenter.kt @@ -1,40 +1,30 @@ package io.github.wulkanowy.ui.modules.splash -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.Status +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.ui.modules.Destination -import kotlinx.coroutines.launch -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.json.Json +import io.github.wulkanowy.utils.flowWithResource +import kotlinx.coroutines.flow.onEach +import timber.log.Timber import javax.inject.Inject class SplashPresenter @Inject constructor( errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val json: Json + studentRepository: StudentRepository ) : BasePresenter(errorHandler, studentRepository) { - fun onAttachView(view: SplashView, externalUrl: String?, startDestinationJson: String?) { + override fun onAttachView(view: SplashView) { super.onAttachView(view) - - val startDestination: Destination? = startDestinationJson?.let { json.decodeFromString(it) } - - if (!externalUrl.isNullOrBlank()) { - view.openExternalUrlAndFinish(externalUrl) - return - } - - presenterScope.launch { - runCatching { studentRepository.isCurrentStudentSet() } - .onFailure(errorHandler::dispatch) - .onSuccess { - if (it) { - view.openMainView(startDestination) - } else { - view.openLoginView() - } + flowWithResource { studentRepository.isCurrentStudentSet() }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Is current user set check started") + Status.SUCCESS -> with(view) { + if (it.data!!) openMainView() + else openLoginView() } - } + Status.ERROR -> errorHandler.dispatch(it.error!!) + } + }.launch() } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashView.kt index 1c5d8bfd..9efd8123 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/splash/SplashView.kt @@ -1,13 +1,10 @@ package io.github.wulkanowy.ui.modules.splash import io.github.wulkanowy.ui.base.BaseView -import io.github.wulkanowy.ui.modules.Destination interface SplashView : BaseView { fun openLoginView() - fun openMainView(destination: Destination?) - - fun openExternalUrlAndFinish(url: String) + fun openMainView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoAdapter.kt deleted file mode 100644 index 60912200..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoAdapter.kt +++ /dev/null @@ -1,45 +0,0 @@ -package io.github.wulkanowy.ui.modules.studentinfo - -import android.view.LayoutInflater -import android.view.View.GONE -import android.view.View.VISIBLE -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.databinding.ItemStudentInfoBinding -import javax.inject.Inject - -class StudentInfoAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = listOf() - - var onItemClickListener: (StudentInfoView.Type?) -> Unit = {} - - var onItemLongClickListener: (text: String) -> Unit = {} - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder( - ItemStudentInfoBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - studentInfoItemTitle.text = item.title - studentInfoItemSubtitle.text = item.subtitle - studentInfoItemArrow.visibility = if (item.showArrow) VISIBLE else GONE - - with(root) { - setOnClickListener { onItemClickListener(item.viewType) } - setOnLongClickListener { - onItemLongClickListener(studentInfoItemSubtitle.text.toString()) - true - } - } - } - } - - class ViewHolder(val binding: ItemStudentInfoBinding) : RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt deleted file mode 100644 index 598046a2..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt +++ /dev/null @@ -1,264 +0,0 @@ -package io.github.wulkanowy.ui.modules.studentinfo - -import android.content.ClipData -import android.content.ClipboardManager -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.View -import android.widget.Toast -import androidx.core.content.getSystemService -import androidx.core.os.bundleOf -import androidx.core.view.get -import androidx.recyclerview.widget.DividerItemDecoration -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.StudentGuardian -import io.github.wulkanowy.data.db.entities.StudentInfo -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.enums.Gender -import io.github.wulkanowy.databinding.FragmentStudentInfoBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.utils.capitalise -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.nullableSerializable -import io.github.wulkanowy.utils.serializable -import javax.inject.Inject - -@AndroidEntryPoint -class StudentInfoFragment : - BaseFragment(R.layout.fragment_student_info), StudentInfoView, - MainView.TitledView { - - @Inject - lateinit var presenter: StudentInfoPresenter - - @Inject - lateinit var studentInfoAdapter: StudentInfoAdapter - - override val titleStringId: Int - get() = when ( - requireArguments().nullableSerializable(INFO_TYPE_ARGUMENT_KEY) - ) { - StudentInfoView.Type.PERSONAL -> R.string.account_personal_data - StudentInfoView.Type.CONTACT -> R.string.account_contact - StudentInfoView.Type.ADDRESS -> R.string.account_address - StudentInfoView.Type.FAMILY -> R.string.account_family - StudentInfoView.Type.SECOND_GUARDIAN -> R.string.student_info_guardian - StudentInfoView.Type.FIRST_GUARDIAN -> R.string.student_info_guardian - else -> R.string.student_info_title - } - - override val isViewEmpty get() = studentInfoAdapter.items.isEmpty() - - companion object { - - private const val INFO_TYPE_ARGUMENT_KEY = "info_type" - - private const val STUDENT_ARGUMENT_KEY = "student_with_semesters" - - fun newInstance(type: StudentInfoView.Type, studentWithSemesters: StudentWithSemesters) = - StudentInfoFragment().apply { - arguments = bundleOf( - INFO_TYPE_ARGUMENT_KEY to type, - STUDENT_ARGUMENT_KEY to studentWithSemesters - ) - } - } - - @Suppress("DEPRECATION") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentStudentInfoBinding.bind(view) - presenter.onAttachView( - view = this, - type = requireArguments().serializable(INFO_TYPE_ARGUMENT_KEY), - studentWithSemesters = requireArguments().serializable(STUDENT_ARGUMENT_KEY), - ) - } - - override fun initView() { - with(binding) { - studentInfoSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - studentInfoSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - studentInfoSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor( - R.attr.colorSwipeRefresh - ) - ) - studentInfoErrorRetry.setOnClickListener { presenter.onRetry() } - studentInfoErrorDetails.setOnClickListener { presenter.onDetailsClick() } - } - - with(studentInfoAdapter) { - onItemClickListener = presenter::onItemSelected - onItemLongClickListener = presenter::onItemLongClick - } - - with(binding.studentInfoRecycler) { - layoutManager = LinearLayoutManager(context) - addItemDecoration(DividerItemDecoration(context, RecyclerView.VERTICAL)) - setHasFixedSize(true) - adapter = studentInfoAdapter - } - } - - override fun updateData(data: List) { - with(studentInfoAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - menu[0].isVisible = false - } - - override fun showPersonalTypeData(studentInfo: StudentInfo) { - updateData( - listOf( - getString(R.string.student_info_first_name) to studentInfo.firstName, - getString(R.string.student_info_second_name) to studentInfo.secondName, - getString(R.string.student_info_last_name) to studentInfo.surname, - getString(R.string.student_info_gender) to getString(if (studentInfo.gender == Gender.MALE) R.string.student_info_male else R.string.student_info_female), - getString(R.string.student_info_polish_citizenship) to getString(if (studentInfo.hasPolishCitizenship) R.string.all_yes else R.string.all_no), - getString(R.string.student_info_family_name) to studentInfo.familyName, - getString(R.string.student_info_parents_name) to studentInfo.parentsNames - ).map { - StudentInfoItem( - title = it.first, - subtitle = it.second.ifBlank { getString(R.string.all_no_data) }, - showArrow = false, - ) - } - ) - } - - override fun showContactTypeData(studentInfo: StudentInfo) { - updateData( - listOf( - getString(R.string.student_info_phone) to studentInfo.phoneNumber, - getString(R.string.student_info_cellphone) to studentInfo.cellPhoneNumber, - getString(R.string.student_info_email) to studentInfo.email - ).map { - StudentInfoItem( - title = it.first, - subtitle = it.second.ifBlank { getString(R.string.all_no_data) }, - showArrow = false, - ) - } - ) - } - - override fun showFamilyTypeData(studentInfo: StudentInfo) { - val items = buildList { - add(studentInfo.firstGuardian?.let { - Triple(it.kinship.capitalise(), it.fullName, StudentInfoView.Type.FIRST_GUARDIAN) - }) - - add(studentInfo.secondGuardian?.let { - Triple(it.kinship.capitalise(), it.fullName, StudentInfoView.Type.SECOND_GUARDIAN) - }) - }.filterNotNull() - - updateData( - items.map { (title, value, type) -> - StudentInfoItem( - title = title.ifBlank { getString(R.string.all_no_data) }, - subtitle = value.ifBlank { getString(R.string.all_no_data) }, - showArrow = true, - viewType = type, - ) - } - ) - } - - override fun showAddressTypeData(studentInfo: StudentInfo) { - updateData( - listOf( - getString(R.string.student_info_address) to studentInfo.address, - getString(R.string.student_info_registered_address) to studentInfo.registeredAddress, - getString(R.string.student_info_correspondence_address) to studentInfo.correspondenceAddress - ).map { - StudentInfoItem( - title = it.first, - subtitle = it.second.ifBlank { getString(R.string.all_no_data) }, - showArrow = false, - ) - } - ) - } - - override fun showGuardianTypeData(studentGuardian: StudentGuardian) { - updateData( - listOf( - getString(R.string.student_info_full_name) to studentGuardian.fullName, - getString(R.string.student_info_kinship) to studentGuardian.kinship, - getString(R.string.student_info_guardian_address) to studentGuardian.address, - getString(R.string.student_info_phones) to studentGuardian.phones, - getString(R.string.student_info_email) to studentGuardian.email - ).map { - StudentInfoItem( - title = it.first, - subtitle = it.second.ifBlank { getString(R.string.all_no_data) }, - showArrow = false, - ) - } - ) - } - - override fun openStudentInfoView( - infoType: StudentInfoView.Type, - studentWithSemesters: StudentWithSemesters - ) { - (requireActivity() as MainActivity).pushView(newInstance(infoType, studentWithSemesters)) - } - - override fun showEmpty(show: Boolean) { - binding.studentInfoEmpty.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showErrorView(show: Boolean) { - binding.studentInfoError.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun setErrorDetails(message: String) { - binding.studentInfoErrorMessage.text = message - } - - override fun showProgress(show: Boolean) { - binding.studentInfoProgress.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun enableSwipe(enable: Boolean) { - binding.studentInfoSwipe.isEnabled = enable - } - - override fun showContent(show: Boolean) { - binding.studentInfoRecycler.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun hideRefresh() { - binding.studentInfoSwipe.isRefreshing = false - } - - override fun copyToClipboard(text: String) { - val clipData = ClipData.newPlainText("student_info_wulkanowy", text) - requireActivity().getSystemService()?.setPrimaryClip(clipData) - Toast.makeText(context, R.string.all_copied, Toast.LENGTH_SHORT).show() - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoItem.kt deleted file mode 100644 index 21226539..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoItem.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.wulkanowy.ui.modules.studentinfo - -data class StudentInfoItem( - val title: String, - val subtitle: String, - val showArrow: Boolean, - val viewType: StudentInfoView.Type? = null, -) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoPresenter.kt deleted file mode 100644 index 083b590b..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoPresenter.kt +++ /dev/null @@ -1,141 +0,0 @@ -package io.github.wulkanowy.ui.modules.studentinfo - -import io.github.wulkanowy.data.* -import io.github.wulkanowy.data.db.entities.StudentInfo -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.data.repositories.StudentInfoRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.getCurrentOrLast -import timber.log.Timber -import javax.inject.Inject - -class StudentInfoPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val studentInfoRepository: StudentInfoRepository, - private val analytics: AnalyticsHelper -) : BasePresenter(errorHandler, studentRepository) { - - private lateinit var infoType: StudentInfoView.Type - - private lateinit var studentWithSemesters: StudentWithSemesters - - private lateinit var lastError: Throwable - - fun onAttachView( - view: StudentInfoView, - type: StudentInfoView.Type, - studentWithSemesters: StudentWithSemesters - ) { - super.onAttachView(view) - infoType = type - this.studentWithSemesters = studentWithSemesters - view.initView() - Timber.i("Student info $infoType view was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData() - } - - fun onSwipeRefresh() { - loadData(true) - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData(true) - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - fun onItemSelected(viewType: StudentInfoView.Type?) { - viewType ?: return - - view?.openStudentInfoView( - studentWithSemesters = studentWithSemesters, - infoType = viewType, - ) - } - - fun onItemLongClick(text: String) { - view?.copyToClipboard(text) - } - - private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { - val semester = studentWithSemesters.semesters.getCurrentOrLast() - studentInfoRepository.getStudentInfo( - student = studentWithSemesters.student, - semester = semester, - forceRefresh = forceRefresh - ) - } - .logResourceStatus("load student info $infoType") - .onResourceData { - val isFamily = infoType == StudentInfoView.Type.FAMILY - val isFirstGuardianEmpty = it?.firstGuardian == null - val isSecondGuardianEmpty = it?.secondGuardian == null - if (it != null && !(isFamily && isFirstGuardianEmpty && isSecondGuardianEmpty)) { - Timber.i("Loading student info $infoType result: Success") - showCorrectData(it) - view?.run { - showContent(true) - showEmpty(false) - showErrorView(false) - } - } else { - Timber.i("Loading student info $infoType result: No student or family info found") - view?.run { - showContent(!isViewEmpty) - showEmpty(isViewEmpty) - showErrorView(false) - } - } - } - .onResourceSuccess { - if (it != null) { - analytics.logEvent("load_item", "type" to "student_info") - } - } - .onResourceNotLoading { - view?.run { - hideRefresh() - showProgress(false) - enableSwipe(true) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private fun showCorrectData(studentInfo: StudentInfo) { - when (infoType) { - StudentInfoView.Type.PERSONAL -> view?.showPersonalTypeData(studentInfo) - StudentInfoView.Type.CONTACT -> view?.showContactTypeData(studentInfo) - StudentInfoView.Type.ADDRESS -> view?.showAddressTypeData(studentInfo) - StudentInfoView.Type.FAMILY -> view?.showFamilyTypeData(studentInfo) - StudentInfoView.Type.SECOND_GUARDIAN -> view?.showGuardianTypeData(studentInfo.secondGuardian!!) - StudentInfoView.Type.FIRST_GUARDIAN -> view?.showGuardianTypeData(studentInfo.firstGuardian!!) - } - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - showContent(false) - showProgress(false) - } else showError(message, error) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoView.kt deleted file mode 100644 index c20359df..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoView.kt +++ /dev/null @@ -1,47 +0,0 @@ -package io.github.wulkanowy.ui.modules.studentinfo - -import io.github.wulkanowy.data.db.entities.StudentGuardian -import io.github.wulkanowy.data.db.entities.StudentInfo -import io.github.wulkanowy.data.db.entities.StudentWithSemesters -import io.github.wulkanowy.ui.base.BaseView - -interface StudentInfoView : BaseView { - - enum class Type { - PERSONAL, ADDRESS, CONTACT, FAMILY, FIRST_GUARDIAN, SECOND_GUARDIAN - } - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun showPersonalTypeData(studentInfo: StudentInfo) - - fun showContactTypeData(studentInfo: StudentInfo) - - fun showAddressTypeData(studentInfo: StudentInfo) - - fun showFamilyTypeData(studentInfo: StudentInfo) - - fun showGuardianTypeData(studentGuardian: StudentGuardian) - - fun openStudentInfoView(infoType: Type, studentWithSemesters: StudentWithSemesters) - - fun showEmpty(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun showProgress(show: Boolean) - - fun enableSwipe(enable: Boolean) - - fun showContent(show: Boolean) - - fun hideRefresh() - - fun copyToClipboard(text: String) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt index 5cb6c401..f049f828 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt @@ -1,104 +1,89 @@ package io.github.wulkanowy.ui.modules.timetable +import android.graphics.Paint import android.view.LayoutInflater import android.view.View.GONE import android.view.View.VISIBLE import android.view.ViewGroup import android.widget.TextView -import androidx.core.view.isVisible -import androidx.recyclerview.widget.DiffUtil +import androidx.core.view.ViewCompat import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.databinding.ItemTimetableBinding -import io.github.wulkanowy.databinding.ItemTimetableEmptyBinding -import io.github.wulkanowy.databinding.ItemTimetableMainAdditionalBinding import io.github.wulkanowy.databinding.ItemTimetableSmallBinding -import io.github.wulkanowy.utils.SyncListAdapter -import io.github.wulkanowy.utils.getPlural import io.github.wulkanowy.utils.getThemeAttrColor +import io.github.wulkanowy.utils.isJustFinished +import io.github.wulkanowy.utils.isShowTimeUntil +import io.github.wulkanowy.utils.left import io.github.wulkanowy.utils.toFormattedString +import io.github.wulkanowy.utils.until +import timber.log.Timber +import java.time.LocalDateTime +import java.util.Timer import javax.inject.Inject +import kotlin.concurrent.timer -class TimetableAdapter @Inject constructor() : - SyncListAdapter(Differ) { +class TimetableAdapter @Inject constructor() : RecyclerView.Adapter() { - override fun getItemViewType(position: Int): Int = getItem(position).type.ordinal + private enum class ViewType(val id: Int) { + ITEM_NORMAL(1), + ITEM_SMALL(2) + } + + var items = mutableListOf() + set(value) { + field = value + resetTimers() + } + + var onClickListener: (Timetable) -> Unit = {} + + var showWholeClassPlan: String = "no" + + var showGroupsInPlan: Boolean = false + + var showTimers: Boolean = false + + private val timers = mutableMapOf() + + fun resetTimers() { + Timber.d("Timetable timers (${timers.size}) reset") + with(timers) { + forEach { (_, timer) -> timer.cancel() } + clear() + } + } + + override fun getItemCount() = items.size + + override fun getItemViewType(position: Int) = when { + !items[position].isStudentPlan && showWholeClassPlan == "small" -> ViewType.ITEM_SMALL.id + else -> ViewType.ITEM_NORMAL.id + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val inflater = LayoutInflater.from(parent.context) - return when (TimetableItemType.entries[viewType]) { - TimetableItemType.SMALL -> SmallViewHolder( - ItemTimetableSmallBinding.inflate(inflater, parent, false) - ) - - TimetableItemType.NORMAL -> NormalViewHolder( - ItemTimetableBinding.inflate(inflater, parent, false) - ) - - TimetableItemType.EMPTY -> EmptyViewHolder( - ItemTimetableEmptyBinding.inflate(inflater, parent, false) - ) - - TimetableItemType.ADDITIONAL -> AdditionalViewHolder( - ItemTimetableMainAdditionalBinding.inflate(inflater, parent, false) - ) + return when (viewType) { + ViewType.ITEM_NORMAL.id -> ItemViewHolder(ItemTimetableBinding.inflate(inflater, parent, false)) + ViewType.ITEM_SMALL.id -> SmallItemViewHolder(ItemTimetableSmallBinding.inflate(inflater, parent, false)) + else -> throw IllegalStateException() } } - override fun onBindViewHolder( - holder: RecyclerView.ViewHolder, - position: Int, - payloads: MutableList - ) { - if (payloads.isNotEmpty() && holder is NormalViewHolder) { - updateTimeLeft( - binding = holder.binding, - timeLeft = (getItem(position) as TimetableItem.Normal).timeLeft, - ) - } else super.onBindViewHolder(holder, position, payloads) - } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val lesson = items[position] + when (holder) { - is SmallViewHolder -> bindSmallView( - binding = holder.binding, - item = getItem(position) as TimetableItem.Small, - ) - is NormalViewHolder -> bindNormalView( - binding = holder.binding, - item = getItem(position) as TimetableItem.Normal, - ) - is EmptyViewHolder -> bindEmptyView( - binding = holder.binding, - item = getItem(position) as TimetableItem.Empty, - ) - - is AdditionalViewHolder -> bindAdditionalView( - binding = holder.binding, - item = getItem(position) as TimetableItem.Additional, - ) + is ItemViewHolder -> bindNormalView(holder.binding, lesson, position) + is SmallItemViewHolder -> bindSmallView(holder.binding, lesson) } } - private fun bindAdditionalView( - binding: ItemTimetableMainAdditionalBinding, - item: TimetableItem.Additional - ) { - with(binding) { - timetableItemSubject.text = item.additional.subject - timetableItemTimeStart.text = item.additional.start.toFormattedString("HH:mm") - timetableItemTimeFinish.text = item.additional.end.toFormattedString("HH:mm") - } - } - - private fun bindSmallView(binding: ItemTimetableSmallBinding, item: TimetableItem.Small) { - val lesson = item.lesson - + private fun bindSmallView(binding: ItemTimetableSmallBinding, lesson: Timetable) { with(binding) { timetableSmallItemNumber.text = lesson.number.toString() - timetableSmallItemNumber.isVisible = item.isLessonNumberVisible timetableSmallItemSubject.text = lesson.subject timetableSmallItemTimeStart.text = lesson.start.toFormattedString("HH:mm") timetableSmallItemRoom.text = lesson.room @@ -108,16 +93,13 @@ class TimetableAdapter @Inject constructor() : bindSmallDescription(binding, lesson) bindSmallColors(binding, lesson) - root.setOnClickListener { item.onClick(lesson) } + root.setOnClickListener { onClickListener(lesson) } } } - private fun bindNormalView(binding: ItemTimetableBinding, item: TimetableItem.Normal) { - val lesson = item.lesson - + private fun bindNormalView(binding: ItemTimetableBinding, lesson: Timetable, position: Int) { with(binding) { timetableItemNumber.text = lesson.number.toString() - timetableItemNumber.isVisible = item.isLessonNumberVisible timetableItemSubject.text = lesson.subject timetableItemGroup.text = lesson.group timetableItemRoom.text = lesson.room @@ -126,65 +108,78 @@ class TimetableAdapter @Inject constructor() : timetableItemTimeFinish.text = lesson.end.toFormattedString("HH:mm") bindSubjectStyle(timetableItemSubject, lesson) - bindNormalDescription(binding, item) + bindNormalDescription(binding, lesson) bindNormalColors(binding, lesson) - updateTimeLeft(binding, item.timeLeft) - root.setOnClickListener { item.onClick(lesson) } - } - } - - private fun bindEmptyView(binding: ItemTimetableEmptyBinding, item: TimetableItem.Empty) { - with(binding) { - timetableEmptyItemNumber.text = when (item.numFrom) { - item.numTo -> item.numFrom.toString() - else -> "${item.numFrom}-${item.numTo}" + if (lesson.isStudentPlan && showTimers) { + timers[position] = timer(period = 1000) { + if (ViewCompat.isAttachedToWindow(root)) { + root.post { updateTimeLeft(binding, lesson, position) } + } + } + } else { + // reset item on set changed + timetableItemTimeUntil.visibility = GONE + timetableItemTimeLeft.visibility = GONE } - timetableEmptyItemSubject.text = timetableEmptyItemSubject.context.getPlural( - R.plurals.timetable_no_lesson, - item.numTo - item.numFrom + 1 - ) + + root.setOnClickListener { onClickListener(lesson) } } } - private fun updateTimeLeft(binding: ItemTimetableBinding, timeLeft: TimeLeft?) { + private fun getPreviousLesson(position: Int): LocalDateTime? { + return items.filter { it.isStudentPlan }.getOrNull(position - 1 - items.filterIndexed { i, item -> i < position && !item.isStudentPlan }.size)?.let { + if (!it.canceled && it.isStudentPlan) it.end + else null + } + } + + private fun updateTimeLeft(binding: ItemTimetableBinding, lesson: Timetable, position: Int) { + val isShowTimeUntil = lesson.isShowTimeUntil(getPreviousLesson(position)) + val until = lesson.until + val left = lesson.left + val isJustFinished = lesson.isJustFinished + with(binding) { when { // before lesson - timeLeft?.until != null -> { + isShowTimeUntil -> { + Timber.d("Show time until lesson: $position") timetableItemTimeLeft.visibility = GONE with(timetableItemTimeUntil) { visibility = VISIBLE - text = context.getString( - R.string.timetable_time_until, - context.getString( - R.string.timetable_minutes, - timeLeft.until.toMinutes().toString(10) - ) + text = context.getString(R.string.timetable_time_until, + if (until.seconds <= 60) { + context.getString(R.string.timetable_seconds, until.seconds.toString(10)) + } else { + context.getString(R.string.timetable_minutes, until.toMinutes().toString(10)) + } ) } } // after lesson start - timeLeft?.left != null -> { + left != null -> { + Timber.d("Show time left lesson: $position") timetableItemTimeUntil.visibility = GONE with(timetableItemTimeLeft) { visibility = VISIBLE text = context.getString( R.string.timetable_time_left, - context.getString( - R.string.timetable_minutes, - timeLeft.left.toMinutes().toString() - ) + if (left.seconds < 60) { + context.getString(R.string.timetable_seconds, left.seconds.toString(10)) + } else { + context.getString(R.string.timetable_minutes, left.toMinutes().toString(10)) + } ) } } // right after lesson finish - timeLeft?.isJustFinished == true -> { + isJustFinished -> { + Timber.d("Show just finished lesson: $position") timetableItemTimeUntil.visibility = GONE timetableItemTimeLeft.visibility = VISIBLE timetableItemTimeLeft.text = root.context.getString(R.string.timetable_finished) } - else -> { timetableItemTimeUntil.visibility = GONE timetableItemTimeLeft.visibility = GONE @@ -194,7 +189,8 @@ class TimetableAdapter @Inject constructor() : } private fun bindSubjectStyle(subjectView: TextView, lesson: Timetable) { - subjectView.paint.isStrikeThruText = lesson.canceled + subjectView.paintFlags = if (lesson.canceled) subjectView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG + else subjectView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() } private fun bindSmallDescription(binding: ItemTimetableSmallBinding, lesson: Timetable) { @@ -206,12 +202,10 @@ class TimetableAdapter @Inject constructor() : timetableSmallItemRoom.visibility = GONE timetableSmallItemTeacher.visibility = GONE - timetableSmallItemDescription.setTextColor( - root.context.getThemeAttrColor( - if (lesson.canceled) R.attr.colorTimetableCanceled - else R.attr.colorTimetableChange - ) - ) + timetableSmallItemDescription.setTextColor(root.context.getThemeAttrColor( + if (lesson.canceled) R.attr.colorPrimary + else R.attr.colorTimetableChange + )) } else { timetableSmallItemDescription.visibility = GONE timetableSmallItemRoom.visibility = VISIBLE @@ -220,8 +214,7 @@ class TimetableAdapter @Inject constructor() : } } - private fun bindNormalDescription(binding: ItemTimetableBinding, item: TimetableItem.Normal) { - val lesson = item.lesson + private fun bindNormalDescription(binding: ItemTimetableBinding, lesson: Timetable) { with(binding) { if (lesson.info.isNotBlank() && !lesson.changes) { timetableItemDescription.visibility = VISIBLE @@ -231,17 +224,14 @@ class TimetableAdapter @Inject constructor() : timetableItemGroup.visibility = GONE timetableItemTeacher.visibility = GONE - timetableItemDescription.setTextColor( - root.context.getThemeAttrColor( - if (lesson.canceled) R.attr.colorTimetableCanceled - else R.attr.colorTimetableChange - ) - ) + timetableItemDescription.setTextColor(root.context.getThemeAttrColor( + if (lesson.canceled) R.attr.colorPrimary + else R.attr.colorTimetableChange + )) } else { timetableItemDescription.visibility = GONE - timetableItemRoom.isVisible = - lesson.room.isNotBlank() || lesson.roomOld.isNotBlank() - timetableItemGroup.isVisible = item.showGroupsInPlan && lesson.group.isNotBlank() + timetableItemRoom.visibility = VISIBLE + timetableItemGroup.visibility = if (showGroupsInPlan && lesson.group.isNotBlank()) VISIBLE else GONE timetableItemTeacher.visibility = VISIBLE } } @@ -250,10 +240,7 @@ class TimetableAdapter @Inject constructor() : private fun bindSmallColors(binding: ItemTimetableSmallBinding, lesson: Timetable) { with(binding) { if (lesson.canceled) { - updateNumberAndSubjectCanceledColor( - timetableSmallItemNumber, - timetableSmallItemSubject - ) + updateNumberAndSubjectCanceledColor(timetableSmallItemNumber, timetableSmallItemSubject) } else { updateNumberColor(timetableSmallItemNumber, lesson) updateSubjectColor(timetableSmallItemSubject, lesson) @@ -277,81 +264,41 @@ class TimetableAdapter @Inject constructor() : } private fun updateNumberAndSubjectCanceledColor(numberView: TextView, subjectView: TextView) { - numberView.setTextColor(numberView.context.getThemeAttrColor(R.attr.colorTimetableCanceled)) - subjectView.setTextColor(subjectView.context.getThemeAttrColor(R.attr.colorTimetableCanceled)) + numberView.setTextColor(numberView.context.getThemeAttrColor(R.attr.colorPrimary)) + subjectView.setTextColor(subjectView.context.getThemeAttrColor(R.attr.colorPrimary)) } private fun updateNumberColor(numberView: TextView, lesson: Timetable) { - numberView.setTextColor( - numberView.context.getThemeAttrColor( - if (lesson.changes || lesson.info.isNotBlank()) R.attr.colorTimetableChange - else android.R.attr.textColorPrimary - ) - ) + numberView.setTextColor(numberView.context.getThemeAttrColor( + if (lesson.changes || lesson.info.isNotBlank()) R.attr.colorTimetableChange + else android.R.attr.textColorPrimary + )) } private fun updateSubjectColor(subjectView: TextView, lesson: Timetable) { - subjectView.setTextColor( - subjectView.context.getThemeAttrColor( - if (lesson.subjectOld.isNotBlank() && lesson.subjectOld != lesson.subject) R.attr.colorTimetableChange - else android.R.attr.textColorPrimary - ) - ) + subjectView.setTextColor(subjectView.context.getThemeAttrColor( + if (lesson.subjectOld.isNotBlank() && lesson.subjectOld != lesson.subject) R.attr.colorTimetableChange + else android.R.attr.textColorPrimary + )) } private fun updateRoomColor(roomView: TextView, lesson: Timetable) { - roomView.setTextColor( - roomView.context.getThemeAttrColor( - if (lesson.roomOld.isNotBlank() && lesson.roomOld != lesson.room) R.attr.colorTimetableChange - else android.R.attr.textColorSecondary - ) - ) + roomView.setTextColor(roomView.context.getThemeAttrColor( + if (lesson.roomOld.isNotBlank() && lesson.roomOld != lesson.room) R.attr.colorTimetableChange + else android.R.attr.textColorSecondary + )) } private fun updateTeacherColor(teacherTextView: TextView, lesson: Timetable) { - teacherTextView.setTextColor( - teacherTextView.context.getThemeAttrColor( - if (lesson.teacherOld.isNotBlank()) R.attr.colorTimetableChange - else android.R.attr.textColorSecondary - ) - ) + teacherTextView.setTextColor(teacherTextView.context.getThemeAttrColor( + if (lesson.teacherOld.isNotBlank() && lesson.teacherOld != lesson.teacher) R.attr.colorTimetableChange + else android.R.attr.textColorSecondary + )) } - private class NormalViewHolder(val binding: ItemTimetableBinding) : + private class ItemViewHolder(val binding: ItemTimetableBinding) : RecyclerView.ViewHolder(binding.root) - private class SmallViewHolder(val binding: ItemTimetableSmallBinding) : + private class SmallItemViewHolder(val binding: ItemTimetableSmallBinding) : RecyclerView.ViewHolder(binding.root) - - private class EmptyViewHolder(val binding: ItemTimetableEmptyBinding) : - RecyclerView.ViewHolder(binding.root) - - private class AdditionalViewHolder(val binding: ItemTimetableMainAdditionalBinding) : - RecyclerView.ViewHolder(binding.root) - - private object Differ : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: TimetableItem, newItem: TimetableItem): Boolean = - when { - oldItem is TimetableItem.Small && newItem is TimetableItem.Small -> { - oldItem.lesson.start == newItem.lesson.start - } - - oldItem is TimetableItem.Normal && newItem is TimetableItem.Normal -> { - oldItem.lesson.start == newItem.lesson.start - } - - else -> oldItem == newItem - } - - override fun areContentsTheSame(oldItem: TimetableItem, newItem: TimetableItem) = - oldItem == newItem - - override fun getChangePayload(oldItem: TimetableItem, newItem: TimetableItem): Any? { - return if (oldItem is TimetableItem.Normal && newItem is TimetableItem.Normal) { - if (oldItem.lesson == newItem.lesson && oldItem.showGroupsInPlan == newItem.showGroupsInPlan && oldItem.timeLeft != newItem.timeLeft) { - "time_left" - } else super.getChangePayload(oldItem, newItem) - } else super.getChangePayload(oldItem, newItem) - } - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt index e8a85347..f7d5b1ed 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt @@ -1,52 +1,55 @@ package io.github.wulkanowy.ui.modules.timetable import android.annotation.SuppressLint -import android.app.Dialog import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG import android.os.Bundle +import android.view.LayoutInflater import android.view.View import android.view.View.GONE import android.view.View.VISIBLE -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.databinding.DialogTimetableBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.* -import java.time.Instant +import io.github.wulkanowy.utils.getThemeAttrColor +import io.github.wulkanowy.utils.lifecycleAwareVariable +import io.github.wulkanowy.utils.toFormattedString +import java.time.LocalDateTime -@AndroidEntryPoint -class TimetableDialog : BaseDialogFragment() { +class TimetableDialog : DialogFragment() { + + private var binding: DialogTimetableBinding by lifecycleAwareVariable() private lateinit var lesson: Timetable companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(lesson: Timetable) = TimetableDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to lesson) + fun newInstance(exam: Timetable): TimetableDialog { + return TimetableDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - lesson = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + lesson = getSerializable(ARGUMENT_KEY) as Timetable + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView(DialogTimetableBinding.inflate(layoutInflater).apply { binding = this }.root) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogTimetableBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(lesson) { - setInfo(info, canceled, changes) + setInfo(info, teacher, canceled, changes) setSubject(subject, subjectOld) setTeacher(teacher, teacherOld) setGroup(group) @@ -59,13 +62,13 @@ class TimetableDialog : BaseDialogFragment() { private fun setSubject(subject: String, subjectOld: String) { with(binding) { - timetableDialogLessonValue.text = subject + timetableDialogSubject.text = subject if (subjectOld.isNotBlank() && subjectOld != subject) { - timetableDialogLessonValue.run { + timetableDialogSubject.run { paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG text = subjectOld } - timetableDialogLessonNewValue.run { + timetableDialogSubjectNew.run { visibility = VISIBLE text = subject } @@ -73,43 +76,28 @@ class TimetableDialog : BaseDialogFragment() { } } - @SuppressLint("DefaultLocale") - private fun setInfo(info: String, canceled: Boolean, changes: Boolean) { + private fun setInfo(info: String, teacher: String, canceled: Boolean, changes: Boolean) { with(binding) { when { info.isNotBlank() -> { if (canceled) { - timetableDialogChangesTitle.setTextColor( - requireContext().getThemeAttrColor( - R.attr.colorTimetableCanceled - ) - ) - timetableDialogChangesValue.setTextColor( - requireContext().getThemeAttrColor( - R.attr.colorTimetableCanceled - ) - ) + timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary)) + timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorPrimary)) } else { - timetableDialogChangesTitle.setTextColor( - requireContext().getThemeAttrColor( - R.attr.colorTimetableChange - ) - ) - timetableDialogChangesValue.setTextColor( - requireContext().getThemeAttrColor( - R.attr.colorTimetableChange - ) - ) + timetableDialogChangesTitle.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange)) + timetableDialogChanges.setTextColor(requireContext().getThemeAttrColor(R.attr.colorTimetableChange)) } - timetableDialogChangesValue.text = when { + timetableDialogChanges.text = when { canceled && !changes -> "Lekcja odwołana: $info" - else -> info.capitalise() + changes && teacher.isNotBlank() -> "Zastępstwo: $teacher" + changes && teacher.isBlank() -> "Zastępstwo, ${info.decapitalize()}" + else -> info.capitalize() } } else -> { timetableDialogChangesTitle.visibility = GONE - timetableDialogChangesValue.visibility = GONE + timetableDialogChanges.visibility = GONE } } } @@ -119,31 +107,22 @@ class TimetableDialog : BaseDialogFragment() { with(binding) { when { teacherOld.isNotBlank() && teacherOld != teacher -> { - timetableDialogTeacherValue.run { + timetableDialogTeacher.run { visibility = VISIBLE paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG text = teacherOld } if (teacher.isNotBlank()) { - timetableDialogTeacherNewValue.run { + timetableDialogTeacherNew.run { visibility = VISIBLE text = teacher } } } - teacherOld.isNotBlank() && teacherOld == teacher -> { - timetableDialogTeacherValue.run { - visibility = GONE - } - timetableDialogTeacherNewValue.run { - visibility = VISIBLE - text = teacher - } - } - teacher.isNotBlank() -> timetableDialogTeacherValue.text = teacher + teacher.isNotBlank() -> timetableDialogTeacher.text = teacher else -> { timetableDialogTeacherTitle.visibility = GONE - timetableDialogTeacherValue.visibility = GONE + timetableDialogTeacher.visibility = GONE } } } @@ -152,10 +131,10 @@ class TimetableDialog : BaseDialogFragment() { private fun setGroup(group: String) { with(binding) { when { - group.isNotBlank() -> timetableDialogGroupValue.text = group + group.isNotBlank() -> timetableDialogGroup.text = group else -> { timetableDialogGroupTitle.visibility = GONE - timetableDialogGroupValue.visibility = GONE + timetableDialogGroup.visibility = GONE } } } @@ -165,30 +144,29 @@ class TimetableDialog : BaseDialogFragment() { with(binding) { when { roomOld.isNotBlank() && roomOld != room -> { - timetableDialogRoomValue.run { + timetableDialogRoom.run { visibility = VISIBLE paintFlags = paintFlags or STRIKE_THRU_TEXT_FLAG text = roomOld } if (room.isNotBlank()) { - timetableDialogRoomNewValue.run { + timetableDialogRoomNew.run { visibility = VISIBLE text = room } } } - room.isNotBlank() -> timetableDialogRoomValue.text = room + room.isNotBlank() -> timetableDialogRoom.text = room else -> { timetableDialogRoomTitle.visibility = GONE - timetableDialogRoomValue.visibility = GONE + timetableDialogRoom.visibility = GONE } } } } @SuppressLint("SetTextI18n") - private fun setTime(start: Instant, end: Instant) { - binding.timetableDialogTimeValue.text = - "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}" + private fun setTime(start: LocalDateTime, end: LocalDateTime) { + binding.timetableDialogTime.text = "${start.toFormattedString("HH:mm")} - ${end.toFormattedString("HH:mm")}" } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt index b73e7c26..4aa375c2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt @@ -7,10 +7,8 @@ import android.view.MenuItem import android.view.View import android.view.View.GONE import android.view.View.VISIBLE -import androidx.core.os.bundleOf -import androidx.core.text.parseAsHtml -import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable @@ -18,14 +16,10 @@ import io.github.wulkanowy.databinding.FragmentTimetableBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.timetable.additional.AdditionalLessonsFragment import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment import io.github.wulkanowy.ui.widgets.DividerItemDecoration +import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear -import io.github.wulkanowy.utils.openMaterialDatePicker import java.time.LocalDate import javax.inject.Inject @@ -42,20 +36,15 @@ class TimetableFragment : BaseFragment(R.layout.fragme companion object { private const val SAVED_DATE_KEY = "CURRENT_DATE" - private const val ARGUMENT_DATE_KEY = "ARGUMENT_DATE" - - fun newInstance(date: LocalDate? = null) = TimetableFragment().apply { - arguments = date?.let { bundleOf(ARGUMENT_DATE_KEY to it.toEpochDay()) } - } + fun newInstance() = TimetableFragment() } override val titleStringId get() = R.string.timetable_title - override val isViewEmpty get() = timetableAdapter.itemCount == 0 + override val isViewEmpty get() = timetableAdapter.items.isEmpty() override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize - @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -65,14 +54,12 @@ class TimetableFragment : BaseFragment(R.layout.fragme super.onViewCreated(view, savedInstanceState) binding = FragmentTimetableBinding.bind(view) messageContainer = binding.timetableRecycler - - val initDate = savedInstanceState?.getLong(SAVED_DATE_KEY) - ?: arguments?.getLong(ARGUMENT_DATE_KEY)?.takeUnless { it == 0L } - - presenter.onAttachView(this, initDate) + presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY)) } override fun initView() { + timetableAdapter.onClickListener = presenter::onTimetableItemSelected + with(binding.timetableRecycler) { layoutManager = LinearLayoutManager(context) adapter = timetableAdapter @@ -81,10 +68,6 @@ class TimetableFragment : BaseFragment(R.layout.fragme with(binding) { timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - timetableSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - timetableSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) timetableErrorRetry.setOnClickListener { presenter.onRetry() } timetableErrorDetails.setOnClickListener { presenter.onDetailsClick() } @@ -92,7 +75,7 @@ class TimetableFragment : BaseFragment(R.layout.fragme timetableNavDate.setOnClickListener { presenter.onPickDate() } timetableNextButton.setOnClickListener { presenter.onNextDay() } - timetableNavContainer.elevation = requireContext().dpToPx(3f) + timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } } @@ -101,30 +84,33 @@ class TimetableFragment : BaseFragment(R.layout.fragme } override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.timetableMenuAdditionalLessons -> presenter.onAdditionalLessonsSwitchSelected() - R.id.timetableMenuCompletedLessons -> presenter.onCompletedLessonsSwitchSelected() - else -> false - } + return if (item.itemId == R.id.timetableMenuCompletedLessons) presenter.onCompletedLessonsSwitchSelected() + else false } - override fun updateData(data: List, isDayChanged: Boolean) { - when { - isDayChanged -> timetableAdapter.recreate(data) - else -> timetableAdapter.submitList(data) + override fun updateData(data: List, showWholeClassPlanType: String, showGroupsInPlanType: Boolean, showTimetableTimers: Boolean) { + with(timetableAdapter) { + items = data.toMutableList() + showTimers = showTimetableTimers + showWholeClassPlan = showWholeClassPlanType + showGroupsInPlan = showGroupsInPlanType + notifyDataSetChanged() } } override fun clearData() { - timetableAdapter.submitList(listOf()) + with(timetableAdapter) { + items = mutableListOf() + notifyDataSetChanged() + } } override fun updateNavigationDay(date: String) { binding.timetableNavDate.text = date } - override fun showRefresh(show: Boolean) { - binding.timetableSwipe.isRefreshing = show + override fun hideRefresh() { + binding.timetableSwipe.isRefreshing = false } override fun resetView() { @@ -143,11 +129,6 @@ class TimetableFragment : BaseFragment(R.layout.fragme binding.timetableEmpty.visibility = if (show) VISIBLE else GONE } - override fun setDayHeaderMessage(message: String?) { - binding.timetableEmptyMessage.visibility = if (message.isNullOrEmpty()) GONE else VISIBLE - binding.timetableEmptyMessage.text = message.orEmpty().parseAsHtml() - } - override fun showErrorView(show: Boolean) { binding.timetableError.visibility = if (show) VISIBLE else GONE } @@ -168,10 +149,6 @@ class TimetableFragment : BaseFragment(R.layout.fragme binding.timetableRecycler.visibility = if (show) VISIBLE else GONE } - override fun showNavigation(show: Boolean) { - binding.timetableNavContainer.isVisible = true - } - override fun showPreButton(show: Boolean) { binding.timetablePreviousButton.visibility = if (show) VISIBLE else View.INVISIBLE } @@ -184,19 +161,19 @@ class TimetableFragment : BaseFragment(R.layout.fragme (activity as? MainActivity)?.showDialogFragment(TimetableDialog.newInstance(lesson)) } - override fun showDatePickerDialog(selectedDate: LocalDate) { - openMaterialDatePicker( - selected = selectedDate, - rangeStart = selectedDate.firstSchoolDayInSchoolYear, - rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear, - onDateSelected = { - presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth) - } - ) - } + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) - override fun openAdditionalLessonsView() { - (activity as? MainActivity)?.pushView(AdditionalLessonsFragment.newInstance()) + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@TimetableFragment.parentFragmentManager, null) + } } override fun openCompletedLessonsView() { @@ -205,12 +182,11 @@ class TimetableFragment : BaseFragment(R.layout.fragme override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - presenter.currentDate?.toEpochDay()?.let { - outState.putLong(SAVED_DATE_KEY, it) - } + outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) } override fun onDestroyView() { + timetableAdapter.resetTimers() presenter.onDetachView() super.onDestroyView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt deleted file mode 100644 index 93290ba2..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableItem.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable - -import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import java.time.Duration - -sealed class TimetableItem(val type: TimetableItemType) { - - data class Small( - val lesson: Timetable, - val isLessonNumberVisible: Boolean, - val onClick: (Timetable) -> Unit, - ) : TimetableItem(TimetableItemType.SMALL) - - data class Normal( - val lesson: Timetable, - val showGroupsInPlan: Boolean, - val isLessonNumberVisible: Boolean, - val timeLeft: TimeLeft?, - val onClick: (Timetable) -> Unit, - ) : TimetableItem(TimetableItemType.NORMAL) - - data class Empty( - val numFrom: Int, - val numTo: Int - ) : TimetableItem(TimetableItemType.EMPTY) - - data class Additional( - val additional: TimetableAdditional, - ) : TimetableItem(TimetableItemType.ADDITIONAL) -} - -data class TimeLeft( - val until: Duration?, - val left: Duration?, - val isJustFinished: Boolean, -) - -enum class TimetableItemType { - SMALL, - NORMAL, - EMPTY, - ADDITIONAL, -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index c00bdc3e..0e913acf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -1,114 +1,81 @@ package io.github.wulkanowy.ui.modules.timetable -import android.os.Handler -import android.os.Looper -import io.github.wulkanowy.data.db.entities.Semester +import android.annotation.SuppressLint +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.enums.ShowAdditionalLessonsMode.BELOW -import io.github.wulkanowy.data.enums.ShowAdditionalLessonsMode.NONE -import io.github.wulkanowy.data.enums.TimetableGapsMode.BETWEEN_AND_BEFORE_LESSONS -import io.github.wulkanowy.data.enums.TimetableGapsMode.NO_GAPS -import io.github.wulkanowy.data.enums.TimetableMode -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceIntermediate -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.pojos.TimetableFull -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase -import io.github.wulkanowy.domain.timetable.IsWeekendHasLessonsUseCase +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.timetable.TimetableRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.capitalise +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.isJustFinished -import io.github.wulkanowy.utils.isShowTimeUntil -import io.github.wulkanowy.utils.left import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousSchoolDay import io.github.wulkanowy.utils.toFormattedString -import io.github.wulkanowy.utils.until +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.onEach import timber.log.Timber -import java.time.Instant import java.time.LocalDate import java.time.LocalDate.now import java.time.LocalDate.of import java.time.LocalDate.ofEpochDay -import java.util.Timer import javax.inject.Inject -import kotlin.concurrent.timer class TimetablePresenter @Inject constructor( errorHandler: ErrorHandler, studentRepository: StudentRepository, private val timetableRepository: TimetableRepository, - private val isStudentHasLessonsOnWeekendUseCase: IsStudentHasLessonsOnWeekendUseCase, - private val isWeekendHasLessonsUseCase: IsWeekendHasLessonsUseCase, private val semesterRepository: SemesterRepository, private val prefRepository: PreferencesRepository, - private val analytics: AnalyticsHelper, + private val analytics: AnalyticsHelper ) : BasePresenter(errorHandler, studentRepository) { - private var initialDate: LocalDate? = null - private var isWeekendHasLessons: Boolean = false - private var isEduOne: Boolean = false + private var baseDate: LocalDate = now().nextOrSameSchoolDay - var currentDate: LocalDate? = null + lateinit var currentDate: LocalDate private set private lateinit var lastError: Throwable - private var tickTimer: Timer? = null - fun onAttachView(view: TimetableView, date: Long?) { super.onAttachView(view) view.initView() Timber.i("Timetable was initialized") errorHandler.showErrorMessage = ::showErrorViewOnError - currentDate = date?.let(::ofEpochDay) - loadData() + loadData(ofEpochDay(date ?: baseDate.toEpochDay())) + if (currentDate.isHolidays) setBaseDateOnHolidays() + reloadView() } fun onPreviousDay() { - val date = if (isWeekendHasLessons) { - currentDate?.minusDays(1) - } else currentDate?.previousSchoolDay - - reloadView(date ?: return) - loadData(isDayChanged = true) + loadData(currentDate.previousSchoolDay) + reloadView() } fun onNextDay() { - val date = if (isWeekendHasLessons) { - currentDate?.plusDays(1) - } else currentDate?.nextSchoolDay - - reloadView(date ?: return) - loadData(isDayChanged = true) + loadData(currentDate.nextSchoolDay) + reloadView() } fun onPickDate() { - view?.showDatePickerDialog(currentDate ?: return) + view?.showDatePickerDialog(currentDate) } fun onDateSet(year: Int, month: Int, day: Int) { - reloadView(of(year, month, day)) - loadData() + loadData(of(year, month, day)) + reloadView() } fun onSwipeRefresh() { Timber.i("Force refreshing the timetable") - loadData(forceRefresh = true) + loadData(currentDate, true) } fun onRetry() { @@ -116,7 +83,7 @@ class TimetablePresenter @Inject constructor( showErrorView(false) showProgress(true) } - loadData(forceRefresh = true) + loadData(currentDate, true) } fun onDetailsClick() { @@ -125,23 +92,21 @@ class TimetablePresenter @Inject constructor( fun onViewReselected() { Timber.i("Timetable view is reselected") - view?.let { view -> + view?.also { view -> if (view.currentStackSize == 1) { - if (currentDate != initialDate) { - reloadView(initialDate ?: return) - loadData() - } else if (!view.isViewEmpty) { - view.resetView() + baseDate.also { + if (currentDate != it) { + loadData(it) + reloadView() + } else if (!view.isViewEmpty) view.resetView() } - } else { - view.popView() - } + } else view.popView() } } - fun onAdditionalLessonsSwitchSelected(): Boolean { - view?.openAdditionalLessonsView() - return true + fun onTimetableItemSelected(lesson: Timetable) { + Timber.i("Select timetable item ${lesson.id}") + view?.showTimetableDialog(lesson) } fun onCompletedLessonsSwitchSelected(): Boolean { @@ -149,197 +114,62 @@ class TimetablePresenter @Inject constructor( return true } - private fun loadData(forceRefresh: Boolean = false, isDayChanged: Boolean = false) { - flatResourceFlow { + private fun setBaseDateOnHolidays() { + flow { + val student = studentRepository.getCurrentStudent() + emit(semesterRepository.getCurrentSemester(student)) + }.catch { + Timber.i("Loading semester result: An exception occurred") + }.onEach { + baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) + currentDate = baseDate + reloadNavigation() + }.launch("holidays") + } + + private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { + currentDate = date + + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - - isEduOne = student.isEduOne == true - checkInitialAndCurrentDate(semester) - timetableRepository.getTimetable( - student = student, - semester = semester, - start = currentDate ?: now(), - end = currentDate ?: now(), - forceRefresh = forceRefresh, - timetableType = TimetableRepository.TimetableType.NORMAL - ) - } - .logResourceStatus("load timetable data") - .onResourceData { - isWeekendHasLessons = isWeekendHasLessons || isWeekendHasLessonsUseCase(it.lessons) - - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - updateData(it, isDayChanged) - showContent(it.lessons.isNotEmpty() || it.additional.isNotEmpty()) - showEmpty(it.lessons.isEmpty() && it.additional.isEmpty()) - setDayHeaderMessage(it.headers.find { header -> header.date == currentDate }?.content) - reloadNavigation() - } - } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "timetable", - "items" to it.lessons.size - ) - } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private suspend fun checkInitialAndCurrentDate(semester: Semester) { - if (initialDate == null) { - isWeekendHasLessons = isStudentHasLessonsOnWeekendUseCase(semester) - initialDate = getInitialDate(semester) - } - - if (currentDate == null) { - currentDate = initialDate - } - } - - private fun getInitialDate(semester: Semester): LocalDate { - val now = now() - - return when { - now.isHolidays -> now.getLastSchoolDayIfHoliday(semester.schoolYear) - isWeekendHasLessons -> now - else -> now.nextOrSameSchoolDay - } - } - - private fun updateData(lessons: TimetableFull, isDayChanged: Boolean) { - tickTimer?.cancel() - - view?.updateData(createItems(lessons), isDayChanged) - if (currentDate == now()) { - tickTimer = timer(period = 2_000, initialDelay = 2_000) { - Handler(Looper.getMainLooper()).post { - view?.updateData(createItems(lessons), isDayChanged) - } - } - } - } - - private sealed class Item( - val isStudentPlan: Boolean, - val start: Instant, - val number: Int?, - ) { - class Lesson(val lesson: Timetable) : - Item(lesson.isStudentPlan, lesson.start, lesson.number) - - class Additional(val additional: TimetableAdditional) : Item(true, additional.start, null) - } - - private fun createItems(fullTimetable: TimetableFull): List { - val showAdditionalLessonsInPlan = prefRepository.showAdditionalLessonsInPlan - val allItems = - fullTimetable.lessons.map(Item::Lesson) + fullTimetable.additional.map(Item::Additional) - .takeIf { showAdditionalLessonsInPlan != NONE }.orEmpty() - - val filteredItems = allItems.filter { - if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) { - it.isStudentPlan - } else true - }.sortedWith( - (compareBy { it is Item.Additional } - .takeIf { showAdditionalLessonsInPlan == BELOW } ?: EmptyComparator()) - .thenBy { it.start } - .thenBy { !it.isStudentPlan } - ) - - var prevNum = when (prefRepository.showTimetableGaps) { - BETWEEN_AND_BEFORE_LESSONS -> 0 - else -> null - } - var prevIsAdditional = false - return buildList { - filteredItems.forEachIndexed { i, it -> - if (prefRepository.showTimetableGaps != NO_GAPS) { - if (prevNum != null && it.number != null && it.number > prevNum!! + 1) { - if (!prevIsAdditional) { - // Additional lessons do count as a lesson so don't add empty lessons - // when there is an additional lesson present - val emptyLesson = TimetableItem.Empty( - numFrom = prevNum!! + 1, numTo = it.number - 1 - ) - add(emptyLesson) - } - } - prevNum = it.number - prevIsAdditional = it is Item.Additional - } - - if (it is Item.Lesson) { - if (it.isStudentPlan) { - val normalLesson = TimetableItem.Normal( - lesson = it.lesson, - showGroupsInPlan = prefRepository.showGroupsInPlan, - timeLeft = filteredItems.getTimeLeftForLesson(it.lesson, i), - onClick = ::onTimetableItemSelected, - isLessonNumberVisible = !isEduOne + timetableRepository.getTimetable(student, semester, date, date, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading timetable data started") + Status.SUCCESS -> { + Timber.i("Loading timetable result: Success") + view?.apply { + updateData( + showWholeClassPlanType = prefRepository.showWholeClassPlan, + showGroupsInPlanType = prefRepository.showGroupsInPlan, + showTimetableTimers = prefRepository.showTimetableTimers, + data = it.data!! + .filter { item -> if (prefRepository.showWholeClassPlan == "no") item.isStudentPlan else true } + .sortedWith(compareBy({ item -> item.number }, { item -> !item.isStudentPlan })) ) - add(normalLesson) - } else { - val smallLesson = TimetableItem.Small( - lesson = it.lesson, - onClick = ::onTimetableItemSelected, - isLessonNumberVisible = !isEduOne - ) - add(smallLesson) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) } - } else if (it is Item.Additional) { - // If the user disabled showing additional lessons, they would've been filtered - // out already, so there's no need to check it again. - add(TimetableItem.Additional(it.additional)) + analytics.logEvent( + "load_data", + "type" to "timetable", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading timetable result: An exception occurred") + errorHandler.dispatch(it.error!!) } } - } - } - - private fun List.getTimeLeftForLesson(lesson: Timetable, index: Int): TimeLeft { - val isShowTimeUntil = lesson.isShowTimeUntil(getPreviousLesson(index)) - return TimeLeft( - until = lesson.until.plusMinutes(1).takeIf { isShowTimeUntil }, - left = lesson.left?.plusMinutes(1), - isJustFinished = lesson.isJustFinished, - ) - } - - private fun List.getPreviousLesson(position: Int): Instant? { - val lessonAdditionalOffset = filterIndexed { i, item -> - i < position && item is Item.Additional - }.size - val lessonStudentPlanOffset = filterIndexed { i, item -> - i < position && !item.isStudentPlan - }.size - val lessonIndex = position - 1 - lessonAdditionalOffset - lessonStudentPlanOffset - - return filterIsInstance() - .filter { it.isStudentPlan } - .getOrNull(lessonIndex) - ?.let { - if (!it.lesson.canceled && it.isStudentPlan) it.lesson.end - else null + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - } - - private fun onTimetableItemSelected(lesson: Timetable) { - Timber.i("Select timetable item ${lesson.id}") - view?.showTimetableDialog(lesson) + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -353,10 +183,8 @@ class TimetablePresenter @Inject constructor( } } - private fun reloadView(date: LocalDate) { - currentDate = date - - Timber.i("Reload timetable view with the date ${currentDate?.toFormattedString()}") + private fun reloadView() { + Timber.i("Reload timetable view with the date ${currentDate.toFormattedString()}") view?.apply { showProgress(true) enableSwipe(false) @@ -368,24 +196,12 @@ class TimetablePresenter @Inject constructor( } } + @SuppressLint("DefaultLocale") private fun reloadNavigation() { - val currentDate = currentDate ?: return - view?.apply { showPreButton(!currentDate.minusDays(1).isHolidays) showNextButton(!currentDate.plusDays(1).isHolidays) - updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalise()) - showNavigation(true) + updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalize()) } } - - override fun onDetachView() { - tickTimer?.cancel() - tickTimer = null - super.onDetachView() - } -} - -private class EmptyComparator : Comparator { - override fun compare(o1: T, o2: T) = 0 } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt index f4d5b762..24412017 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt @@ -12,20 +12,18 @@ interface TimetableView : BaseView { fun initView() - fun updateData(data: List, isDayChanged: Boolean) + fun updateData(data: List, showWholeClassPlanType: String, showGroupsInPlanType: Boolean, showTimetableTimers: Boolean) fun updateNavigationDay(date: String) fun clearData() - fun showRefresh(show: Boolean) + fun hideRefresh() fun resetView() fun showEmpty(show: Boolean) - fun setDayHeaderMessage(message: String?) - fun showErrorView(show: Boolean) fun setErrorDetails(message: String) @@ -36,19 +34,15 @@ interface TimetableView : BaseView { fun showContent(show: Boolean) - fun showNavigation(show: Boolean) - fun showPreButton(show: Boolean) fun showNextButton(show: Boolean) fun showTimetableDialog(lesson: Timetable) - fun showDatePickerDialog(selectedDate: LocalDate) + fun showDatePickerDialog(currentDate: LocalDate) fun popView() - fun openAdditionalLessonsView() - fun openCompletedLessonsView() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsAdapter.kt deleted file mode 100644 index c2ce8028..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsAdapter.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.databinding.ItemTimetableAdditionalBinding -import io.github.wulkanowy.utils.toFormattedString -import javax.inject.Inject - -class AdditionalLessonsAdapter @Inject constructor() : - RecyclerView.Adapter() { - - var items = emptyList() - - var onDeleteClickListener: (timetableAdditional: TimetableAdditional) -> Unit = {} - - override fun getItemCount() = items.size - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder( - ItemTimetableAdditionalBinding.inflate(LayoutInflater.from(parent.context), parent, false) - ) - - @SuppressLint("SetTextI18n") - override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { - val item = items[position] - - with(holder.binding) { - additionalLessonItemTime.text = - "${item.start.toFormattedString("HH:mm")} - ${item.end.toFormattedString("HH:mm")}" - additionalLessonItemSubject.text = item.subject - - additionalLessonItemDelete.isVisible = item.isAddedByUser - additionalLessonItemDelete.setOnClickListener { onDeleteClickListener(item) } - } - } - - class ItemViewHolder(val binding: ItemTimetableAdditionalBinding) : - RecyclerView.ViewHolder(binding.root) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsFragment.kt deleted file mode 100644 index bf6be56f..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsFragment.kt +++ /dev/null @@ -1,181 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional - -import android.os.Bundle -import android.view.View -import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.databinding.FragmentTimetableAdditionalBinding -import io.github.wulkanowy.ui.base.BaseFragment -import io.github.wulkanowy.ui.modules.main.MainActivity -import io.github.wulkanowy.ui.modules.main.MainView -import io.github.wulkanowy.ui.modules.timetable.additional.add.AdditionalLessonAddDialog -import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.dpToPx -import io.github.wulkanowy.utils.firstSchoolDayInSchoolYear -import io.github.wulkanowy.utils.getThemeAttrColor -import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear -import io.github.wulkanowy.utils.openMaterialDatePicker -import java.time.LocalDate -import javax.inject.Inject - -@AndroidEntryPoint -class AdditionalLessonsFragment : - BaseFragment(R.layout.fragment_timetable_additional), - AdditionalLessonsView, MainView.TitledView { - - @Inject - lateinit var presenter: AdditionalLessonsPresenter - - @Inject - lateinit var additionalLessonsAdapter: AdditionalLessonsAdapter - - companion object { - private const val SAVED_DATE_KEY = "CURRENT_DATE" - - fun newInstance() = AdditionalLessonsFragment() - } - - override val titleStringId get() = R.string.additional_lessons_title - - override val isViewEmpty get() = additionalLessonsAdapter.items.isEmpty() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding = FragmentTimetableAdditionalBinding.bind(view) - messageContainer = binding.additionalLessonsRecycler - presenter.onAttachView(this, savedInstanceState?.getLong(SAVED_DATE_KEY)) - } - - override fun initView() { - with(binding.additionalLessonsRecycler) { - layoutManager = LinearLayoutManager(context) - adapter = additionalLessonsAdapter.apply { - onDeleteClickListener = { presenter.onDeleteLessonsSelected(it) } - } - addItemDecoration(DividerItemDecoration(context)) - } - - with(binding) { - additionalLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - additionalLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - additionalLessonsSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) - additionalLessonsErrorRetry.setOnClickListener { presenter.onRetry() } - additionalLessonsErrorDetails.setOnClickListener { presenter.onDetailsClick() } - - additionalLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() } - additionalLessonsNavDate.setOnClickListener { presenter.onPickDate() } - additionalLessonsNextButton.setOnClickListener { presenter.onNextDay() } - - openAddAdditionalLessonButton.setOnClickListener { presenter.onAdditionalLessonAddButtonClicked() } - - additionalLessonsNavContainer.elevation = requireContext().dpToPx(3f) - } - } - - override fun updateData(data: List) { - with(additionalLessonsAdapter) { - items = data - notifyDataSetChanged() - } - } - - override fun clearData() { - with(additionalLessonsAdapter) { - items = emptyList() - notifyDataSetChanged() - } - } - - override fun showSuccessMessage() { - getString(R.string.additional_lessons_delete_success) - } - - override fun updateNavigationDay(date: String) { - binding.additionalLessonsNavDate.text = date - } - - override fun hideRefresh() { - binding.additionalLessonsSwipe.isRefreshing = false - } - - override fun showEmpty(show: Boolean) { - binding.additionalLessonsEmpty.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showErrorView(show: Boolean) { - binding.additionalLessonsError.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun setErrorDetails(message: String) { - binding.additionalLessonsErrorMessage.text = message - } - - override fun showProgress(show: Boolean) { - binding.additionalLessonsProgress.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun enableSwipe(enable: Boolean) { - binding.additionalLessonsSwipe.isEnabled = enable - } - - override fun showContent(show: Boolean) { - binding.additionalLessonsRecycler.visibility = if (show) View.VISIBLE else View.GONE - } - - override fun showPreButton(show: Boolean) { - binding.additionalLessonsPreviousButton.visibility = - if (show) View.VISIBLE else View.INVISIBLE - } - - override fun showNextButton(show: Boolean) { - binding.additionalLessonsNextButton.visibility = if (show) View.VISIBLE else View.INVISIBLE - } - - override fun showAddAdditionalLessonDialog(currentDate: LocalDate) { - (activity as? MainActivity)?.showDialogFragment( - AdditionalLessonAddDialog.newInstance( - currentDate - ) - ) - } - - override fun showDatePickerDialog(selectedDate: LocalDate) { - val now = LocalDate.now() - - openMaterialDatePicker( - selected = selectedDate, - rangeStart = now.firstSchoolDayInSchoolYear, - rangeEnd = now.lastSchoolDayInSchoolYear, - onDateSelected = { - presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth) - } - ) - } - - override fun showDeleteLessonDialog(timetableAdditional: TimetableAdditional) { - MaterialAlertDialogBuilder(requireContext()) - .setTitle(getString(R.string.additional_lessons_delete_title)) - .setItems( - arrayOf( - getString(R.string.additional_lessons_delete_one), - getString(R.string.additional_lessons_delete_series) - ) - ) { _, position -> presenter.onDeleteDialogSelectItem(position, timetableAdditional) } - .show() - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsPresenter.kt deleted file mode 100644 index 16ec9746..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsPresenter.kt +++ /dev/null @@ -1,227 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional - -import android.annotation.SuppressLint -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.flatResourceFlow -import io.github.wulkanowy.data.logResourceStatus -import io.github.wulkanowy.data.onResourceData -import io.github.wulkanowy.data.onResourceError -import io.github.wulkanowy.data.onResourceNotLoading -import io.github.wulkanowy.data.onResourceSuccess -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.domain.timetable.IsStudentHasLessonsOnWeekendUseCase -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.AnalyticsHelper -import io.github.wulkanowy.utils.capitalise -import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday -import io.github.wulkanowy.utils.isHolidays -import io.github.wulkanowy.utils.nextOrSameSchoolDay -import io.github.wulkanowy.utils.nextSchoolDay -import io.github.wulkanowy.utils.previousSchoolDay -import io.github.wulkanowy.utils.toFormattedString -import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import timber.log.Timber -import java.time.LocalDate -import javax.inject.Inject - -class AdditionalLessonsPresenter @Inject constructor( - studentRepository: StudentRepository, - errorHandler: ErrorHandler, - private val semesterRepository: SemesterRepository, - private val timetableRepository: TimetableRepository, - private val isStudentHasLessonsOnWeekendUseCase: IsStudentHasLessonsOnWeekendUseCase, - private val analytics: AnalyticsHelper -) : BasePresenter(errorHandler, studentRepository) { - - private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay - - private var isWeekendHasLessons: Boolean = false - - lateinit var currentDate: LocalDate - private set - - private lateinit var lastError: Throwable - - fun onAttachView(view: AdditionalLessonsView, date: Long?) { - super.onAttachView(view) - view.initView() - Timber.i("Additional lessons was initialized") - errorHandler.showErrorMessage = ::showErrorViewOnError - loadData(LocalDate.ofEpochDay(date ?: baseDate.toEpochDay())) - if (currentDate.isHolidays) setBaseDateOnHolidays() - reloadView() - } - - fun onPreviousDay() { - val date = if (isWeekendHasLessons) { - currentDate.minusDays(1) - } else currentDate.previousSchoolDay - loadData(date) - reloadView() - } - - fun onNextDay() { - val date = if (isWeekendHasLessons) { - currentDate.plusDays(1) - } else currentDate.nextSchoolDay - loadData(date) - reloadView() - } - - fun onPickDate() { - view?.showDatePickerDialog(currentDate) - } - - fun onAdditionalLessonAddButtonClicked() { - view?.showAddAdditionalLessonDialog(currentDate) - } - - fun onDateSet(year: Int, month: Int, day: Int) { - loadData(LocalDate.of(year, month, day)) - reloadView() - } - - fun onSwipeRefresh() { - Timber.i("Force refreshing the additional lessons") - loadData(currentDate, true) - } - - fun onRetry() { - view?.run { - showErrorView(false) - showProgress(true) - } - loadData(currentDate, true) - } - - fun onDetailsClick() { - view?.showErrorDetailsDialog(lastError) - } - - private fun setBaseDateOnHolidays() { - flow { - val student = studentRepository.getCurrentStudent() - emit(semesterRepository.getCurrentSemester(student)) - }.catch { - Timber.i("Loading semester result: An exception occurred") - }.onEach { - baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear) - currentDate = baseDate - reloadNavigation() - }.launch("holidays") - } - - fun onDeleteLessonsSelected(timetableAdditional: TimetableAdditional) { - if (timetableAdditional.repeatId == null) { - deleteAdditionalLessons(timetableAdditional, false) - } else { - view?.showDeleteLessonDialog(timetableAdditional) - } - } - - fun onDeleteDialogSelectItem(position: Int, timetableAdditional: TimetableAdditional) { - deleteAdditionalLessons(timetableAdditional, position == 1) - } - - private fun deleteAdditionalLessons( - timetableAdditional: TimetableAdditional, - deleteSeries: Boolean - ) { - presenterScope.launch { - Timber.i("Additional Lesson delete start") - runCatching { timetableRepository.deleteAdditional(timetableAdditional, deleteSeries) } - .onSuccess { - Timber.i("Additional Lesson delete: Success") - view?.showSuccessMessage() - } - .onFailure { - Timber.i("Additional Lesson delete result: An exception occurred") - errorHandler.dispatch(it) - } - } - } - - private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { - currentDate = date - - flatResourceFlow { - val student = studentRepository.getCurrentStudent() - val semester = semesterRepository.getCurrentSemester(student) - - isWeekendHasLessons = isStudentHasLessonsOnWeekendUseCase(semester, currentDate) - timetableRepository.getTimetable( - student = student, - semester = semester, - start = date, - end = date, - forceRefresh = forceRefresh, - refreshAdditional = true, - timetableType = TimetableRepository.TimetableType.ADDITIONAL - ) - } - .logResourceStatus("load additional lessons") - .onResourceData { - view?.apply { - updateData(it.additional.sortedBy { item -> item.start }) - showEmpty(it.additional.isEmpty()) - showErrorView(false) - showContent(it.additional.isNotEmpty()) - } - } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "additional_lessons", - "items" to it.additional.size - ) - } - .onResourceNotLoading { - view?.run { - hideRefresh() - showProgress(false) - enableSwipe(true) - } - } - .onResourceError(errorHandler::dispatch) - .launch() - } - - private fun showErrorViewOnError(message: String, error: Throwable) { - view?.run { - if (isViewEmpty) { - lastError = error - setErrorDetails(message) - showErrorView(true) - showEmpty(false) - } else showError(message, error) - } - } - - private fun reloadView() { - Timber.i("Reload additional lessons view with the date ${currentDate.toFormattedString()}") - view?.apply { - showProgress(true) - enableSwipe(false) - showContent(false) - showEmpty(false) - showErrorView(false) - clearData() - reloadNavigation() - } - } - - @SuppressLint("DefaultLocale") - private fun reloadNavigation() { - view?.apply { - showPreButton(!currentDate.minusDays(1).isHolidays) - showNextButton(!currentDate.plusDays(1).isHolidays) - updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalise()) - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsView.kt deleted file mode 100644 index 291c1217..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/AdditionalLessonsView.kt +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional - -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.ui.base.BaseView -import java.time.LocalDate - -interface AdditionalLessonsView : BaseView { - - val isViewEmpty: Boolean - - fun initView() - - fun updateData(data: List) - - fun clearData() - - fun updateNavigationDay(date: String) - - fun hideRefresh() - - fun showEmpty(show: Boolean) - - fun showErrorView(show: Boolean) - - fun setErrorDetails(message: String) - - fun showProgress(show: Boolean) - - fun enableSwipe(enable: Boolean) - - fun showContent(show: Boolean) - - fun showPreButton(show: Boolean) - - fun showNextButton(show: Boolean) - - fun showDatePickerDialog(selectedDate: LocalDate) - - fun showAddAdditionalLessonDialog(currentDate: LocalDate) - - fun showSuccessMessage() - - fun showDeleteLessonDialog(timetableAdditional: TimetableAdditional) -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddDialog.kt deleted file mode 100644 index 9470c910..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddDialog.kt +++ /dev/null @@ -1,178 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional.add - -import android.app.Dialog -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.core.widget.doOnTextChanged -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.timepicker.MaterialTimePicker -import com.google.android.material.timepicker.TimeFormat -import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.R -import io.github.wulkanowy.databinding.DialogAdditionalAddBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear -import io.github.wulkanowy.utils.openMaterialDatePicker -import io.github.wulkanowy.utils.toFormattedString -import java.time.LocalDate -import java.time.LocalTime -import javax.inject.Inject - -@AndroidEntryPoint -class AdditionalLessonAddDialog : BaseDialogFragment(), - AdditionalLessonAddView { - - @Inject - lateinit var presenter: AdditionalLessonAddPresenter - - companion object { - const val ARGUMENT_KEY = "additional_lesson_default_date" - fun newInstance(defaultDate: LocalDate) = AdditionalLessonAddDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to defaultDate.toEpochDay()) - } - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogAdditionalAddBinding.inflate(layoutInflater).apply { binding = this }.root - ) - .create() - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - arguments?.getLong(ARGUMENT_KEY)?.let(LocalDate::ofEpochDay)?.let { - presenter.onDateSelected(it) - } - presenter.onAttachView(this) - } - - override fun initView(selectedDate: LocalDate) { - with(binding) { - additionalLessonDialogStartEdit.doOnTextChanged { _, _, _, _ -> - additionalLessonDialogStart.isErrorEnabled = false - additionalLessonDialogStart.error = null - } - additionalLessonDialogEndEdit.doOnTextChanged { _, _, _, _ -> - additionalLessonDialogEnd.isErrorEnabled = false - additionalLessonDialogEnd.error = null - } - additionalLessonDialogDateEdit.setText(selectedDate.toFormattedString()) - additionalLessonDialogDateEdit.doOnTextChanged { _, _, _, _ -> - additionalLessonDialogDate.isErrorEnabled = false - additionalLessonDialogDate.error = null - } - additionalLessonDialogContentEdit.doOnTextChanged { _, _, _, _ -> - additionalLessonDialogContent.isErrorEnabled = false - additionalLessonDialogContent.error = null - } - additionalLessonDialogAdd.setOnClickListener { - presenter.onAddAdditionalClicked( - start = additionalLessonDialogStartEdit.text?.toString(), - end = additionalLessonDialogEndEdit.text?.toString(), - date = additionalLessonDialogDateEdit.text?.toString(), - content = additionalLessonDialogContentEdit.text?.toString(), - isRepeat = additionalLessonDialogRepeat.isChecked - ) - } - additionalLessonDialogClose.setOnClickListener { dismiss() } - additionalLessonDialogDateEdit.setOnClickListener { presenter.showDatePicker() } - additionalLessonDialogStartEdit.setOnClickListener { presenter.showStartTimePicker() } - additionalLessonDialogEndEdit.setOnClickListener { presenter.showEndTimePicker() } - } - } - - override fun showSuccessMessage() { - showMessage(getString(R.string.additional_lessons_add_success)) - } - - override fun setErrorDateRequired() { - with(binding.additionalLessonDialogDate) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorStartRequired() { - with(binding.additionalLessonDialogStart) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorEndRequired() { - with(binding.additionalLessonDialogEnd) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorContentRequired() { - with(binding.additionalLessonDialogContent) { - isErrorEnabled = true - error = getString(R.string.error_field_required) - } - } - - override fun setErrorIncorrectEndTime() { - with(binding.additionalLessonDialogEnd) { - isErrorEnabled = true - error = getString(R.string.additional_lessons_end_time_error) - } - } - - override fun closeDialog() { - dismiss() - } - - override fun showDatePickerDialog(selectedDate: LocalDate) { - openMaterialDatePicker( - selected = selectedDate, - rangeStart = LocalDate.now(), - rangeEnd = LocalDate.now().lastSchoolDayInSchoolYear, - onDateSelected = { - presenter.onDateSelected(it) - binding.additionalLessonDialogDateEdit.setText(it.toFormattedString()) - } - ) - } - - override fun showStartTimePickerDialog(selectedTime: LocalTime) { - showTimePickerDialog(selectedTime) { - presenter.onStartTimeSelected(it) - binding.additionalLessonDialogStartEdit.setText(it.toString()) - } - } - - override fun showEndTimePickerDialog(selectedTime: LocalTime) { - showTimePickerDialog(selectedTime) { - presenter.onEndTimeSelected(it) - binding.additionalLessonDialogEndEdit.setText(it.toString()) - } - } - - private fun showTimePickerDialog(defaultTime: LocalTime, onTimeSelected: (LocalTime) -> Unit) { - val timePicker = MaterialTimePicker.Builder() - .setTimeFormat(TimeFormat.CLOCK_24H) - .setHour(defaultTime.hour) - .setMinute(defaultTime.minute) - .build() - - timePicker.addOnPositiveButtonClickListener { - if (isAdded) { - onTimeSelected(LocalTime.of(timePicker.hour, timePicker.minute)) - } - } - - if (!parentFragmentManager.isStateSaved) { - timePicker.show(parentFragmentManager, null) - } - } - - override fun onDestroyView() { - presenter.onDetachView() - super.onDestroyView() - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt deleted file mode 100644 index db59a2ab..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddPresenter.kt +++ /dev/null @@ -1,167 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional.add - -import io.github.wulkanowy.data.db.entities.TimetableAdditional -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.ui.base.ErrorHandler -import io.github.wulkanowy.utils.lastSchoolDayInSchoolYear -import io.github.wulkanowy.utils.toLocalDate -import kotlinx.coroutines.launch -import timber.log.Timber -import java.time.LocalDate -import java.time.LocalTime -import java.time.ZoneId -import java.time.ZonedDateTime -import java.time.temporal.ChronoUnit -import java.util.UUID -import javax.inject.Inject - -class AdditionalLessonAddPresenter @Inject constructor( - errorHandler: ErrorHandler, - studentRepository: StudentRepository, - private val timetableRepository: TimetableRepository, - private val semesterRepository: SemesterRepository -) : BasePresenter(errorHandler, studentRepository) { - - private var selectedStartTime = LocalTime.of(15, 0) - - private var selectedEndTime = LocalTime.of(15, 45) - - private var selectedDate = LocalDate.now() - - override fun onAttachView(view: AdditionalLessonAddView) { - super.onAttachView(view) - view.initView(selectedDate) - Timber.i("AdditionalLesson details view was initialized") - } - - fun showDatePicker() { - view?.showDatePickerDialog(selectedDate) - } - - fun showStartTimePicker() { - view?.showStartTimePickerDialog(selectedStartTime) - } - - fun showEndTimePicker() { - view?.showEndTimePickerDialog(selectedEndTime) - } - - fun onStartTimeSelected(time: LocalTime) { - selectedStartTime = time - } - - fun onEndTimeSelected(time: LocalTime) { - selectedEndTime = time - } - - fun onDateSelected(date: LocalDate) { - selectedDate = date - } - - fun onAddAdditionalClicked( - start: String?, - end: String?, - date: String?, - content: String?, - isRepeat: Boolean - ) { - if (isUserInputValid(start, end, date, content)) { - addAdditionalLesson( - start = LocalTime.parse(start!!), - end = LocalTime.parse(end), - date = date!!.toLocalDate(), - subject = content!!, - isRepeat = isRepeat - ) - } - } - - private fun isUserInputValid( - start: String?, - end: String?, - date: String?, - content: String? - ): Boolean { - var isValid = true - - if (start.isNullOrBlank()) { - view?.setErrorStartRequired() - isValid = false - } - - if (end.isNullOrBlank()) { - view?.setErrorEndRequired() - isValid = false - } - - if (date.isNullOrBlank()) { - view?.setErrorDateRequired() - isValid = false - } - - if (content.isNullOrBlank()) { - view?.setErrorContentRequired() - isValid = false - } - - if (selectedStartTime >= selectedEndTime) { - view?.setErrorIncorrectEndTime() - isValid = false - } - - return isValid - } - - private fun addAdditionalLesson( - start: LocalTime, - end: LocalTime, - date: LocalDate, - subject: String, - isRepeat: Boolean - ) { - presenterScope.launch { - val semester = runCatching { - val student = studentRepository.getCurrentStudent() - semesterRepository.getCurrentSemester(student) - } - .onFailure(errorHandler::dispatch) - .getOrNull() ?: return@launch - - val weeks = if (isRepeat) { - ChronoUnit.WEEKS.between(date, date.lastSchoolDayInSchoolYear) - } else 0 - val uniqueRepeatId = UUID.randomUUID().takeIf { isRepeat } - - val lessonsToAdd = (0..weeks).map { - TimetableAdditional( - studentId = semester.studentId, - diaryId = semester.diaryId, - start = ZonedDateTime.of(date, start, ZoneId.systemDefault()).toInstant(), - end = ZonedDateTime.of(date, end, ZoneId.systemDefault()).toInstant(), - date = date.plusWeeks(it), - subject = subject - ).apply { - isAddedByUser = true - repeatId = uniqueRepeatId - } - } - - Timber.i("AdditionalLesson insert start") - runCatching { timetableRepository.saveAdditionalList(lessonsToAdd) } - .onSuccess { - Timber.i("AdditionalLesson insert: Success") - view?.run { - showSuccessMessage() - closeDialog() - } - } - .onFailure { - Timber.i("AdditionalLesson insert result: An exception occurred") - errorHandler.dispatch(it) - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddView.kt deleted file mode 100644 index 8d9678e7..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/additional/add/AdditionalLessonAddView.kt +++ /dev/null @@ -1,30 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetable.additional.add - -import io.github.wulkanowy.ui.base.BaseView -import java.time.LocalDate -import java.time.LocalTime - -interface AdditionalLessonAddView : BaseView { - - fun initView(selectedDate: LocalDate) - - fun closeDialog() - - fun showDatePickerDialog(selectedDate: LocalDate) - - fun showStartTimePickerDialog(selectedTime: LocalTime) - - fun showEndTimePickerDialog(selectedTime: LocalTime) - - fun showSuccessMessage() - - fun setErrorDateRequired() - - fun setErrorStartRequired() - - fun setErrorEndRequired() - - fun setErrorContentRequired() - - fun setErrorIncorrectEndTime() -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt index d937d4dd..56ea16cf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt @@ -1,80 +1,81 @@ package io.github.wulkanowy.ui.modules.timetable.completed -import android.app.Dialog +import android.annotation.SuppressLint import android.os.Bundle +import android.view.LayoutInflater import android.view.View -import androidx.core.os.bundleOf -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import dagger.hilt.android.AndroidEntryPoint +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.databinding.DialogLessonCompletedBinding -import io.github.wulkanowy.ui.base.BaseDialogFragment -import io.github.wulkanowy.utils.serializable +import io.github.wulkanowy.utils.lifecycleAwareVariable -@AndroidEntryPoint -class CompletedLessonDialog : BaseDialogFragment() { +class CompletedLessonDialog : DialogFragment() { + + private var binding: DialogLessonCompletedBinding by lifecycleAwareVariable() private lateinit var completedLesson: CompletedLesson companion object { - private const val ARGUMENT_KEY = "Item" - fun newInstance(lesson: CompletedLesson) = CompletedLessonDialog().apply { - arguments = bundleOf(ARGUMENT_KEY to lesson) + fun newInstance(exam: CompletedLesson): CompletedLessonDialog { + return CompletedLessonDialog().apply { + arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) } + } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - completedLesson = requireArguments().serializable(ARGUMENT_KEY) + setStyle(STYLE_NO_TITLE, 0) + arguments?.run { + completedLesson = getSerializable(ARGUMENT_KEY) as CompletedLesson + } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - return MaterialAlertDialogBuilder(requireContext(), theme) - .setView( - DialogLessonCompletedBinding.inflate(layoutInflater).apply { binding = this }.root - ) - .create() + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return DialogLessonCompletedBinding.inflate(inflater).apply { binding = this }.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + @SuppressLint("SetTextI18n") + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) with(binding) { - completedLessonDialogSubjectValue.text = completedLesson.subject - completedLessonDialogTopicValue.text = completedLesson.topic - completedLessonDialogTeacherValue.text = completedLesson.teacher - completedLessonDialogAbsenceValue.text = completedLesson.absence - completedLessonDialogChangesValue.text = completedLesson.substitution - completedLessonDialogResourcesValue.text = completedLesson.resources + completedLessonDialogSubject.text = completedLesson.subject + completedLessonDialogTopic.text = completedLesson.topic + completedLessonDialogTeacher.text = completedLesson.teacher + completedLessonDialogAbsence.text = completedLesson.absence + completedLessonDialogChanges.text = completedLesson.substitution + completedLessonDialogResources.text = completedLesson.resources } completedLesson.substitution.let { if (it.isBlank()) { with(binding) { completedLessonDialogChangesTitle.visibility = View.GONE - completedLessonDialogChangesValue.visibility = View.GONE + completedLessonDialogChanges.visibility = View.GONE } - } else binding.completedLessonDialogChangesValue.text = it + } else binding.completedLessonDialogChanges.text = it } completedLesson.absence.let { if (it.isBlank()) { with(binding) { completedLessonDialogAbsenceTitle.visibility = View.GONE - completedLessonDialogAbsenceValue.visibility = View.GONE + completedLessonDialogAbsence.visibility = View.GONE } - } else binding.completedLessonDialogAbsenceValue.text = it + } else binding.completedLessonDialogAbsence.text = it } completedLesson.resources.let { if (it.isBlank()) { with(binding) { completedLessonDialogResourcesTitle.visibility = View.GONE - completedLessonDialogResourcesValue.visibility = View.GONE + completedLessonDialogResources.visibility = View.GONE } - } else binding.completedLessonDialogResourcesValue.text = it + } else binding.completedLessonDialogResources.text = it } binding.completedLessonDialogClose.setOnClickListener { dismiss() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsErrorHandler.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsErrorHandler.kt index 36e38fb9..767c2f31 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsErrorHandler.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsErrorHandler.kt @@ -1,13 +1,15 @@ package io.github.wulkanowy.ui.modules.timetable.completed -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext +import android.content.res.Resources +import com.chuckerteam.chucker.api.ChuckerCollector import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException import io.github.wulkanowy.ui.base.ErrorHandler import javax.inject.Inject -class CompletedLessonsErrorHandler @Inject constructor(@ApplicationContext context: Context) : - ErrorHandler(context) { +class CompletedLessonsErrorHandler @Inject constructor( + resources: Resources, + chuckerCollector: ChuckerCollector +) : ErrorHandler(resources, chuckerCollector) { var onFeatureDisabled: () -> Unit = {} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt index 77a7bbd5..5b77fc1f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt @@ -2,8 +2,11 @@ package io.github.wulkanowy.ui.modules.timetable.completed import android.os.Bundle import android.view.View -import android.view.View.* +import android.view.View.GONE +import android.view.View.INVISIBLE +import android.view.View.VISIBLE import androidx.recyclerview.widget.LinearLayoutManager +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.CompletedLesson @@ -12,7 +15,9 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.widgets.DividerItemDecoration -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.SchooldaysRangeLimiter +import io.github.wulkanowy.utils.dpToPx +import io.github.wulkanowy.utils.getCompatDrawable import java.time.LocalDate import javax.inject.Inject @@ -55,10 +60,6 @@ class CompletedLessonsFragment : with(binding) { completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) - completedLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) - completedLessonsSwipe.setProgressBackgroundColorSchemeColor( - requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh) - ) completedLessonErrorRetry.setOnClickListener { presenter.onRetry() } completedLessonErrorDetails.setOnClickListener { presenter.onDetailsClick() } @@ -66,7 +67,7 @@ class CompletedLessonsFragment : completedLessonsNavDate.setOnClickListener { presenter.onPickDate() } completedLessonsNextButton.setOnClickListener { presenter.onNextDay() } - completedLessonsNavContainer.elevation = requireContext().dpToPx(3f) + completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f)) } } @@ -88,8 +89,8 @@ class CompletedLessonsFragment : binding.completedLessonsNavDate.text = date } - override fun showRefresh(show: Boolean) { - binding.completedLessonsSwipe.isRefreshing = show + override fun hideRefresh() { + binding.completedLessonsSwipe.isRefreshing = false } override fun showEmpty(show: Boolean) { @@ -132,24 +133,22 @@ class CompletedLessonsFragment : } override fun showCompletedLessonDialog(completedLesson: CompletedLesson) { - (activity as? MainActivity)?.showDialogFragment( - CompletedLessonDialog.newInstance( - completedLesson - ) - ) + (activity as? MainActivity)?.showDialogFragment(CompletedLessonDialog.newInstance(completedLesson)) } - override fun showDatePickerDialog(selectedDate: LocalDate) { - val now = LocalDate.now() + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) - openMaterialDatePicker( - selected = selectedDate, - rangeStart = now.firstSchoolDayInSchoolYear, - rangeEnd = now.lastSchoolDayInSchoolYear, - onDateSelected = { - presenter.onDateSet(it.year, it.monthValue, it.dayOfMonth) - } - ) + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@CompletedLessonsFragment.parentFragmentManager, null) + } } override fun onSaveInstanceState(outState: Bundle) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt index 16c51fd2..e5551ed5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt @@ -1,13 +1,21 @@ package io.github.wulkanowy.ui.modules.timetable.completed import android.annotation.SuppressLint -import io.github.wulkanowy.data.* +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.CompletedLesson -import io.github.wulkanowy.data.repositories.CompletedLessonsRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter -import io.github.wulkanowy.utils.* +import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.afterLoading +import io.github.wulkanowy.utils.flowWithResourceIn +import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday +import io.github.wulkanowy.utils.isHolidays +import io.github.wulkanowy.utils.nextOrSameSchoolDay +import io.github.wulkanowy.utils.nextSchoolDay +import io.github.wulkanowy.utils.previousSchoolDay +import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach @@ -42,19 +50,19 @@ class CompletedLessonsPresenter @Inject constructor( this.view?.showEmpty(true) Timber.i("Completed lessons feature disabled by school") } - reloadView(ofEpochDay(date ?: baseDate.toEpochDay())) - loadData() + loadData(ofEpochDay(date ?: baseDate.toEpochDay())) if (currentDate.isHolidays) setBaseDateOnHolidays() + reloadView() } fun onPreviousDay() { - reloadView(currentDate.previousSchoolDay) - loadData() + loadData(currentDate.previousSchoolDay) + reloadView() } fun onNextDay() { - reloadView(currentDate.nextSchoolDay) - loadData() + loadData(currentDate.nextSchoolDay) + reloadView() } fun onPickDate() { @@ -62,13 +70,13 @@ class CompletedLessonsPresenter @Inject constructor( } fun onDateSet(year: Int, month: Int, day: Int) { - reloadView(LocalDate.of(year, month, day)) - loadData() + loadData(LocalDate.of(year, month, day)) + reloadView() } fun onSwipeRefresh() { Timber.i("Force refreshing the completed lessons") - loadData(true) + loadData(currentDate, true) } fun onRetry() { @@ -76,7 +84,7 @@ class CompletedLessonsPresenter @Inject constructor( showErrorView(false) showProgress(true) } - loadData(true) + loadData(currentDate, true) } fun onDetailsClick() { @@ -101,47 +109,42 @@ class CompletedLessonsPresenter @Inject constructor( }.launch("holidays") } - private fun loadData(forceRefresh: Boolean = false) { - flatResourceFlow { + private fun loadData(date: LocalDate, forceRefresh: Boolean = false) { + currentDate = date + + flowWithResourceIn { val student = studentRepository.getCurrentStudent() val semester = semesterRepository.getCurrentSemester(student) - completedLessonsRepository.getCompletedLessons( - student = student, - semester = semester, - start = currentDate, - end = currentDate, - forceRefresh = forceRefresh - ) - } - .logResourceStatus("load completed lessons") - .mapResourceData { it.sortedBy { lesson -> lesson.number } } - .onResourceData { - view?.run { - enableSwipe(true) - showProgress(false) - showErrorView(false) - showContent(it.isNotEmpty()) - showEmpty(it.isEmpty()) - updateData(it) + completedLessonsRepository.getCompletedLessons(student, semester, date, date, forceRefresh) + }.onEach { + when (it.status) { + Status.LOADING -> Timber.i("Loading completed lessons data started") + Status.SUCCESS -> { + Timber.i("Loading completed lessons lessons result: Success") + view?.apply { + updateData(it.data!!.sortedBy { item -> item.number }) + showEmpty(it.data.isEmpty()) + showErrorView(false) + showContent(it.data.isNotEmpty()) + } + analytics.logEvent( + "load_data", + "type" to "completed_lessons", + "items" to it.data!!.size + ) + } + Status.ERROR -> { + Timber.i("Loading completed lessons result: An exception occurred") + completedLessonsErrorHandler.dispatch(it.error!!) } } - .onResourceIntermediate { view?.showRefresh(true) } - .onResourceSuccess { - analytics.logEvent( - "load_data", - "type" to "completed_lessons", - "items" to it.size - ) + }.afterLoading { + view?.run { + hideRefresh() + showProgress(false) + enableSwipe(true) } - .onResourceNotLoading { - view?.run { - enableSwipe(true) - showProgress(false) - showRefresh(false) - } - } - .onResourceError(errorHandler::dispatch) - .launch() + }.launch() } private fun showErrorViewOnError(message: String, error: Throwable) { @@ -155,9 +158,7 @@ class CompletedLessonsPresenter @Inject constructor( } } - private fun reloadView(date: LocalDate) { - currentDate = date - + private fun reloadView() { Timber.i("Reload completed lessons view with the date ${currentDate.toFormattedString()}") view?.apply { showProgress(true) @@ -175,7 +176,7 @@ class CompletedLessonsPresenter @Inject constructor( view?.apply { showPreButton(!currentDate.minusDays(1).isHolidays) showNextButton(!currentDate.plusDays(1).isHolidays) - updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalise()) + updateNavigationDay(currentDate.toFormattedString("EEEE, dd.MM").capitalize()) } } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt index 715ce01f..7e92cc63 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt @@ -16,7 +16,7 @@ interface CompletedLessonsView : BaseView { fun updateNavigationDay(date: String) - fun showRefresh(show: Boolean) + fun hideRefresh() fun showEmpty(show: Boolean) @@ -38,5 +38,5 @@ interface CompletedLessonsView : BaseView { fun showCompletedLessonDialog(completedLesson: CompletedLesson) - fun showDatePickerDialog(selectedDate: LocalDate) + fun showDatePickerDialog(currentDate: LocalDate) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt index 672dbe72..23d1f27a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt @@ -1,18 +1,22 @@ package io.github.wulkanowy.ui.modules.timetablewidget -import android.appwidget.AppWidgetManager.* +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.content.Intent +import android.os.Build import android.os.Bundle import android.widget.Toast import android.widget.Toast.LENGTH_LONG +import androidx.appcompat.app.AlertDialog import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint -import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.databinding.ActivityWidgetConfigureBinding import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.base.WidgetConfigureAdapter import io.github.wulkanowy.ui.modules.login.LoginActivity -import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.EXTRA_FROM_CONFIGURE import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.EXTRA_FROM_PROVIDER import io.github.wulkanowy.utils.AppInfo import javax.inject.Inject @@ -31,19 +35,15 @@ class TimetableWidgetConfigureActivity : @Inject lateinit var appInfo: AppInfo - override fun onCreate(savedInstanceState: Bundle?) { + private var dialog: AlertDialog? = null + + override public fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setResult(RESULT_CANCELED) - setContentView( - ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root - ) + setContentView(ActivityWidgetConfigureBinding.inflate(layoutInflater).apply { binding = this }.root) intent.extras.let { - presenter.onAttachView( - this, - it?.getInt(EXTRA_APPWIDGET_ID), - it?.getBoolean(EXTRA_FROM_PROVIDER) - ) + presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID), it?.getBoolean(EXTRA_FROM_PROVIDER)) } } @@ -56,9 +56,24 @@ class TimetableWidgetConfigureActivity : configureAdapter.onClickListener = presenter::onItemSelect } - override fun updateData(data: List, selectedStudentId: Long) { + override fun showThemeDialog() { + var items = arrayOf( + getString(R.string.widget_timetable_theme_light), + getString(R.string.widget_timetable_theme_dark) + ) + if (appInfo.systemVersion >= Build.VERSION_CODES.Q) items += getString(R.string.widget_timetable_theme_system) + + dialog = AlertDialog.Builder(this, R.style.WulkanowyTheme_WidgetAccountSwitcher) + .setTitle(R.string.widget_timetable_theme_title) + .setOnDismissListener { presenter.onDismissThemeView() } + .setSingleChoiceItems(items, -1) { _, which -> + presenter.onThemeSelect(which) + } + .show() + } + + override fun updateData(data: List>) { with(configureAdapter) { - selectedId = selectedStudentId items = data notifyDataSetChanged() } @@ -69,7 +84,6 @@ class TimetableWidgetConfigureActivity : .apply { action = ACTION_APPWIDGET_UPDATE putExtra(EXTRA_APPWIDGET_IDS, intArrayOf(widgetId)) - putExtra(EXTRA_FROM_CONFIGURE, true) }) } @@ -88,4 +102,9 @@ class TimetableWidgetConfigureActivity : override fun openLoginView() { startActivity(LoginActivity.getStartIntent(this)) } + + override fun onDestroy() { + super.onDestroy() + dialog?.dismiss() + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt index 87e89336..2274ecb9 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt @@ -1,13 +1,14 @@ package io.github.wulkanowy.ui.modules.timetablewidget -import io.github.wulkanowy.data.Resource +import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.resourceFlow +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getThemeWidgetKey +import io.github.wulkanowy.utils.flowWithResource import kotlinx.coroutines.flow.onEach import timber.log.Timber import javax.inject.Inject @@ -24,11 +25,7 @@ class TimetableWidgetConfigurePresenter @Inject constructor( private var selectedStudent: Student? = null - fun onAttachView( - view: TimetableWidgetConfigureView, - appWidgetId: Int?, - isFromProvider: Boolean? - ) { + fun onAttachView(view: TimetableWidgetConfigureView, appWidgetId: Int?, isFromProvider: Boolean?) { super.onAttachView(view) this.appWidgetId = appWidgetId this.isFromProvider = isFromProvider ?: false @@ -38,24 +35,40 @@ class TimetableWidgetConfigurePresenter @Inject constructor( fun onItemSelect(student: Student) { selectedStudent = student + + if (isFromProvider) registerStudent(selectedStudent) + else view?.showThemeDialog() + } + + fun onThemeSelect(index: Int) { + appWidgetId?.let { + sharedPref.putLong(getThemeWidgetKey(it), index.toLong()) + } registerStudent(selectedStudent) } + fun onDismissThemeView() { + view?.finishView() + } + private fun loadData() { - resourceFlow { studentRepository.getSavedStudents(false) }.onEach { - when (it) { - is Resource.Loading -> Timber.d("Timetable widget configure students data load") - is Resource.Success -> { - val selectedStudentId = appWidgetId?.let { id -> - sharedPref.getLong(getStudentWidgetKey(id), 0) - } ?: -1 + flowWithResource { studentRepository.getSavedStudents(false) }.onEach { + when (it.status) { + Status.LOADING -> Timber.d("Timetable widget configure students data load") + Status.SUCCESS -> { + val widgetId = appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) } when { - it.data.isEmpty() -> view?.openLoginView() - it.data.size == 1 && !isFromProvider -> onItemSelect(it.data.single().student) - else -> view?.updateData(it.data, selectedStudentId) + it.data!!.isEmpty() -> view?.openLoginView() + it.data.size == 1 && !isFromProvider -> { + selectedStudent = it.data.single().student + view?.showThemeDialog() + } + else -> view?.updateData(it.data.map { entity -> + entity.student to (entity.student.id == widgetId) + }) } } - is Resource.Error -> errorHandler.dispatch(it.error) + Status.ERROR -> errorHandler.dispatch(it.error!!) } }.launch() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt index 7740b9bb..056225ab 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt @@ -1,16 +1,18 @@ package io.github.wulkanowy.ui.modules.timetablewidget -import io.github.wulkanowy.data.db.entities.StudentWithSemesters +import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseView interface TimetableWidgetConfigureView : BaseView { fun initView() - fun updateData(data: List, selectedStudentId: Long) + fun updateData(data: List>) fun updateTimetableWidget(widgetId: Int) + fun showThemeDialog() + fun setSuccessResult(widgetId: Int) fun finishView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt index e60d5488..c7b4d4a8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt @@ -1,62 +1,60 @@ package io.github.wulkanowy.ui.modules.timetablewidget +import android.annotation.SuppressLint import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID import android.content.Context import android.content.Intent -import android.content.res.Configuration import android.graphics.Paint.ANTI_ALIAS_FLAG import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG import android.view.View.GONE import android.view.View.VISIBLE +import android.widget.AdapterView.INVALID_POSITION import android.widget.RemoteViews import android.widget.RemoteViewsService import io.github.wulkanowy.R -import io.github.wulkanowy.data.dataOrThrow import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Timetable -import io.github.wulkanowy.data.enums.TimetableGapsMode.BETWEEN_AND_BEFORE_LESSONS -import io.github.wulkanowy.data.enums.TimetableGapsMode.NO_GAPS -import io.github.wulkanowy.data.repositories.PreferencesRepository -import io.github.wulkanowy.data.repositories.SemesterRepository -import io.github.wulkanowy.data.repositories.StudentRepository -import io.github.wulkanowy.data.repositories.TimetableRepository -import io.github.wulkanowy.data.toFirstResult +import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.data.repositories.timetable.TimetableRepository +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getCurrentThemeWidgetKey import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey -import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getTodayLastLessonEndDateTimeWidgetKey import io.github.wulkanowy.utils.getCompatColor -import io.github.wulkanowy.utils.getErrorString -import io.github.wulkanowy.utils.getPlural +import io.github.wulkanowy.utils.toFirstResult import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.runBlocking import timber.log.Timber -import java.time.Instant import java.time.LocalDate class TimetableWidgetFactory( private val timetableRepository: TimetableRepository, private val studentRepository: StudentRepository, private val semesterRepository: SemesterRepository, - private val sharedPref: SharedPrefProvider, private val prefRepository: PreferencesRepository, + private val sharedPref: SharedPrefProvider, private val context: Context, private val intent: Intent? ) : RemoteViewsService.RemoteViewsFactory { - private var items = emptyList() - private var timetableCanceledColor: Int? = null + private var lessons = emptyList() + + private var savedCurrentTheme: Long? = null + + private var primaryColor: Int? = null + private var textColor: Int? = null + private var timetableChangeColor: Int? = null override fun getLoadingView() = null override fun hasStableIds() = true - override fun getCount() = items.size + override fun getCount() = lessons.size - override fun getViewTypeCount() = 3 + override fun getViewTypeCount() = 2 override fun getItemId(position: Int) = position.toLong() @@ -65,267 +63,156 @@ class TimetableWidgetFactory( override fun onDestroy() {} override fun onDataSetChanged() { - val appWidgetId = intent?.extras?.getInt(EXTRA_APPWIDGET_ID) ?: return - val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0)) - val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0) + intent?.extras?.getInt(EXTRA_APPWIDGET_ID)?.let { appWidgetId -> + val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0)) + val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0) - items = emptyList() + updateTheme(appWidgetId) + lessons = getLessons(date, studentId) + } + } + private fun updateTheme(appWidgetId: Int) { + savedCurrentTheme = sharedPref.getLong(getCurrentThemeWidgetKey(appWidgetId), 0) + + if (savedCurrentTheme == 0L) { + primaryColor = R.color.colorPrimary + textColor = android.R.color.black + timetableChangeColor = R.color.timetable_change_dark + } else { + primaryColor = R.color.colorPrimaryLight + textColor = android.R.color.white + timetableChangeColor = R.color.timetable_change_light + } + } + + private fun getItemLayout(lesson: Timetable): Int { + return when { + prefRepository.showWholeClassPlan == "small" && !lesson.isStudentPlan -> { + if (savedCurrentTheme == 0L) R.layout.item_widget_timetable_small + else R.layout.item_widget_timetable_small_dark + } + savedCurrentTheme == 1L -> R.layout.item_widget_timetable_dark + else -> R.layout.item_widget_timetable + } + } + + private fun getLessons(date: LocalDate, studentId: Long) = try { runBlocking { - runCatching { - val student = getStudent(studentId) ?: return@runBlocking - val semester = semesterRepository.getCurrentSemester(student) - val lessons = getLessons(student, semester, date) - val lastSync = timetableRepository.getLastRefreshTimestamp(semester, date, date) + if (!studentRepository.isStudentSaved()) return@runBlocking emptyList() - createItems(lessons, lastSync, !(student.isEduOne ?: false)) - } - .onFailure { - items = listOf(TimetableWidgetItem.Error(it)) - Timber.e(it, "An error has occurred in timetable widget factory") - } - .onSuccess { - items = it - if (date == LocalDate.now()) { - updateTodayLastLessonEnd(appWidgetId) - } - } + val students = studentRepository.getSavedStudents() + val student = students.singleOrNull { it.student.id == studentId }?.student + ?: return@runBlocking emptyList() + + val semester = semesterRepository.getCurrentSemester(student) + timetableRepository.getTimetable(student, semester, date, date, false) + .toFirstResult().data.orEmpty() + .sortedWith(compareBy({ it.number }, { !it.isStudentPlan })) + .filter { if (prefRepository.showWholeClassPlan == "no") it.isStudentPlan else true } } + } catch (e: Exception) { + Timber.e(e, "An error has occurred in timetable widget factory") + emptyList() } - private suspend fun getStudent(studentId: Long): Student? { - val students = studentRepository.getSavedStudents() - return students.singleOrNull { it.student.id == studentId }?.student - } - - private suspend fun getLessons( - student: Student, semester: Semester, date: LocalDate - ): List { - val timetable = timetableRepository.getTimetable( - student = student, - semester = semester, - start = date, - end = date, - forceRefresh = false, - isFromAppWidget = true - ) - val lessons = timetable.toFirstResult().dataOrThrow.lessons - return lessons.sortedBy { it.start } - } - - private fun createItems( - lessons: List, - lastSync: Instant?, - isEduOne: Boolean - ): List { - var prevNum = when (prefRepository.showTimetableGaps) { - BETWEEN_AND_BEFORE_LESSONS -> 0 - else -> null - } - - return buildList { - lessons.forEach { - if (prefRepository.showTimetableGaps != NO_GAPS && prevNum != null && it.number > prevNum!! + 1) { - val emptyItem = TimetableWidgetItem.Empty( - numFrom = prevNum!! + 1, - numTo = it.number - 1 - ) - add(emptyItem) - } - add(TimetableWidgetItem.Normal(it, isEduOne)) - prevNum = it.number - } - add(TimetableWidgetItem.Synchronized(lastSync ?: Instant.MIN)) - } - } - - private fun updateTodayLastLessonEnd(appWidgetId: Int) { - val todayLastLessonEnd = items.filterIsInstance() - .maxOfOrNull { it.lesson.end } ?: return - val key = getTodayLastLessonEndDateTimeWidgetKey(appWidgetId) - sharedPref.putLong(key, todayLastLessonEnd.epochSecond, true) - } - + @SuppressLint("DefaultLocale") override fun getViewAt(position: Int): RemoteViews? { - return when (val item = items.getOrNull(position) ?: return null) { - is TimetableWidgetItem.Normal -> getNormalItemRemoteView(item) - is TimetableWidgetItem.Empty -> getEmptyItemRemoteView(item) - is TimetableWidgetItem.Synchronized -> getSynchronizedItemRemoteView(item) - is TimetableWidgetItem.Error -> getErrorItemRemoteView(item) - } - } + if (position == INVALID_POSITION || lessons.getOrNull(position) == null) return null - private fun getNormalItemRemoteView(item: TimetableWidgetItem.Normal): RemoteViews { - val lesson = item.lesson - - val lessonStartTime = lesson.start.toFormattedString(TIME_FORMAT_STYLE) - val lessonEndTime = lesson.end.toFormattedString(TIME_FORMAT_STYLE) - val lessonNumberVisibility = if (item.isLessonNumberVisible) VISIBLE else GONE - - val remoteViews = RemoteViews(context.packageName, R.layout.item_widget_timetable).apply { - setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString()) - setViewVisibility(R.id.timetableWidgetItemNumber, lessonNumberVisibility) - setTextViewText(R.id.timetableWidgetItemTimeStart, lessonStartTime) - setTextViewText(R.id.timetableWidgetItemTimeFinish, lessonEndTime) + val lesson = lessons[position] + return RemoteViews(context.packageName, getItemLayout(lesson)).apply { setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject) + setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString()) + setTextViewText(R.id.timetableWidgetItemTimeStart, lesson.start.toFormattedString("HH:mm")) + setTextViewText(R.id.timetableWidgetItemTimeFinish, lesson.end.toFormattedString("HH:mm")) + + updateDescription(this, lesson) + + if (lesson.canceled) { + updateStylesCanceled(this) + } else { + updateStylesNotCanceled(this, lesson) + } - setTextViewText(R.id.timetableWidgetItemTeacher, lesson.teacher) - setTextViewText(R.id.timetableWidgetItemDescription, lesson.info) setOnClickFillInIntent(R.id.timetableWidgetItemContainer, Intent()) } - updateTheme() - clearLessonStyles(remoteViews) - if (lesson.room.isBlank()) { - remoteViews.setViewVisibility(R.id.timetableWidgetItemRoom, GONE) - } else { - remoteViews.setTextViewText(R.id.timetableWidgetItemRoom, lesson.room) - } - when { - lesson.canceled -> applyCancelledLessonStyles(remoteViews) - lesson.changes or lesson.info.isNotBlank() -> applyChangedLessonStyles( - remoteViews = remoteViews, - lesson = lesson, - ) - } - return remoteViews } - private fun getEmptyItemRemoteView(item: TimetableWidgetItem.Empty): RemoteViews { - return RemoteViews( - context.packageName, - R.layout.item_widget_timetable_empty - ).apply { - setTextViewText( - R.id.timetableWidgetEmptyItemNumber, - when (item.numFrom) { - item.numTo -> item.numFrom.toString() - else -> "${item.numFrom}-${item.numTo}" - } - ) - setTextViewText( - R.id.timetableWidgetEmptyItemText, - context.getPlural( - R.plurals.timetable_no_lesson, - item.numTo - item.numFrom + 1 - ) - ) - setOnClickFillInIntent(R.id.timetableWidgetEmptyItemContainer, Intent()) - } - } - - private fun getSynchronizedItemRemoteView(item: TimetableWidgetItem.Synchronized): RemoteViews { - return RemoteViews( - context.packageName, - R.layout.item_widget_timetable_footer - ).apply { - setTextViewText( - R.id.timetableWidgetSynchronizationTime, - getSynchronizationInfoText(item.timestamp) - ) - } - } - - private fun getErrorItemRemoteView(item: TimetableWidgetItem.Error): RemoteViews { - return RemoteViews( - context.packageName, - R.layout.item_widget_timetable_error - ).apply { - setTextViewText( - R.id.timetable_widget_item_error_message, - context.resources.getErrorString(item.error) - ) - } - } - - private fun updateTheme() { - when (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { - Configuration.UI_MODE_NIGHT_YES -> { - textColor = android.R.color.white - timetableChangeColor = R.color.timetable_change_dark - timetableCanceledColor = R.color.timetable_canceled_dark - } - - else -> { - textColor = android.R.color.black - timetableChangeColor = R.color.timetable_change_light - timetableCanceledColor = R.color.timetable_canceled_light + private fun updateDescription(remoteViews: RemoteViews, lesson: Timetable) { + with(remoteViews) { + if (lesson.info.isNotBlank() && !lesson.changes) { + setTextViewText(R.id.timetableWidgetItemDescription, lesson.info) + setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) + setViewVisibility(R.id.timetableWidgetItemRoom, GONE) + setViewVisibility(R.id.timetableWidgetItemTeacher, GONE) + } else { + setViewVisibility(R.id.timetableWidgetItemDescription, GONE) + setViewVisibility(R.id.timetableWidgetItemRoom, VISIBLE) + setViewVisibility(R.id.timetableWidgetItemTeacher, VISIBLE) } } } - private fun clearLessonStyles(remoteViews: RemoteViews) { - val defaultTextColor = context.getCompatColor(textColor ?: 0) + private fun updateStylesCanceled(remoteViews: RemoteViews) { + with(remoteViews) { + setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", + STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG) + setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor(primaryColor!!)) + setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(primaryColor!!)) + setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(primaryColor!!)) + } + } - remoteViews.apply { + private fun updateStylesNotCanceled(remoteViews: RemoteViews, lesson: Timetable) { + with(remoteViews) { setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG) - setViewVisibility(R.id.timetableWidgetItemRoom, VISIBLE) - setViewVisibility(R.id.timetableWidgetItemTeacher, VISIBLE) - setViewVisibility(R.id.timetableWidgetItemIcon, GONE) - setViewVisibility(R.id.timetableWidgetItemDescription, GONE) - setTextColor(R.id.timetableWidgetItemNumber, defaultTextColor) - setTextColor(R.id.timetableWidgetItemSubject, defaultTextColor) - setTextColor(R.id.timetableWidgetItemRoom, defaultTextColor) - setTextColor(R.id.timetableWidgetItemTeacher, defaultTextColor) - setTextColor(R.id.timetableWidgetItemDescription, defaultTextColor) + setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(textColor!!)) + setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(timetableChangeColor!!)) + + updateNotCanceledLessonNumberColor(this, lesson) + updateNotCanceledSubjectColor(this, lesson) + + val teacherChange = lesson.teacherOld.isNotBlank() && lesson.teacher != lesson.teacherOld + updateNotCanceledRoom(this, lesson, teacherChange) + updateNotCanceledTeacher(this, lesson, teacherChange) } } - private fun applyCancelledLessonStyles(remoteViews: RemoteViews) { - val cancelledThemeColor = context.getCompatColor(timetableCanceledColor ?: 0) - val strikeThroughPaintFlags = STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG + private fun updateNotCanceledLessonNumberColor(remoteViews: RemoteViews, lesson: Timetable) { + remoteViews.setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor( + if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!! + else textColor!! + )) + } - remoteViews.apply { - setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", strikeThroughPaintFlags) - setTextColor(R.id.timetableWidgetItemNumber, cancelledThemeColor) - setTextColor(R.id.timetableWidgetItemSubject, cancelledThemeColor) - setTextColor(R.id.timetableWidgetItemDescription, cancelledThemeColor) - setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) - setViewVisibility(R.id.timetableWidgetItemRoom, GONE) - setViewVisibility(R.id.timetableWidgetItemTeacher, GONE) + private fun updateNotCanceledSubjectColor(remoteViews: RemoteViews, lesson: Timetable) { + remoteViews.setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor( + if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!! + else textColor!! + )) + } + + private fun updateNotCanceledRoom(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) { + with(remoteViews) { + if (lesson.room.isNotBlank()) { + setTextViewText(R.id.timetableWidgetItemRoom, + if (teacherChange) lesson.room + else "${context.getString(R.string.timetable_room)} ${lesson.room}" + ) + + setTextColor(R.id.timetableWidgetItemRoom, context.getCompatColor( + if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!! + else textColor!! + )) + } else setTextViewText(R.id.timetableWidgetItemRoom, "") } } - private fun applyChangedLessonStyles(remoteViews: RemoteViews, lesson: Timetable) { - val changesTextColor = context.getCompatColor(timetableChangeColor ?: 0) - - remoteViews.apply { - setTextColor(R.id.timetableWidgetItemNumber, changesTextColor) - setTextColor(R.id.timetableWidgetItemDescription, changesTextColor) - setViewVisibility(R.id.timetableWidgetItemIcon, VISIBLE) - setImageViewResource(R.id.timetableWidgetItemIcon, R.drawable.ic_timetable_widget_swap) - } - - if (lesson.subject != lesson.subjectOld) { - remoteViews.setTextColor(R.id.timetableWidgetItemSubject, changesTextColor) - } - - if (lesson.room != lesson.roomOld) { - remoteViews.setTextColor(R.id.timetableWidgetItemRoom, changesTextColor) - } - - if (lesson.teacher != lesson.teacherOld) { - remoteViews.setTextColor(R.id.timetableWidgetItemTeacher, changesTextColor) - } - - if (lesson.info.isNotBlank() && !lesson.changes) { - remoteViews.setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE) - remoteViews.setViewVisibility(R.id.timetableWidgetItemRoom, GONE) - remoteViews.setViewVisibility(R.id.timetableWidgetItemTeacher, GONE) - } - } - - private fun getSynchronizationInfoText(synchronizationInstant: Instant) = - synchronizationInstant.run { - val synchronizationTime = toFormattedString(TIME_FORMAT_STYLE) - val synchronizationDate = toFormattedString() - context.getString( - R.string.widget_timetable_last_synchronization, - synchronizationDate, - synchronizationTime, - ) - } - - private companion object { - private const val TIME_FORMAT_STYLE = "HH:mm" + private fun updateNotCanceledTeacher(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) { + remoteViews.setTextViewText(R.id.timetableWidgetItemTeacher, + if (teacherChange) lesson.teacher + else "" + ) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetItem.kt deleted file mode 100644 index d4c2cfc0..00000000 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetItem.kt +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.wulkanowy.ui.modules.timetablewidget - -import io.github.wulkanowy.data.db.entities.Timetable -import java.time.Instant - -sealed class TimetableWidgetItem(val type: TimetableWidgetItemType) { - - data class Normal( - val lesson: Timetable, - val isLessonNumberVisible: Boolean, - ) : TimetableWidgetItem(TimetableWidgetItemType.NORMAL) - - data class Empty( - val numFrom: Int, - val numTo: Int - ) : TimetableWidgetItem(TimetableWidgetItemType.EMPTY) - - data class Synchronized( - val timestamp: Instant, - ) : TimetableWidgetItem(TimetableWidgetItemType.SYNCHRONIZED) - - data class Error( - val error: Throwable - ) : TimetableWidgetItem(TimetableWidgetItemType.ERROR) -} - -enum class TimetableWidgetItemType { - NORMAL, - EMPTY, - SYNCHRONIZED, - ERROR, -} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt index cc48539a..18e0ea56 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt @@ -1,39 +1,43 @@ package io.github.wulkanowy.ui.modules.timetablewidget +import android.annotation.SuppressLint import android.app.PendingIntent +import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.appwidget.AppWidgetManager -import android.appwidget.AppWidgetManager.* -import android.content.BroadcastReceiver +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.content.Context import android.content.Intent import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK -import android.graphics.Bitmap +import android.content.res.Configuration import android.widget.RemoteViews -import androidx.appcompat.content.res.AppCompatResources -import androidx.core.graphics.drawable.DrawableCompat -import androidx.core.graphics.drawable.toBitmap import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.exceptions.NoCurrentStudentException -import io.github.wulkanowy.data.repositories.StudentRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.services.HiltBroadcastReceiver import io.github.wulkanowy.services.widgets.TimetableWidgetService -import io.github.wulkanowy.ui.modules.Destination -import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.utils.* -import kotlinx.coroutines.DelicateCoroutinesApi +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.AnalyticsHelper +import io.github.wulkanowy.utils.nextOrSameSchoolDay +import io.github.wulkanowy.utils.nextSchoolDay +import io.github.wulkanowy.utils.previousSchoolDay +import io.github.wulkanowy.utils.toFormattedString import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import timber.log.Timber import java.time.LocalDate -import java.time.LocalDateTime -import java.time.ZoneOffset +import java.time.LocalDate.now import javax.inject.Inject @AndroidEntryPoint -class TimetableWidgetProvider : BroadcastReceiver() { +class TimetableWidgetProvider : HiltBroadcastReceiver() { @Inject lateinit var appWidgetManager: AppWidgetManager @@ -49,8 +53,6 @@ class TimetableWidgetProvider : BroadcastReceiver() { companion object { - private const val TIMETABLE_PENDING_INTENT_ID = 201 - private const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget" private const val EXTRA_BUTTON_TYPE = "extraButtonType" @@ -61,190 +63,129 @@ class TimetableWidgetProvider : BroadcastReceiver() { private const val BUTTON_RESET = "buttonReset" - const val EXTRA_FROM_CONFIGURE = "extraFromConfigure" - const val EXTRA_FROM_PROVIDER = "extraFromProvider" fun getDateWidgetKey(appWidgetId: Int) = "timetable_widget_date_$appWidgetId" - fun getTodayLastLessonEndDateTimeWidgetKey(appWidgetId: Int) = - "timetable_widget_today_last_lesson_end_date_time_$appWidgetId" - fun getStudentWidgetKey(appWidgetId: Int) = "timetable_widget_student_$appWidgetId" + + fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId" + + fun getCurrentThemeWidgetKey(appWidgetId: Int) = "timetable_widget_current_theme_$appWidgetId" } - @OptIn(DelicateCoroutinesApi::class) override fun onReceive(context: Context, intent: Intent) { + super.onReceive(context, intent) GlobalScope.launch { when (intent.action) { - ACTION_APPWIDGET_UPDATE -> onWidgetUpdate(context, intent) - ACTION_APPWIDGET_DELETED -> onWidgetDeleted(intent) + ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent) + ACTION_APPWIDGET_DELETED -> onDelete(intent) } } } - private suspend fun onWidgetUpdate(context: Context, intent: Intent) { - val pressedButton = intent.getPressedButton() - - if (pressedButton == null) { - val updatedWidgetIds = intent.getWidgetIds() ?: return - updatedWidgetIds.forEach { updateWidgetLayout(context, it) } + private suspend fun onUpdate(context: Context, intent: Intent) { + if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) { + intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId -> + val student = getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId) + updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student) + } } else { - val widgetId = intent.getToggledWidgetId() ?: return - reportChangedDay(pressedButton) - updateSavedWidgetDate(widgetId, pressedButton) - updateWidgetLayout(context, widgetId) + val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE) + val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0) + val student = getStudent(sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0), toggledWidgetId) + val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0)) + val date = when (buttonType) { + BUTTON_RESET -> now().nextOrSameSchoolDay + BUTTON_NEXT -> savedDate.nextSchoolDay + BUTTON_PREV -> savedDate.previousSchoolDay + else -> now().nextOrSameSchoolDay + } + if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType) + updateWidget(context, toggledWidgetId, date, student) } } - private fun Intent.getPressedButton(): String? { - return getStringExtra(EXTRA_BUTTON_TYPE) - } + private fun onDelete(intent: Intent) { + val appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID, 0) - private fun Intent.getWidgetIds(): IntArray? { - return getIntArrayExtra(EXTRA_APPWIDGET_IDS) - } - - private fun Intent.getToggledWidgetId(): Int? { - val toggledWidgetId = getIntExtra(EXTRA_TOGGLED_WIDGET_ID, INVALID_APPWIDGET_ID) - return toggledWidgetId.takeIf { it != INVALID_APPWIDGET_ID } - } - - private fun reportChangedDay(buttonType: String) { - if (buttonType.isNotBlank()) { - analytics.logEvent("changed_timetable_widget_day", "button" to buttonType) + if (appWidgetId != 0) { + with(sharedPref) { + delete(getStudentWidgetKey(appWidgetId)) + delete(getDateWidgetKey(appWidgetId)) + delete(getThemeWidgetKey(appWidgetId)) + delete(getCurrentThemeWidgetKey(appWidgetId)) + } } } - private fun updateSavedWidgetDate(widgetId: Int, buttonType: String) { - val savedDate = getSavedWidgetDate(widgetId) - val newDate = savedDate?.let { getNewDate(it, widgetId, buttonType) } - ?: getWidgetDefaultDateToLoad(widgetId) - setWidgetDate(widgetId, newDate) - } + @SuppressLint("DefaultLocale") + private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) { + val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0) + val isSystemDarkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES + var currentTheme = 0L + var layoutId = R.layout.widget_timetable - private fun getSavedWidgetDate(widgetId: Int): LocalDate? { - val epochDay = sharedPref.getLong(getDateWidgetKey(widgetId), 0) - return if (epochDay == 0L) null else LocalDate.ofEpochDay(epochDay) - } - - private fun getNewDate( - currentDate: LocalDate, - widgetId: Int, - selectedButton: String - ): LocalDate { - return when (selectedButton) { - BUTTON_NEXT -> currentDate.nextSchoolDay - BUTTON_PREV -> currentDate.previousSchoolDay - else -> getWidgetDefaultDateToLoad(widgetId) + if (savedConfigureTheme == 1L || (savedConfigureTheme == 2L && isSystemDarkMode)) { + currentTheme = 1L + layoutId = R.layout.widget_timetable_dark } - } - private fun setWidgetDate(widgetId: Int, dateToSet: LocalDate) { - val widgetDateKey = getDateWidgetKey(widgetId) - sharedPref.putLong(widgetDateKey, dateToSet.toEpochDay(), true) - } + val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT) + val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV) + val resetNavIntent = createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET) + val adapterIntent = Intent(context, TimetableWidgetService::class.java) + .apply { + putExtra(EXTRA_APPWIDGET_ID, appWidgetId) + //make Intent unique + action = appWidgetId.toString() + } + val accountIntent = PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId, + Intent(context, TimetableWidgetConfigureActivity::class.java).apply { + addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) + putExtra(EXTRA_APPWIDGET_ID, appWidgetId) + putExtra(EXTRA_FROM_PROVIDER, true) + }, FLAG_UPDATE_CURRENT) + val appIntent = PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id, + MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT) - private fun getWidgetDefaultDateToLoad(widgetId: Int): LocalDate { - val lastLessonEndDateTime = getLastLessonDateTime(widgetId) - - val todayDate = LocalDate.now() - val isLastLessonToday = lastLessonEndDateTime.toLocalDate() == todayDate - val isEndOfLessons = LocalDateTime.now() > lastLessonEndDateTime - - return if (isLastLessonToday && isEndOfLessons) { - todayDate.nextSchoolDay - } else { - todayDate.nextOrSameSchoolDay - } - } - - private fun getLastLessonDateTime(widgetId: Int): LocalDateTime { - val lastLessonTimestamp = sharedPref - .getLong(getTodayLastLessonEndDateTimeWidgetKey(widgetId), 0) - return LocalDateTime.ofEpochSecond(lastLessonTimestamp, 0, ZoneOffset.UTC) - } - - private suspend fun updateWidgetLayout( - context: Context, widgetId: Int - ) { - val widgetRemoteViews = RemoteViews(context.packageName, R.layout.widget_timetable) - - // Apply the click action intent - val appIntent = createPendingAppIntent(context) - widgetRemoteViews.setPendingIntentTemplate(R.id.timetableWidgetList, appIntent) - - // Display saved date - val date = getSavedWidgetDate(widgetId) ?: getWidgetDefaultDateToLoad(widgetId) - val formattedDate = date.toFormattedString("EEE, dd.MM").capitalise() - widgetRemoteViews.setTextViewText(R.id.timetableWidgetDate, formattedDate) - - // Apply intents to the date switcher buttons - val nextNavIntent = createNavButtonIntent(context, widgetId, widgetId, BUTTON_NEXT) - val prevNavIntent = createNavButtonIntent(context, -widgetId, widgetId, BUTTON_PREV) - val resetNavIntent = - createNavButtonIntent(context, Int.MAX_VALUE - widgetId, widgetId, BUTTON_RESET) - widgetRemoteViews.run { + val remoteView = RemoteViews(context.packageName, layoutId).apply { + setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty) + setTextViewText(R.id.timetableWidgetDate, date.toFormattedString("EEEE, dd.MM").capitalize()) + setTextViewText(R.id.timetableWidgetName, student?.studentName ?: context.getString(R.string.all_no_data)) + setRemoteAdapter(R.id.timetableWidgetList, adapterIntent) setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent) setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent) setOnClickPendingIntent(R.id.timetableWidgetDate, resetNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetName, resetNavIntent) + setOnClickPendingIntent(R.id.timetableWidgetAccount, accountIntent) + setPendingIntentTemplate(R.id.timetableWidgetList, appIntent) } - // Setup the lesson list adapter - val lessonListAdapterIntent = createLessonListAdapterIntent(context, widgetId) - // --- Ensure the selected date is stored in the shared preferences, - // --- on which the TimetableWidgetFactory relies - setWidgetDate(widgetId, date) - // --- - widgetRemoteViews.apply { - setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty) - setRemoteAdapter(R.id.timetableWidgetList, lessonListAdapterIntent) + with(sharedPref) { + putLong(getCurrentThemeWidgetKey(appWidgetId), currentTheme) + putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true) } - // Setup profile picture - getWidgetStudent(widgetId)?.let { student -> - setupAccountView(context, student, widgetRemoteViews, widgetId) - } - - // Apply updates with(appWidgetManager) { - partiallyUpdateAppWidget(widgetId, widgetRemoteViews) - notifyAppWidgetViewDataChanged(widgetId, R.id.timetableWidgetList) + updateAppWidget(appWidgetId, remoteView) + notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList) + Timber.d("TimetableWidgetProvider updated") } - - Timber.d("TimetableWidgetProvider updated") } - private fun createPendingAppIntent(context: Context) = PendingIntent.getActivity( - context, TIMETABLE_PENDING_INTENT_ID, - SplashActivity.getStartIntent(context, Destination.Timetable()), - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - - private fun createNavButtonIntent( - context: Context, code: Int, appWidgetId: Int, buttonType: String - ) = PendingIntent.getBroadcast( - context, code, Intent(context, TimetableWidgetProvider::class.java).apply { - action = ACTION_APPWIDGET_UPDATE - putExtra(EXTRA_BUTTON_TYPE, buttonType) - putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId) - }, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - - private fun createLessonListAdapterIntent(context: Context, widgetId: Int) = - Intent(context, TimetableWidgetService::class.java).apply { - putExtra(EXTRA_APPWIDGET_ID, widgetId) - action = widgetId.toString() //make Intent unique - } - - private suspend fun getWidgetStudent(widgetId: Int): Student? { - val studentId = sharedPref.getLong(getStudentWidgetKey(widgetId), 0) - return getStudent(studentId, widgetId) + private fun createNavIntent(context: Context, code: Int, appWidgetId: Int, buttonType: String): PendingIntent { + return PendingIntent.getBroadcast(context, code, + Intent(context, TimetableWidgetProvider::class.java).apply { + action = ACTION_APPWIDGET_UPDATE + putExtra(EXTRA_BUTTON_TYPE, buttonType) + putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId) + }, FLAG_UPDATE_CURRENT) } private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try { val students = studentRepository.getSavedStudents(false) - val student = students.singleOrNull { it.student.id == studentId }?.student + val student = students.singleOrNull { it -> it.student.id == studentId }?.student when { student != null -> student studentId != 0L && studentRepository.isCurrentStudentSet() -> { @@ -252,7 +193,6 @@ class TimetableWidgetProvider : BroadcastReceiver() { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } } - else -> null } } catch (e: Exception) { @@ -261,65 +201,4 @@ class TimetableWidgetProvider : BroadcastReceiver() { } null } - - private fun setupAccountView( - context: Context, student: Student, remoteViews: RemoteViews, widgetId: Int - ) { - val accountInitials = getAccountInitials(student.nickOrName) - val accountPickerPendingIntent = createAccountPickerPendingIntent(context, widgetId) - - getAvatarBackgroundBitmap(context, student.avatarColor)?.let { - remoteViews.setImageViewBitmap(R.id.timetableWidgetAccountBackground, it) - } - - remoteViews.apply { - setTextViewText(R.id.timetableWidgetAccountInitials, accountInitials) - setOnClickPendingIntent(R.id.timetableWidgetAccount, accountPickerPendingIntent) - } - } - - private fun getAccountInitials(name: String): String { - val firstLetters = name.split(" ").mapNotNull { it.firstOrNull() } - return firstLetters.joinToString(separator = "").uppercase() - } - - private fun createAccountPickerPendingIntent(context: Context, widgetId: Int) = - PendingIntent.getActivity( - context, - -Int.MAX_VALUE + widgetId, - Intent(context, TimetableWidgetConfigureActivity::class.java).apply { - addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) - putExtra(EXTRA_APPWIDGET_ID, widgetId) - putExtra(EXTRA_FROM_PROVIDER, true) - }, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE - ) - - private fun getAvatarBackgroundBitmap(context: Context, avatarColor: Long): Bitmap? { - val avatarDrawableResource = R.drawable.background_timetable_widget_avatar - return AppCompatResources.getDrawable(context, avatarDrawableResource)?.let { drawable -> - val screenDensity = context.resources.displayMetrics.density - val avatarSize = (48 * screenDensity).toInt() - DrawableCompat.wrap(drawable).run { - DrawableCompat.setTint(this, avatarColor.toInt()) - toBitmap(avatarSize, avatarSize) - } - } - } - - private fun onWidgetDeleted(intent: Intent) { - val deletedWidgetId = intent.getWidgetId() - deleteWidgetPreferences(deletedWidgetId) - } - - private fun Intent.getWidgetId(): Int { - return getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID) - } - - private fun deleteWidgetPreferences(widgetId: Int) { - with(sharedPref) { - delete(getStudentWidgetKey(widgetId)) - delete(getDateWidgetKey(widgetId)) - } - } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/DividerItemDecoration.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/DividerItemDecoration.kt index 93330131..b0b6999e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/DividerItemDecoration.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/DividerItemDecoration.kt @@ -2,27 +2,23 @@ package io.github.wulkanowy.ui.widgets import android.content.Context import android.graphics.Canvas +import android.view.View import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView -class DividerItemDecoration( - context: Context, - private val showDividerWithFirstItem: Boolean = true -) : DividerItemDecoration(context, VERTICAL) { +class DividerItemDecoration(context: Context) : DividerItemDecoration(context, VERTICAL) { override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { canvas.save() val dividerLeft = parent.paddingLeft val dividerRight = parent.width - parent.paddingRight + val childCount = parent.childCount - for (i in 0..parent.childCount - 2) { - if (!showDividerWithFirstItem && i == 0) continue - - val child = parent.getChildAt(i) + for (i in 0..childCount - 2) { + val child: View = parent.getChildAt(i) val params = child.layoutParams as RecyclerView.LayoutParams - val dividerTop = child.bottom + params.bottomMargin + val dividerTop: Int = child.bottom + params.bottomMargin val dividerBottom = dividerTop + drawable!!.intrinsicHeight - drawable?.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) drawable?.draw(canvas) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt index 6b7fb4aa..0f121dc5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/FittedScrollableTabLayout.kt @@ -3,15 +3,17 @@ package io.github.wulkanowy.ui.widgets import android.content.Context import android.util.AttributeSet import android.view.ViewGroup -import com.google.android.material.tabs.TabLayout /** * @see Tabs don't fit to screen with tabmode=scrollable, Even with a Custom Tab Layout */ -class FittedScrollableTabLayout @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : TabLayout(context, attrs) { +class FittedScrollableTabLayout : MaterialTabLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { setMeasuredDimension(widthMeasureSpec, heightMeasureSpec) diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt index 4e1ca1a9..a04922e5 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialLinearLayout.kt @@ -1,19 +1,24 @@ package io.github.wulkanowy.ui.widgets import android.content.Context +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP import android.util.AttributeSet import android.widget.LinearLayout import androidx.core.view.ViewCompat +import com.google.android.material.elevation.ElevationOverlayProvider import com.google.android.material.shape.MaterialShapeDrawable -class MaterialLinearLayout @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null -) : LinearLayout(context, attrs) { +class MaterialLinearLayout : LinearLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attr: AttributeSet) : super(context, attr) + + constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr) init { - val drawable = - MaterialShapeDrawable.createWithElevationOverlay(context, ViewCompat.getElevation(this)) + val drawable = MaterialShapeDrawable.createWithElevationOverlay(context, ViewCompat.getElevation(this)) ViewCompat.setBackground(this, drawable) } @@ -23,4 +28,12 @@ class MaterialLinearLayout @JvmOverloads constructor( (background as MaterialShapeDrawable).elevation = elevation } } + + fun setElevationCompat(elevation: Float) { + if (SDK_INT >= LOLLIPOP) { + setElevation(elevation) + } else { + setBackgroundColor(ElevationOverlayProvider(context).compositeOverlayWithThemeSurfaceColorIfNeeded(elevation)) + } + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt new file mode 100644 index 00000000..e19d0111 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/widgets/MaterialTabLayout.kt @@ -0,0 +1,25 @@ +package io.github.wulkanowy.ui.widgets + +import android.content.Context +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP +import android.util.AttributeSet +import com.google.android.material.elevation.ElevationOverlayProvider +import com.google.android.material.tabs.TabLayout + +open class MaterialTabLayout : TabLayout { + + constructor(context: Context) : super(context) + + constructor(context: Context, attr: AttributeSet) : super(context, attr) + + constructor(context: Context, attr: AttributeSet, defStyleAttr: Int) : super(context, attr, defStyleAttr) + + fun setElevationCompat(elevation: Float) { + if (SDK_INT >= LOLLIPOP) { + setElevation(elevation) + } else { + setBackgroundColor(ElevationOverlayProvider(context).compositeOverlayWithThemeSurfaceColorIfNeeded(elevation)) + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt b/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt index e16db53c..1098a9a0 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt @@ -1,39 +1,31 @@ package io.github.wulkanowy.utils import android.content.res.Resources -import android.os.Build -import io.github.wulkanowy.BuildConfig +import android.os.Build.MANUFACTURER +import android.os.Build.MODEL +import android.os.Build.VERSION.SDK_INT +import io.github.wulkanowy.BuildConfig.DEBUG +import io.github.wulkanowy.BuildConfig.VERSION_CODE +import io.github.wulkanowy.BuildConfig.VERSION_NAME import javax.inject.Inject import javax.inject.Singleton @Singleton open class AppInfo @Inject constructor() { - open val isDebug get() = BuildConfig.DEBUG + open val isDebug get() = DEBUG - open val versionCode get() = BuildConfig.VERSION_CODE + open val versionCode get() = VERSION_CODE - open val buildTimestamp get() = BuildConfig.BUILD_TIMESTAMP + open val versionName get() = VERSION_NAME - open val buildFlavor get() = BuildConfig.FLAVOR + open val systemVersion get() = SDK_INT - open val versionName get() = BuildConfig.VERSION_NAME + open val systemManufacturer: String get() = MANUFACTURER - open val systemVersion get() = Build.VERSION.SDK_INT - - open val systemManufacturer: String get() = Build.MANUFACTURER - - open val systemModel: String get() = Build.MODEL - - open val messagesBaseUrl: String = BuildConfig.MESSAGES_BASE_URL - open val schoolsBaseUrl: String = BuildConfig.SCHOOLS_BASE_URL + open val systemModel: String get() = MODEL @Suppress("DEPRECATION") open val systemLanguage: String get() = Resources.getSystem().configuration.locale.language - - val defaultColorsForAvatar = listOf( - 0xd32f2f, 0xE64A19, 0xFFA000, 0xAFB42B, 0x689F38, 0x388E3C, 0x00796B, 0x0097A7, - 0x1976D2, 0x3647b5, 0x6236c9, 0x9225c1, 0xC2185B, 0x616161, 0x455A64, 0x7a5348 - ).map { (it and 0x00ffffff or (255 shl 24)).toLong() } } diff --git a/app/src/main/java/io/github/wulkanowy/utils/AppWidgetUpdater.kt b/app/src/main/java/io/github/wulkanowy/utils/AppWidgetUpdater.kt deleted file mode 100644 index 1b54f40c..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/AppWidgetUpdater.kt +++ /dev/null @@ -1,34 +0,0 @@ -package io.github.wulkanowy.utils - -import android.appwidget.AppWidgetManager -import android.content.BroadcastReceiver -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import dagger.hilt.android.qualifiers.ApplicationContext -import timber.log.Timber -import javax.inject.Inject -import kotlin.reflect.KClass - -class AppWidgetUpdater @Inject constructor( - @ApplicationContext private val context: Context, - private val appWidgetManager: AppWidgetManager -) { - - fun updateAllAppWidgetsByProvider(providerClass: KClass) { - try { - val ids = appWidgetManager.getAppWidgetIds(ComponentName(context, providerClass.java)) - if (ids.isEmpty()) return - - val intent = Intent(context, providerClass.java) - .apply { - action = AppWidgetManager.ACTION_APPWIDGET_UPDATE - putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids) - } - - context.sendBroadcast(intent) - } catch (e: Exception) { - Timber.e(e, "Failed to update all widgets for provider $providerClass") - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt index 3cac0b48..f10b00a0 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/AttendanceExtension.kt @@ -10,26 +10,23 @@ import io.github.wulkanowy.sdk.scrapper.attendance.AttendanceCategory * (https://www.vulcan.edu.pl/vulcang_files/user/AABW/AABW-PDF/uonetplus/uonetplus_Frekwencja-liczby-obecnych-nieobecnych.pdf) */ -inline val AttendanceSummary.allPresences: Int - get() = presence + absenceForSchoolReasons + lateness + latenessExcused +private inline val AttendanceSummary.allPresences: Double + get() = presence.toDouble() + absenceForSchoolReasons + lateness + latenessExcused -inline val AttendanceSummary.allAbsences: Int - get() = absence + absenceExcused +private inline val AttendanceSummary.allAbsences: Double + get() = absence.toDouble() + absenceExcused -inline val Attendance.isExcusableOrNotExcused: Boolean - get() = (excusable || ((absence || lateness) && !excused)) && excuseStatus == null - -fun AttendanceSummary.calculatePercentage() = calculatePercentage(allPresences.toDouble(), allAbsences.toDouble()) +fun AttendanceSummary.calculatePercentage() = calculatePercentage(allPresences, allAbsences) fun List.calculatePercentage(): Double { - return calculatePercentage(sumOf { it.allPresences.toDouble() }, sumOf { it.allAbsences.toDouble() }) + return calculatePercentage(sumByDouble { it.allPresences }, sumByDouble { it.allAbsences }) } private fun calculatePercentage(presence: Double, absence: Double): Double { return if ((presence + absence) == 0.0) 0.0 else (presence / (presence + absence)) * 100 } -inline val Attendance.descriptionRes +inline val Attendance.description get() = when (AttendanceCategory.getCategoryByName(name)) { AttendanceCategory.PRESENCE -> R.string.attendance_present AttendanceCategory.ABSENCE_UNEXCUSED -> R.string.attendance_absence_unexcused diff --git a/app/src/main/java/io/github/wulkanowy/utils/BaseRemoteConfigHelper.kt b/app/src/main/java/io/github/wulkanowy/utils/BaseRemoteConfigHelper.kt deleted file mode 100644 index 002612a8..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/BaseRemoteConfigHelper.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.github.wulkanowy.utils - -abstract class BaseRemoteConfigHelper { - - open fun initialize() = Unit - - open val userAgentTemplate: String - get() = RemoteConfigDefaults.USER_AGENT_TEMPLATE.value as String -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt deleted file mode 100644 index b1742b4f..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt +++ /dev/null @@ -1,34 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Intent -import android.os.Build -import android.os.Bundle -import android.os.Parcelable -import androidx.core.os.BundleCompat -import java.io.Serializable - -// Even though API was introduced in 33, we use 34 as 33 is bugged in some scenarios. - -inline fun Bundle.serializable(key: String): T = when { - Build.VERSION.SDK_INT >= 34 -> getSerializable(key, T::class.java)!! - else -> @Suppress("DEPRECATION") getSerializable(key) as T -} - -inline fun Bundle.nullableSerializable(key: String): T? = when { - Build.VERSION.SDK_INT >= 34 -> getSerializable(key, T::class.java) - else -> @Suppress("DEPRECATION") getSerializable(key) as T? -} - -@Suppress("UNCHECKED_CAST") -inline fun Bundle.parcelableArray(key: String): Array? = - BundleCompat.getParcelableArray(this, key, T::class.java) as Array? - -inline fun Intent.serializable(key: String): T = when { - Build.VERSION.SDK_INT >= 34 -> getSerializableExtra(key, T::class.java)!! - else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T -} - -inline fun Intent.nullableSerializable(key: String): T? = when { - Build.VERSION.SDK_INT >= 34 -> getSerializableExtra(key, T::class.java) - else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T? -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt index 77f3eb64..cf715e65 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt @@ -1,19 +1,16 @@ package io.github.wulkanowy.utils -import android.annotation.SuppressLint import android.content.Context -import android.content.res.ColorStateList -import android.graphics.* -import android.text.TextPaint +import android.content.Intent +import android.net.Uri import android.util.DisplayMetrics.DENSITY_DEFAULT -import androidx.annotation.* +import androidx.annotation.AttrRes +import androidx.annotation.ColorInt +import androidx.annotation.ColorRes +import androidx.annotation.DrawableRes import androidx.core.content.ContextCompat import androidx.core.graphics.ColorUtils -import androidx.core.graphics.applyCanvas -import androidx.core.graphics.drawable.RoundedBitmapDrawable -import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory -import androidx.core.graphics.drawable.toBitmap - +import io.github.wulkanowy.BuildConfig.APPLICATION_ID @ColorInt fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int { @@ -33,60 +30,58 @@ fun Context.getThemeAttrColor(@AttrRes colorAttr: Int, alpha: Int): Int { @ColorInt fun Context.getCompatColor(@ColorRes colorRes: Int) = ContextCompat.getColor(this, colorRes) -fun Context.getCompatDrawable(@DrawableRes drawableRes: Int) = - ContextCompat.getDrawable(this, drawableRes) +fun Context.getCompatDrawable(@DrawableRes drawableRes: Int) = ContextCompat.getDrawable(this, drawableRes) -fun Context.getCompatDrawable(@DrawableRes drawableRes: Int, @ColorRes colorRes: Int) = - getCompatDrawable(drawableRes)?.mutate()?.apply { - colorFilter = PorterDuffColorFilter( - getCompatColor(colorRes), PorterDuff.Mode.MULTIPLY - ) +fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -> Unit) { + Intent.parseUri(uri, 0).let { + if (it.resolveActivity(packageManager) != null) startActivity(it) + else onActivityNotFound(uri) + } +} + +fun Context.openAppInMarket(onActivityNotFound: (uri: String) -> Unit) { + openInternetBrowser("market://details?id=${APPLICATION_ID}") { + openInternetBrowser("https://github.com/wulkanowy/wulkanowy/releases", onActivityNotFound) + } +} + +fun Context.openEmailClient(chooserTitle: String, email: String, subject: String, body: String, onActivityNotFound: () -> Unit = {}) { + val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply { + putExtra(Intent.EXTRA_EMAIL, arrayOf(email)) + putExtra(Intent.EXTRA_SUBJECT, subject) + putExtra(Intent.EXTRA_TEXT, body) } -fun Context.getCompatBitmap(@DrawableRes drawableRes: Int, @ColorRes colorRes: Int) = - getCompatDrawable(drawableRes, colorRes)?.toBitmap() + if (intent.resolveActivity(packageManager) != null) { + startActivity(Intent.createChooser(intent, chooserTitle)) + } else onActivityNotFound() +} -fun Context.getPlural(@PluralsRes pluralRes: Int, quantity: Int, vararg arguments: Any) = - resources.getQuantityString(pluralRes, quantity, *arguments) +fun Context.openNavigation(location: String) { + val intentUri = Uri.parse("geo:0,0?q=${Uri.encode(location)}") + val intent = Intent(Intent.ACTION_VIEW, intentUri) + if (intent.resolveActivity(packageManager) != null) { + startActivity(intent) + } +} + +fun Context.openDialer(phone: String) { + val intentUri = Uri.parse("tel:$phone") + val intent = Intent(Intent.ACTION_DIAL, intentUri) + startActivity(intent) +} + +fun Context.shareText(text: String, subject: String?) { + val sendIntent: Intent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_TEXT, text) + if (subject != null) { + putExtra(Intent.EXTRA_SUBJECT, subject) + } + type = "text/plain" + } + val shareIntent = Intent.createChooser(sendIntent, null) + startActivity(shareIntent) +} fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT - -@SuppressLint("DefaultLocale") -fun Context.createNameInitialsDrawable( - text: String, - backgroundColor: Long, - scaleFactory: Float = 1f -): RoundedBitmapDrawable { - val words = text.split(" ") - val firstCharFirstWord = words.getOrNull(0)?.firstOrNull() ?: "" - val firstCharSecondWord = words.getOrNull(1)?.firstOrNull() ?: "" - - val initials = "$firstCharFirstWord$firstCharSecondWord".uppercase() - - val bounds = Rect() - val dimension = this.dpToPx(64f * scaleFactory).toInt() - val textPaint = TextPaint().apply { - typeface = Typeface.SANS_SERIF - color = Color.WHITE - textAlign = Paint.Align.CENTER - isAntiAlias = true - textSize = this@createNameInitialsDrawable.dpToPx(30f * scaleFactory) - getTextBounds(initials, 0, initials.length, bounds) - } - - val xCoordinate = (dimension / 2).toFloat() - val yCoordinate = (dimension / 2 + (bounds.bottom - bounds.top) / 2).toFloat() - - val bitmap = Bitmap.createBitmap(dimension, dimension, Bitmap.Config.ARGB_8888) - .applyCanvas { - drawColor(backgroundColor.toInt()) - drawText(initials, 0, initials.length, xCoordinate, yCoordinate, textPaint) - } - - return RoundedBitmapDrawableFactory.create(this.resources, bitmap) - .apply { isCircular = true } -} - -fun Context.getAttrColorStateList(@AttrRes color: Int): ColorStateList { - return ColorStateList.valueOf(getThemeAttrColor(color)) -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/DispatchersProvider.kt b/app/src/main/java/io/github/wulkanowy/utils/DispatchersProvider.kt index 8aaa57f4..ecc8e05e 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/DispatchersProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/DispatchersProvider.kt @@ -1,8 +1,10 @@ package io.github.wulkanowy.utils +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers open class DispatchersProvider { - open val io get() = Dispatchers.IO + open val backgroundThread: CoroutineDispatcher + get() = Dispatchers.IO } diff --git a/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt deleted file mode 100644 index d541c0a7..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt +++ /dev/null @@ -1,82 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.res.Resources -import io.github.wulkanowy.R -import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException -import io.github.wulkanowy.sdk.scrapper.exception.AccountInactiveException -import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException -import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException -import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException -import io.github.wulkanowy.sdk.scrapper.exception.ServiceUnavailableException -import io.github.wulkanowy.sdk.scrapper.exception.VulcanException -import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException -import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException -import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException -import okhttp3.internal.http2.StreamResetException -import java.io.InterruptedIOException -import java.net.ConnectException -import java.net.SocketException -import java.net.SocketTimeoutException -import java.net.UnknownHostException -import java.security.cert.CertPathValidatorException -import java.security.cert.CertificateExpiredException -import java.security.cert.CertificateNotYetValidException -import javax.net.ssl.SSLHandshakeException - -fun Resources.getErrorString(error: Throwable): String = when (error) { - is UnknownHostException -> R.string.error_no_internet - is ConnectException, - is SocketException, - is SocketTimeoutException, - is InterruptedIOException, - is StreamResetException -> R.string.error_timeout - is NotLoggedInException -> R.string.error_login_failed - is PasswordChangeRequiredException -> R.string.error_password_change_required - is ServiceUnavailableException -> R.string.error_service_unavailable - is FeatureDisabledException -> R.string.error_feature_disabled - is FeatureNotAvailableException -> R.string.error_feature_not_available - is BadCredentialsException -> R.string.error_password_invalid - is AccountInactiveException -> R.string.error_account_inactive - is VulcanException -> R.string.error_unknown_uonet - is ScrapperException -> R.string.error_unknown_app - is CloudflareVerificationException -> R.string.error_cloudflare_captcha - is SSLHandshakeException -> when { - error.isCausedByCertificateNotValidNow() -> R.string.error_invalid_device_datetime - else -> R.string.error_timeout - } - else -> R.string.error_unknown -}.let { getString(it) } - -fun Throwable.isShouldBeReported(): Boolean = when (this) { - is UnknownHostException, - is ConnectException, - is SocketException, - is SocketTimeoutException, - is InterruptedIOException, - is StreamResetException, - is ServiceUnavailableException, - is FeatureDisabledException, - is FeatureNotAvailableException -> false - is SSLHandshakeException -> when { - isCausedByCertificateNotValidNow() -> false - else -> true - } - else -> true -} - -private fun Throwable?.isCausedByCertificateNotValidNow(): Boolean { - var exception = this - do { - if (exception.isCertificateNotValidNow()) return true - - exception = exception?.cause - } while (exception != null) - return false -} - -private fun Throwable?.isCertificateNotValidNow(): Boolean { - val isNotYetValid = this is CertificateNotYetValidException - val isExpired = this is CertificateExpiredException - val isInvalidPath = this is CertPathValidatorException - return isNotYetValid || isExpired || isInvalidPath -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/FlowUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/FlowUtils.kt new file mode 100644 index 00000000..724458c0 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/FlowUtils.kt @@ -0,0 +1,98 @@ +package io.github.wulkanowy.utils + +import io.github.wulkanowy.data.Resource +import io.github.wulkanowy.data.Status +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.takeWhile + +inline fun networkBoundResource( + showSavedOnLoading: Boolean = true, + crossinline query: () -> Flow, + crossinline fetch: suspend (ResultType) -> RequestType, + crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit, + crossinline onFetchFailed: (Throwable) -> Unit = { Unit }, + crossinline shouldFetch: (ResultType) -> Boolean = { true }, + crossinline filterResult: (ResultType) -> ResultType = { it } +) = flow { + emit(Resource.loading()) + + val data = query().first() + emitAll(if (shouldFetch(data)) { + if (showSavedOnLoading) emit(Resource.loading(filterResult(data))) + + try { + saveFetchResult(data, fetch(data)) + query().map { Resource.success(filterResult(it)) } + } catch (throwable: Throwable) { + onFetchFailed(throwable) + query().map { Resource.error(throwable, filterResult(it)) } + } + } else { + query().map { Resource.success(filterResult(it)) } + }) +} + +@JvmName("networkBoundResourceWithMap") +inline fun networkBoundResource( + showSavedOnLoading: Boolean = true, + crossinline query: () -> Flow, + crossinline fetch: suspend (ResultType) -> RequestType, + crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit, + crossinline onFetchFailed: (Throwable) -> Unit = { Unit }, + crossinline shouldFetch: (ResultType) -> Boolean = { true }, + crossinline mapResult: (ResultType) -> T +) = flow { + emit(Resource.loading()) + + val data = query().first() + emitAll(if (shouldFetch(data)) { + if (showSavedOnLoading) emit(Resource.loading(mapResult(data))) + + try { + saveFetchResult(data, fetch(data)) + query().map { Resource.success(mapResult(it)) } + } catch (throwable: Throwable) { + onFetchFailed(throwable) + query().map { Resource.error(throwable, mapResult(it)) } + } + } else { + query().map { Resource.success(mapResult(it)) } + }) +} + +fun flowWithResource(block: suspend () -> T) = flow { + emit(Resource.loading()) + emit(try { + Resource.success(block()) + } catch (e: Throwable) { + Resource.error(e) + }) +} + +fun flowWithResourceIn(block: suspend () -> Flow>) = flow { + emit(Resource.loading()) + + block() + .catch { emit(Resource.error(it)) } + .collect { + if (it.status != Status.LOADING) { // LOADING is already emitted + emit(it) + } + } +} + +fun Flow>.afterLoading(callback: () -> Unit) = onEach { + if (it.status != Status.LOADING) callback() +} + +suspend fun Flow>.toFirstResult() = filter { it.status != Status.LOADING }.first() + +suspend fun Flow>.waitForResult() = takeWhile { it.status == Status.LOADING }.collect() diff --git a/app/src/main/java/io/github/wulkanowy/utils/FragNavControlerExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/FragNavControlerExtension.kt index 01c876dd..9dc1e18a 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/FragNavControlerExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/FragNavControlerExtension.kt @@ -2,19 +2,16 @@ package io.github.wulkanowy.utils import androidx.fragment.app.Fragment import com.ncapdevi.fragnav.FragNavController -import io.github.wulkanowy.ui.base.BaseView +import io.github.wulkanowy.ui.modules.main.MainView -inline fun FragNavController.setOnViewChangeListener(crossinline listener: (view: BaseView) -> Unit) { +inline fun FragNavController.setOnViewChangeListener(crossinline listener: (section: MainView.Section?, name: String?) -> Unit) { transactionListener = object : FragNavController.TransactionListener { - override fun onFragmentTransaction( - fragment: Fragment?, - transactionType: FragNavController.TransactionType - ) { - fragment?.let { listener(it as BaseView) } + override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) { + listener(fragment?.toSection(), fragment?.let { it::class.java.simpleName }) } override fun onTabTransaction(fragment: Fragment?, index: Int) { - fragment?.let { listener(it as BaseView) } + listener(fragment?.toSection(), fragment?.let { it::class.java.simpleName }) } } } diff --git a/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt new file mode 100644 index 00000000..0b71c964 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/FragmentExtension.kt @@ -0,0 +1,34 @@ +package io.github.wulkanowy.utils + +import androidx.fragment.app.Fragment +import io.github.wulkanowy.ui.modules.about.AboutFragment +import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment +import io.github.wulkanowy.ui.modules.exam.ExamFragment +import io.github.wulkanowy.ui.modules.grade.GradeFragment +import io.github.wulkanowy.ui.modules.homework.HomeworkFragment +import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment +import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.ui.modules.message.MessageFragment +import io.github.wulkanowy.ui.modules.more.MoreFragment +import io.github.wulkanowy.ui.modules.note.NoteFragment +import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment +import io.github.wulkanowy.ui.modules.settings.SettingsFragment +import io.github.wulkanowy.ui.modules.timetable.TimetableFragment + +fun Fragment.toSection(): MainView.Section? { + return when (this) { + is GradeFragment -> MainView.Section.GRADE + is AttendanceFragment -> MainView.Section.ATTENDANCE + is ExamFragment -> MainView.Section.EXAM + is TimetableFragment -> MainView.Section.TIMETABLE + is MoreFragment -> MainView.Section.MORE + is MessageFragment -> MainView.Section.MESSAGE + is HomeworkFragment -> MainView.Section.HOMEWORK + is NoteFragment -> MainView.Section.NOTE + is LuckyNumberFragment -> MainView.Section.LUCKY_NUMBER + is SettingsFragment -> MainView.Section.SETTINGS + is AboutFragment -> MainView.Section.ABOUT + is SchoolAndTeachersFragment -> MainView.Section.SCHOOL + else -> null + } +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt index 61924d4e..c57b6247 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt @@ -3,80 +3,76 @@ package io.github.wulkanowy.utils import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.db.entities.GradeSummary -import io.github.wulkanowy.data.enums.GradeColorTheme -import io.github.wulkanowy.sdk.scrapper.grades.getGradeValueWithModifier -import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid -fun List.calcAverage(isOptionalArithmeticAverage: Boolean): Double { - val isArithmeticAverage = isOptionalArithmeticAverage && !any { it.weightValue != .0 } +fun List.calcAverage(): Double { var counter = 0.0 var denominator = 0.0 forEach { - val weight = if (isArithmeticAverage && isGradeValid(it.entry)) 1.0 else it.weightValue - counter += (it.value + it.modifier) * weight - denominator += weight + counter += (it.value + it.modifier) * it.weightValue + denominator += it.weightValue } return if (denominator != 0.0) counter / denominator else 0.0 } -fun List.calcFinalAverage(plusModifier: Double, minusModifier: Double) = asSequence() - .mapNotNull { summary -> - val (gradeValue, gradeModifier) = getGradeValueWithModifier(summary.finalGrade) - if (gradeValue == null || gradeModifier == null) return@mapNotNull null +@JvmName("calcSummaryAverage") +fun List.calcAverage(): Double { + return asSequence().mapNotNull { + if (it.finalGrade.matches("[0-6]".toRegex())) it.finalGrade.toDouble() else null + }.average().let { if (it.isNaN()) 0.0 else it } +} - when { - gradeModifier > 0 -> gradeValue + plusModifier - gradeModifier < 0 -> gradeValue - minusModifier - else -> gradeValue + 0.0 +fun Grade.getBackgroundColor(theme: String): Int { + return when (theme) { + "grade_color" -> getGradeColor() + "material" -> when (value.toInt()) { + 6 -> R.color.grade_material_six + 5 -> R.color.grade_material_five + 4 -> R.color.grade_material_four + 3 -> R.color.grade_material_three + 2 -> R.color.grade_material_two + 1 -> R.color.grade_material_one + else -> R.color.grade_material_default + } + else -> when (value.toInt()) { + 6 -> R.color.grade_vulcan_six + 5 -> R.color.grade_vulcan_five + 4 -> R.color.grade_vulcan_four + 3 -> R.color.grade_vulcan_three + 2 -> R.color.grade_vulcan_two + 1 -> R.color.grade_vulcan_one + else -> R.color.grade_vulcan_default } } - .average() - .let { if (it.isNaN()) 0.0 else it } +} -fun Grade.getGradeColor() = when (color) { - "000000" -> R.color.grade_black - "F04C4C" -> R.color.grade_red - "20A4F7" -> R.color.grade_blue - "6ECD07" -> R.color.grade_green - "B16CF1" -> R.color.grade_purple - else -> R.color.grade_material_default +fun Grade.getGradeColor(): Int { + return when (color) { + "000000" -> R.color.grade_black + "F04C4C" -> R.color.grade_red + "20A4F7" -> R.color.grade_blue + "6ECD07" -> R.color.grade_green + "B16CF1" -> R.color.grade_purple + else -> R.color.grade_material_default + } } inline val Grade.colorStringId: Int - get() = when (color) { - "000000" -> R.string.all_black - "F04C4C" -> R.string.all_red - "20A4F7" -> R.string.all_blue - "6ECD07" -> R.string.all_green - "B16CF1" -> R.string.all_purple - else -> R.string.all_empty_color + get() { + return when (color) { + "000000" -> R.string.all_black + "F04C4C" -> R.string.all_red + "20A4F7" -> R.string.all_blue + "6ECD07" -> R.string.all_green + "B16CF1" -> R.string.all_purple + else -> R.string.all_empty_color + } } -fun Grade.changeModifier(plusModifier: Double, minusModifier: Double) = when { - modifier > 0 -> copy(modifier = plusModifier) - modifier < 0 -> copy(modifier = -minusModifier) - else -> this -} - -fun Grade.getBackgroundColor(theme: GradeColorTheme) = when (theme) { - GradeColorTheme.GRADE_COLOR -> getGradeColor() - GradeColorTheme.MATERIAL -> when (value.toInt()) { - 6 -> R.color.grade_material_six - 5 -> R.color.grade_material_five - 4 -> R.color.grade_material_four - 3 -> R.color.grade_material_three - 2 -> R.color.grade_material_two - 1 -> R.color.grade_material_one - else -> R.color.grade_material_default - } - GradeColorTheme.VULCAN -> when (value.toInt()) { - 6 -> R.color.grade_vulcan_six - 5 -> R.color.grade_vulcan_five - 4 -> R.color.grade_vulcan_four - 3 -> R.color.grade_vulcan_three - 2 -> R.color.grade_vulcan_two - 1 -> R.color.grade_vulcan_one - else -> R.color.grade_vulcan_default +fun Grade.changeModifier(plusModifier: Double, minusModifier: Double): Grade { + return when { + modifier > 0 -> copy(modifier = plusModifier) + modifier < 0 -> copy(modifier = -minusModifier) + else -> this } } diff --git a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt deleted file mode 100644 index 62b85af4..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt +++ /dev/null @@ -1,121 +0,0 @@ -package io.github.wulkanowy.utils - -import android.app.Activity -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Build -import android.provider.CalendarContract -import android.provider.Settings -import io.github.wulkanowy.BuildConfig -import timber.log.Timber -import java.time.LocalDateTime -import java.time.ZoneId - -fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -> Unit = {}) { - Intent.parseUri(uri, 0).let { - try { - startActivity(it) - } catch (e: ActivityNotFoundException) { - onActivityNotFound(uri) - } - } -} - -fun Context.openAppInMarket(onActivityNotFound: (uri: String) -> Unit) { - openInternetBrowser("market://details?id=${BuildConfig.APPLICATION_ID}") { - openInternetBrowser("https://github.com/wulkanowy/wulkanowy/releases", onActivityNotFound) - } -} - -fun Context.openEmailClient( - chooserTitle: String, - email: String, - subject: String, - body: String, - onActivityNotFound: () -> Unit = {} -) { - val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply { - putExtra(Intent.EXTRA_EMAIL, arrayOf(email)) - putExtra(Intent.EXTRA_SUBJECT, subject) - putExtra(Intent.EXTRA_TEXT, body) - } - - if (intent.resolveActivity(packageManager) != null) { - startActivity(Intent.createChooser(intent, chooserTitle)) - } else onActivityNotFound() -} - -fun Context.openCalendarEventAdd( - title: String, - description: String, - start: LocalDateTime, - end: LocalDateTime? = null, - isAllDay: Boolean = false, - onActivityNotFound: (uri: String?) -> Unit = {}, -) { - val beginTime = start.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - val endTime = end?.atZone(ZoneId.systemDefault())?.toInstant()?.toEpochMilli() - - val intent = Intent(Intent.ACTION_INSERT) - .setData(CalendarContract.Events.CONTENT_URI) - .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime) - .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime) - .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay) - .putExtra(CalendarContract.Events.TITLE, title) - .putExtra(CalendarContract.Events.DESCRIPTION, description) - .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY) - - try { - startActivity(intent) - } catch (e: ActivityNotFoundException) { - onActivityNotFound(intent.dataString) - } -} - -fun Context.openNavigation(location: String) { - val intentUri = Uri.parse("geo:0,0?q=${Uri.encode(location)}") - val intent = Intent(Intent.ACTION_VIEW, intentUri) - if (intent.resolveActivity(packageManager) != null) { - startActivity(intent) - } -} - -fun Context.openDialer(phone: String) { - val intentUri = Uri.parse("tel:$phone") - val intent = Intent(Intent.ACTION_DIAL, intentUri) - if (intent.resolveActivity(packageManager) != null) { - startActivity(intent) - } -} - -fun Activity.openNotificationSettings() { - val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply { - putExtra("android.provider.extra.APP_PACKAGE", packageName) - } - } else { - Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { - data = Uri.fromParts("package", packageName, null) - } - } - try { - startActivity(intent) - } catch (e: Exception) { - Timber.e(e) - } -} - -fun Context.shareText(text: String, subject: String?) { - val sendIntent: Intent = Intent().apply { - action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_TEXT, text) - if (subject != null) { - putExtra(Intent.EXTRA_SUBJECT, subject) - } - type = "text/plain" - } - val shareIntent = Intent.createChooser(sendIntent, null) - startActivity(shareIntent) -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt b/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt index 76ce66dc..b96faeb2 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt @@ -1,16 +1,14 @@ package io.github.wulkanowy.utils -import android.os.Handler -import android.os.Looper import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty -class LifecycleAwareVariable : ReadWriteProperty, DefaultLifecycleObserver { +class LifecycleAwareVariable : ReadWriteProperty, LifecycleObserver { private var _value: T? = null @@ -23,39 +21,35 @@ class LifecycleAwareVariable : ReadWriteProperty, DefaultL override fun getValue(thisRef: Fragment, property: KProperty<*>) = _value ?: throw IllegalStateException("Trying to call an lifecycle-aware value outside of the view lifecycle, or the value has not been initialized") - override fun onDestroy(owner: LifecycleOwner) { - Handler(Looper.getMainLooper()).post { - _value = null - } + @Suppress("unused") + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun onDestroyView() { + _value = null } } -class LifecycleAwareVariableComponent : ReadWriteProperty, - DefaultLifecycleObserver { +class LifecycleAwareVariableActivity : ReadWriteProperty, LifecycleObserver { private var _value: T? = null - override fun setValue(thisRef: LifecycleOwner, property: KProperty<*>, value: T) { + override fun setValue(thisRef: AppCompatActivity, property: KProperty<*>, value: T) { thisRef.lifecycle.removeObserver(this) _value = value thisRef.lifecycle.addObserver(this) } - override fun getValue(thisRef: LifecycleOwner, property: KProperty<*>) = _value + override fun getValue(thisRef: AppCompatActivity, property: KProperty<*>) = _value ?: throw IllegalStateException("Trying to call an lifecycle-aware value outside of the view lifecycle, or the value has not been initialized") - override fun onDestroy(owner: LifecycleOwner) { - Handler(Looper.getMainLooper()).post { - _value = null - } + @Suppress("unused") + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun onDestroyView() { + _value = null } } + @Suppress("unused") fun Fragment.lifecycleAwareVariable() = LifecycleAwareVariable() -@Suppress("unused") -fun DialogFragment.lifecycleAwareVariable() = LifecycleAwareVariableComponent() - -@Suppress("unused") -fun AppCompatActivity.lifecycleAwareVariable() = LifecycleAwareVariableComponent() +fun lifecycleAwareVariable() = LifecycleAwareVariableActivity() diff --git a/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt index 00ed2c11..48d46892 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt @@ -7,13 +7,7 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import fr.bipi.treessence.common.filters.Filter -import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException -import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException import timber.log.Timber -import java.io.InterruptedIOException -import java.net.SocketTimeoutException -import java.net.UnknownHostException import javax.inject.Inject import javax.inject.Singleton @@ -24,20 +18,7 @@ class DebugLogTree : Timber.DebugTree() { } } -object ExceptionFilter : Filter { - - override fun isLoggable(priority: Int, tag: String?) = true - - override fun skipLog(priority: Int, tag: String?, message: String, t: Throwable?) = - when (t) { - is FeatureDisabledException, - is FeatureNotAvailableException, - is UnknownHostException, - is SocketTimeoutException, - is InterruptedIOException -> true - else -> false - } -} +private fun Bundle?.checkSavedState() = if (this == null) "(STATE IS NULL)" else "(STATE IS NOT NULL)" class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { @@ -71,15 +52,9 @@ class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { } @Singleton -class FragmentLifecycleLogger @Inject constructor() : - FragmentManager.FragmentLifecycleCallbacks() { +class FragmentLifecycleLogger @Inject constructor() : FragmentManager.FragmentLifecycleCallbacks() { - override fun onFragmentViewCreated( - fm: FragmentManager, - f: Fragment, - v: View, - savedInstanceState: Bundle? - ) { + override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) { Timber.d("${f::class.java.simpleName} VIEW CREATED ${savedInstanceState.checkSavedState()}") } @@ -87,11 +62,7 @@ class FragmentLifecycleLogger @Inject constructor() : Timber.d("${f::class.java.simpleName} STOPPED") } - override fun onFragmentCreated( - fm: FragmentManager, - f: Fragment, - savedInstanceState: Bundle? - ) { + override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { Timber.d("${f::class.java.simpleName} CREATED ${savedInstanceState.checkSavedState()}") } @@ -107,11 +78,7 @@ class FragmentLifecycleLogger @Inject constructor() : Timber.d("${f::class.java.simpleName} DESTROYED") } - override fun onFragmentSaveInstanceState( - fm: FragmentManager, - f: Fragment, - outState: Bundle - ) { + override fun onFragmentSaveInstanceState(fm: FragmentManager, f: Fragment, outState: Bundle) { Timber.d("${f::class.java.simpleName} SAVED INSTANCE STATE") } @@ -123,6 +90,10 @@ class FragmentLifecycleLogger @Inject constructor() : Timber.d("${f::class.java.simpleName} VIEW DESTROYED") } + override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { + Timber.d("${f::class.java.simpleName} ACTIVITY CREATED ${savedInstanceState.checkSavedState()}") + } + override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { Timber.d("${f::class.java.simpleName} PAUSED") } @@ -131,7 +102,3 @@ class FragmentLifecycleLogger @Inject constructor() : Timber.d("${f::class.java.simpleName} DETACHED") } } - -private fun Bundle?.checkSavedState() = - if (this == null) "(STATE IS NULL)" else "(RESTORE STATE)" - diff --git a/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt deleted file mode 100644 index 09ccda89..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/MaterialDatePickerUtils.kt +++ /dev/null @@ -1,50 +0,0 @@ -package io.github.wulkanowy.utils - -import androidx.fragment.app.Fragment -import com.google.android.material.datepicker.CalendarConstraints -import com.google.android.material.datepicker.MaterialDatePicker -import kotlinx.parcelize.Parcelize -import java.time.LocalDate -import java.time.temporal.ChronoUnit - -fun Fragment.openMaterialDatePicker( - selected: LocalDate, - rangeStart: LocalDate, - rangeEnd: LocalDate, - onDateSelected: (LocalDate) -> Unit, -) { - val constraintsBuilder = CalendarConstraints.Builder().apply { - setValidator(CalendarDayRangeValidator(rangeStart, rangeEnd)) - setStart(rangeStart.toTimestamp()) - setEnd(rangeEnd.toTimestamp()) - } - - val datePicker = MaterialDatePicker.Builder.datePicker() - .setCalendarConstraints(constraintsBuilder.build()) - .setSelection(selected.toTimestamp()) - .build() - - datePicker.addOnPositiveButtonClickListener { - val date = it.toLocalDateTime().toLocalDate() - onDateSelected(date) - } - - if (!parentFragmentManager.isStateSaved) { - datePicker.show(parentFragmentManager, null) - } -} - -@Parcelize -private class CalendarDayRangeValidator( - val start: LocalDate, - val end: LocalDate, -) : CalendarConstraints.DateValidator { - - override fun isValid(dateLong: Long): Boolean { - val date = dateLong.toLocalDateTime().toLocalDate() - val daysUntilEnd = date.until(end, ChronoUnit.DAYS) - val daysUntilStart = date.until(start, ChronoUnit.DAYS) - - return daysUntilStart <= 0 && daysUntilEnd >= 0 - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/PendingIntentCompat.kt b/app/src/main/java/io/github/wulkanowy/utils/PendingIntentCompat.kt deleted file mode 100644 index 45ee431a..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/PendingIntentCompat.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.github.wulkanowy.utils - -import android.app.PendingIntent -import android.os.Build - -object PendingIntentCompat { - - val FLAG_IMMUTABLE = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - PendingIntent.FLAG_IMMUTABLE - } else 0 -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt deleted file mode 100644 index e43654b8..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.github.wulkanowy.utils - -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.wulkanowy.R -import io.github.wulkanowy.data.db.SharedPrefProvider -import io.github.wulkanowy.data.db.entities.Mailbox -import io.github.wulkanowy.data.db.entities.Semester -import io.github.wulkanowy.data.db.entities.Student -import io.github.wulkanowy.data.enums.MessageFolder -import timber.log.Timber -import java.time.Duration.ofMinutes -import java.time.Instant -import java.time.LocalDate -import javax.inject.Inject - -fun getRefreshKey(name: String, semester: Semester, start: LocalDate, end: LocalDate): String { - return "${name}_${semester.studentId}_${semester.semesterId}_${start.monday}_${end.sunday}" -} - -fun getRefreshKey(name: String, semester: Semester): String { - return "${name}_${semester.studentId}_${semester.semesterId}" -} - -fun getRefreshKey(name: String, student: Student): String { - return "${name}_${student.studentId}" -} - -fun getRefreshKey(name: String, mailbox: Mailbox?, folder: MessageFolder): String { - return "${name}_${mailbox?.globalKey ?: "all"}_${folder.id}" -} - -class AutoRefreshHelper @Inject constructor( - @ApplicationContext private val context: Context, - private val sharedPref: SharedPrefProvider -) { - - fun shouldBeRefreshed(key: String): Boolean { - val timestamp = sharedPref.getLong(key, 0).let(Instant::ofEpochMilli) - val servicesInterval = sharedPref.getString(context.getString(R.string.pref_key_services_interval), context.getString(R.string.pref_default_services_interval)).toLong() - - val shouldBeRefreshed = timestamp < Instant.now().minus(ofMinutes(servicesInterval)) - - Timber.d("Check if $key need to be refreshed: $shouldBeRefreshed (last refresh: $timestamp, interval: $servicesInterval min)") - - return shouldBeRefreshed - } - - fun updateLastRefreshTimestamp(key: String) { - sharedPref.putLong(key, Instant.now().toEpochMilli()) - } - - fun getLastRefreshTimestamp(key: String): Instant { - val refreshTimestampMilli = sharedPref.getLong(key, 0) - return Instant.ofEpochMilli(refreshTimestampMilli) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/RemoteConfigDefaults.kt b/app/src/main/java/io/github/wulkanowy/utils/RemoteConfigDefaults.kt deleted file mode 100644 index 6e8f7ae6..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/RemoteConfigDefaults.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.wulkanowy.utils - -enum class RemoteConfigDefaults(val value: Any) { - USER_AGENT_TEMPLATE(""), - ; - - val key get() = name.lowercase() -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt new file mode 100644 index 00000000..da5fd3db --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/ResourcesExtension.kt @@ -0,0 +1,29 @@ +package io.github.wulkanowy.utils + +import android.content.res.Resources +import io.github.wulkanowy.R +import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException +import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException +import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException +import io.github.wulkanowy.sdk.scrapper.exception.ServiceUnavailableException +import io.github.wulkanowy.sdk.scrapper.exception.VulcanException +import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException +import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException +import okhttp3.internal.http2.StreamResetException +import java.io.InterruptedIOException +import java.net.ConnectException +import java.net.SocketTimeoutException +import java.net.UnknownHostException + +fun Resources.getString(error: Throwable) = when (error) { + is UnknownHostException -> getString(R.string.error_no_internet) + is SocketTimeoutException, is InterruptedIOException, is ConnectException, is StreamResetException -> getString(R.string.error_timeout) + is NotLoggedInException -> getString(R.string.error_login_failed) + is PasswordChangeRequiredException -> getString(R.string.error_password_change_required) + is ServiceUnavailableException -> getString(R.string.error_service_unavailable) + is FeatureDisabledException -> getString(R.string.error_feature_disabled) + is FeatureNotAvailableException -> getString(R.string.error_feature_not_available) + is VulcanException -> getString(R.string.error_unknown_uonet) + is ScrapperException -> getString(R.string.error_unknown_app) + else -> getString(R.string.error_unknown) +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt b/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt new file mode 100644 index 00000000..e7c51745 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt @@ -0,0 +1,51 @@ +package io.github.wulkanowy.utils + +import android.os.Parcel +import android.os.Parcelable +import com.wdullaer.materialdatetimepicker.date.DateRangeLimiter +import java.time.DayOfWeek +import java.time.LocalDate +import java.util.Calendar + +@Suppress("UNUSED_PARAMETER") +class SchooldaysRangeLimiter : DateRangeLimiter { + + private val now = LocalDate.now() + + override fun setToNearestDate(day: Calendar): Calendar = day + + override fun isOutOfRange(year: Int, month: Int, day: Int): Boolean { + val date = LocalDate.of(year, month + 1, day) + val dayOfWeek = date.dayOfWeek + return dayOfWeek == DayOfWeek.SUNDAY || date.isHolidays + } + + override fun getStartDate(): Calendar { + val startYear = if (now.monthValue <= 6) now.year - 1 else now.year + val startOfSchoolYear = now.withYear(startYear).firstSchoolDay + + val calendar = Calendar.getInstance() + calendar.set(startOfSchoolYear.year, startOfSchoolYear.monthValue - 1, startOfSchoolYear.dayOfMonth) + return calendar + } + + override fun getEndDate(): Calendar { + val endYear = if (now.monthValue > 6) now.year + 1 else now.year + val endOfSchoolYear = now.withYear(endYear).lastSchoolDay + + val calendar = Calendar.getInstance() + calendar.set(endOfSchoolYear.year, endOfSchoolYear.monthValue - 1, endOfSchoolYear.dayOfMonth) + return calendar + } + + override fun writeToParcel(parcel: Parcel, flags: Int) {} + + override fun describeContents() = 0 + + companion object CREATOR : Parcelable.Creator { + + override fun createFromParcel(parcel: Parcel): SchooldaysRangeLimiter = SchooldaysRangeLimiter() + + override fun newArray(size: Int): Array = arrayOfNulls(size) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt new file mode 100644 index 00000000..63a30db8 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt @@ -0,0 +1,31 @@ +package io.github.wulkanowy.utils + +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.sdk.Sdk +import timber.log.Timber + +fun Sdk.init(student: Student): Sdk { + email = student.email + password = student.password + symbol = student.symbol + schoolSymbol = student.schoolSymbol + studentId = student.studentId + classId = student.classId + + if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) { + scrapperBaseUrl = student.scrapperBaseUrl + loginType = Sdk.ScrapperLoginType.valueOf(student.loginType) + } + loginId = student.userLoginId + + mode = Sdk.Mode.valueOf(student.loginMode) + mobileBaseUrl = student.mobileBaseUrl + certKey = student.certificateKey + privateKey = student.privateKey + + emptyCookieJarInterceptor = true + + Timber.d("Sdk in ${student.loginMode} mode reinitialized") + + return this +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt index 6cfc4fa1..6e11a8b2 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt @@ -1,33 +1,19 @@ package io.github.wulkanowy.utils import io.github.wulkanowy.data.db.entities.Semester -import java.time.LocalDate import java.time.LocalDate.now -import java.time.Month -fun Semester.isCurrent(now: LocalDate = now()): Boolean { - val shiftedStart = if (start.month == Month.SEPTEMBER) { - start.minusDays(3) - } else start - - val shiftedEnd = if (end.month == Month.AUGUST || end.month == Month.SEPTEMBER) { - end.minusDays(3) - } else end - - return now in shiftedStart..shiftedEnd -} +inline val Semester.isCurrent: Boolean + get() = now() in start..end fun List.getCurrentOrLast(): Semester { - if (isEmpty()) throw IllegalStateException("Empty semester list") + if (isEmpty()) throw RuntimeException("Empty semester list") // when there is only one current semester - singleOrNull { it.isCurrent() }?.let { return it } + singleOrNull { it.isCurrent }?.let { return it } // when there is more than one current semester - find one with higher id singleOrNull { semester -> semester.semesterId == maxByOrNull { it.semesterId }?.semesterId }?.let { return it } - // when there is no active kindergarten semester - get one from last year - singleOrNull { semester -> semester.schoolYear == maxByOrNull { it.schoolYear }?.schoolYear }?.let { return it } - throw IllegalArgumentException("Duplicated last semester! Semesters: ${joinToString(separator = "\n")}") } diff --git a/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt index 8043e365..65167fd7 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt @@ -1,15 +1,3 @@ package io.github.wulkanowy.utils -import androidx.core.text.parseAsHtml -import org.apache.commons.text.StringEscapeUtils - -inline fun String?.ifNullOrBlank(defaultValue: () -> String) = - if (isNullOrBlank()) defaultValue() else this - -fun String.capitalise() = - replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() } - -fun String.parseUonetHtml() = this - .let(StringEscapeUtils::unescapeHtml4) - .replace("\n", "
") - .parseAsHtml() +inline fun String?.ifNullOrBlank(defaultValue: () -> String) = if (this.isNullOrBlank()) defaultValue() else this diff --git a/app/src/main/java/io/github/wulkanowy/utils/StudentExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/StudentExtension.kt deleted file mode 100644 index 132a3085..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/StudentExtension.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.github.wulkanowy.utils - -import io.github.wulkanowy.data.db.entities.Student - -inline val Student.nickOrName get() = nick.ifBlank { studentName } diff --git a/app/src/main/java/io/github/wulkanowy/utils/SyncListAdapter.kt b/app/src/main/java/io/github/wulkanowy/utils/SyncListAdapter.kt deleted file mode 100644 index e9135f49..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/SyncListAdapter.kt +++ /dev/null @@ -1,66 +0,0 @@ -package io.github.wulkanowy.utils - -import android.annotation.SuppressLint -import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.RecyclerView - -/** - * Custom alternative to androidx.recyclerview.widget.ListAdapter. ListAdapter is asynchronous which - * caused data race problems in views when a Resource.Error arrived shortly after - * Resource.Intermediate/Success - occasionally in that case the user could see both the Resource's - * data and an error message one on top of the other. This is synchronized by design to avoid that - * problem, however it retains the quality of life improvements of the original. - */ -abstract class SyncListAdapter private constructor( - private val updateStrategy: SyncListAdapter.(List) -> Unit -) : RecyclerView.Adapter() { - - constructor(differ: DiffUtil.ItemCallback) : this({ newItems -> - val diffResult = DiffUtil.calculateDiff(toCallback(differ, items, newItems)) - items = newItems - diffResult.dispatchUpdatesTo(this) - }) - - var items = emptyList() - private set - - final override fun getItemCount() = items.size - - fun getItem(position: Int): T { - return items[position] - } - - /** - * Updates all items, same as submitList, however also disables animations temporarily. - * This prevents a flashing effect on some views. Should be used in favor of submitList when - * all data is changed (e.g. the selected day changes in timetable causing all lessons to change). - */ - @SuppressLint("NotifyDataSetChanged") - fun recreate(data: List) { - items = data - notifyDataSetChanged() - } - - fun submitList(data: List) { - updateStrategy(data.toList()) - } - - private fun toCallback( - itemCallback: DiffUtil.ItemCallback, - old: List, - new: List, - ) = object : DiffUtil.Callback() { - override fun getOldListSize() = old.size - - override fun getNewListSize() = new.size - - override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) = - itemCallback.areItemsTheSame(old[oldItemPosition], new[newItemPosition]) - - override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = - itemCallback.areContentsTheSame(old[oldItemPosition], new[newItemPosition]) - - override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int) = - itemCallback.getChangePayload(old[oldItemPosition], new[newItemPosition]) - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt index e7a50d0c..9bd30e87 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt @@ -1,40 +1,56 @@ package io.github.wulkanowy.utils -import java.text.SimpleDateFormat -import java.time.* -import java.time.DayOfWeek.* -import java.time.format.DateTimeFormatter -import java.time.temporal.TemporalAdjusters.* -import java.util.* +import android.annotation.SuppressLint +import java.time.DayOfWeek.FRIDAY +import java.time.DayOfWeek.MONDAY +import java.time.DayOfWeek.SATURDAY +import java.time.DayOfWeek.SUNDAY +import java.time.Instant.ofEpochMilli +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalDateTime.ofInstant +import java.time.Month +import java.time.ZoneId +import java.time.ZoneOffset +import java.time.format.DateTimeFormatter.ofPattern +import java.time.format.TextStyle.FULL +import java.time.temporal.TemporalAdjusters.firstInMonth +import java.time.temporal.TemporalAdjusters.next +import java.time.temporal.TemporalAdjusters.previous +import java.util.Locale -private const val DEFAULT_DATE_PATTERN = "dd.MM.yyyy" +private const val DATE_PATTERN = "dd.MM.yyyy" -fun LocalDate.toTimestamp(): Long = atStartOfDay() - .toInstant(ZoneOffset.UTC) - .toEpochMilli() +fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format)) -fun Long.toLocalDateTime(): LocalDateTime = LocalDateTime.ofInstant( - Instant.ofEpochMilli(this), ZoneOffset.UTC -) +fun LocalDateTime.toTimestamp() = atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli() -fun Instant.toLocalDate(): LocalDate = atZone(ZoneOffset.UTC).toLocalDate() +fun Long.toLocalDateTime(): LocalDateTime = ofInstant(ofEpochMilli(this), ZoneId.systemDefault()) -fun String.toLocalDate(format: String = DEFAULT_DATE_PATTERN): LocalDate = - LocalDate.parse(this, DateTimeFormatter.ofPattern(format)) +fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format)) -fun LocalDate.toFormattedString(pattern: String = DEFAULT_DATE_PATTERN): String = - format(DateTimeFormatter.ofPattern(pattern)) - -fun Instant.toFormattedString( - pattern: String = DEFAULT_DATE_PATTERN, - tz: ZoneId = ZoneId.systemDefault() -): String = atZone(tz).format(DateTimeFormatter.ofPattern(pattern)) +fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format)) +@SuppressLint("DefaultLocale") fun Month.getFormattedName(): String { - val formatter = SimpleDateFormat("LLLL", Locale.getDefault()) - - val date = LocalDateTime.now().withMonth(value) - return formatter.format(date.toInstant(ZoneOffset.UTC).toEpochMilli()).capitalise() + return getDisplayName(FULL, Locale.getDefault()) + .let { + when (it) { + "stycznia" -> "Styczeń" + "lutego" -> "Luty" + "marca" -> "Marzec" + "kwietnia" -> "Kwiecień" + "maja" -> "Maj" + "czerwca" -> "Czerwiec" + "lipca" -> "Lipiec" + "sierpnia" -> "Sierpień" + "września" -> "Wrzesień" + "października" -> "Październik" + "listopada" -> "Listopad" + "grudnia" -> "Grudzień" + else -> it + } + }.capitalize() } inline val LocalDate.nextSchoolDay: LocalDate @@ -76,33 +92,31 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate } inline val LocalDate.weekDayName: String - get() = format(DateTimeFormatter.ofPattern("EEEE", Locale.getDefault())) + get() = format(ofPattern("EEEE", Locale.getDefault())) -inline val LocalDate.monday: LocalDate get() = with(MONDAY) +inline val LocalDate.monday: LocalDate + get() = with(MONDAY) -inline val LocalDate.sunday: LocalDate get() = with(SUNDAY) +inline val LocalDate.sunday: LocalDate + get() = with(SUNDAY) /** * [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335) */ -val LocalDate.isHolidays: Boolean - get() = isBefore(firstSchoolDayInCalendarYear) && isAfter(lastSchoolDayInCalendarYear) +inline val LocalDate.isHolidays: Boolean + get() = isBefore(firstSchoolDay) && isAfter(lastSchoolDay) -val LocalDate.firstSchoolDayInSchoolYear: LocalDate - get() = withYear(if (this.monthValue <= 6) this.year - 1 else this.year).firstSchoolDayInCalendarYear - -val LocalDate.lastSchoolDayInSchoolYear: LocalDate - get() = withYear(if (this.monthValue > 6) this.year + 1 else this.year).lastSchoolDayInCalendarYear - -fun LocalDate.getLastSchoolDayIfHoliday(schoolYear: Int): LocalDate { - val date = LocalDate.of(schoolYear.getSchoolYearByMonth(monthValue), monthValue, dayOfMonth) - - if (date.isHolidays) { - return date.lastSchoolDayInCalendarYear +inline val LocalDate.firstSchoolDay: LocalDate + get() = LocalDate.of(year, 9, 1).run { + when (dayOfWeek) { + FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY)) + else -> this + } } - return date -} +inline val LocalDate.lastSchoolDay: LocalDate + get() = LocalDate.of(year, 6, 20) + .with(next(FRIDAY)) private fun Int.getSchoolYearByMonth(monthValue: Int): Int { return when (monthValue) { @@ -111,15 +125,12 @@ private fun Int.getSchoolYearByMonth(monthValue: Int): Int { } } -private inline val LocalDate.firstSchoolDayInCalendarYear: LocalDate - get() = LocalDate.of(year, 9, 1).run { - when (dayOfWeek) { - FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY)) - else -> this - } +fun LocalDate.getLastSchoolDayIfHoliday(schoolYear: Int): LocalDate { + val date = LocalDate.of(schoolYear.getSchoolYearByMonth(monthValue), monthValue, dayOfMonth) + + if (date.isHolidays) { + return date.lastSchoolDay } -private inline val LocalDate.lastSchoolDayInCalendarYear: LocalDate - get() = LocalDate.of(year, 6, 20) - .with(next(FRIDAY)) - + return date +} diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt index 3e94463b..f3591306 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimetableExtension.kt @@ -3,10 +3,10 @@ package io.github.wulkanowy.utils import io.github.wulkanowy.data.db.entities.Timetable import java.time.Duration import java.time.Duration.between -import java.time.Instant -import java.time.Instant.now +import java.time.LocalDateTime +import java.time.LocalDateTime.now -fun Timetable.isShowTimeUntil(previousLessonEnd: Instant?) = when { +fun Timetable.isShowTimeUntil(previousLessonEnd: LocalDateTime?) = when { !isStudentPlan -> false canceled -> false now().isAfter(start) -> false @@ -18,7 +18,7 @@ inline val Timetable.left: Duration? get() = when { canceled -> null !isStudentPlan -> null - end >= now() && start <= now() -> between(now(), end) + end.isAfter(now()) && start.isBefore(now()) -> between(now(), end) else -> null } diff --git a/app/src/main/java/io/github/wulkanowy/utils/ViewPagerExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ViewPagerExtension.kt index 700ac2f1..6a5ad880 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ViewPagerExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ViewPagerExtension.kt @@ -1,11 +1,13 @@ package io.github.wulkanowy.utils -import androidx.viewpager2.widget.ViewPager2 +import androidx.viewpager.widget.ViewPager -inline fun ViewPager2.setOnSelectPageListener(crossinline selectListener: (position: Int) -> Unit) { - registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { +inline fun ViewPager.setOnSelectPageListener(crossinline selectListener: (position: Int) -> Unit) { + addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageSelected(position: Int) { selectListener(position) } + override fun onPageScrollStateChanged(state: Int) {} + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} }) } diff --git a/app/src/main/java/io/github/wulkanowy/utils/WebkitCookieManagerProxy.kt b/app/src/main/java/io/github/wulkanowy/utils/WebkitCookieManagerProxy.kt deleted file mode 100644 index 4d2dde78..00000000 --- a/app/src/main/java/io/github/wulkanowy/utils/WebkitCookieManagerProxy.kt +++ /dev/null @@ -1,74 +0,0 @@ -package io.github.wulkanowy.utils - -import android.util.AndroidRuntimeException -import java.net.CookiePolicy -import java.net.CookieStore -import java.net.HttpCookie -import java.net.URI -import javax.inject.Inject -import javax.inject.Singleton -import android.webkit.CookieManager as WebkitCookieManager -import java.net.CookieManager as JavaCookieManager - -@Singleton -class WebkitCookieManagerProxy @Inject constructor() : - JavaCookieManager(null, CookiePolicy.ACCEPT_ALL) { - - val webkitCookieManager: WebkitCookieManager? = getCookieManager() - - /** - * @see [https://stackoverflow.com/a/70354583/6695449] - */ - private fun getCookieManager(): WebkitCookieManager? { - return try { - WebkitCookieManager.getInstance() - } catch (e: AndroidRuntimeException) { - null - } - } - - override fun put(uri: URI?, responseHeaders: Map>?) { - if (uri == null || responseHeaders == null) return - val url = uri.toString() - for (headerKey in responseHeaders.keys) { - if (headerKey == null || !( - headerKey.equals("Set-Cookie2", ignoreCase = true) || - headerKey.equals("Set-Cookie", ignoreCase = true) - ) - ) continue - - // process each of the headers - for (headerValue in responseHeaders[headerKey].orEmpty()) { - webkitCookieManager?.setCookie(url, headerValue) - } - } - } - - override operator fun get( - uri: URI?, - requestHeaders: Map?>? - ): Map> { - require(!(uri == null || requestHeaders == null)) { "Argument is null" } - val res = mutableMapOf>() - val cookie = webkitCookieManager?.getCookie(uri.toString()) - if (cookie != null) res["Cookie"] = listOf(cookie) - return res - } - - override fun getCookieStore(): CookieStore { - val cookies = super.getCookieStore() - return object : CookieStore { - override fun add(uri: URI?, cookie: HttpCookie?) = cookies.add(uri, cookie) - override fun get(uri: URI?): List = cookies.get(uri) - override fun getCookies(): List = cookies.cookies - override fun getURIs(): List = cookies.urIs - override fun remove(uri: URI?, cookie: HttpCookie?): Boolean = - cookies.remove(uri, cookie) - - override fun removeAll(): Boolean { - webkitCookieManager?.removeAllCookies(null) ?: return false - return true - } - } - } -} diff --git a/app/src/main/java/io/github/wulkanowy/utils/security/Scrambler.kt b/app/src/main/java/io/github/wulkanowy/utils/security/Scrambler.kt index db16a256..264f4542 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/security/Scrambler.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/security/Scrambler.kt @@ -2,8 +2,10 @@ package io.github.wulkanowy.utils.security +import android.annotation.TargetApi import android.content.Context import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.JELLY_BEAN_MR2 import android.os.Build.VERSION_CODES.M import android.security.KeyPairGeneratorSpec import android.security.keystore.KeyGenParameterSpec @@ -16,7 +18,6 @@ import android.util.Base64.DEFAULT import android.util.Base64.decode import android.util.Base64.encode import android.util.Base64.encodeToString -import dagger.hilt.android.qualifiers.ApplicationContext import timber.log.Timber import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream @@ -34,124 +35,114 @@ import javax.crypto.CipherInputStream import javax.crypto.CipherOutputStream import javax.crypto.spec.OAEPParameterSpec import javax.crypto.spec.PSource.PSpecified -import javax.inject.Inject -import javax.inject.Singleton import javax.security.auth.x500.X500Principal -@Singleton -class Scrambler @Inject constructor( - @ApplicationContext private val context: Context, -) { - private val keyCharset = Charset.forName("UTF-8") +private const val KEYSTORE_NAME = "AndroidKeyStore" - private val isKeyPairExists: Boolean - get() = keyStore.getKey(KEY_ALIAS, null) != null +private const val KEY_ALIAS = "wulkanowy_password" - private val keyStore: KeyStore - get() = KeyStore.getInstance(KEYSTORE_NAME).apply { load(null) } +private val KEY_CHARSET = Charset.forName("UTF-8") - private val cipher: Cipher - get() { - return if (SDK_INT >= M) Cipher.getInstance( - "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", - "AndroidKeyStoreBCWorkaround" - ) - else Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL") - } +private val isKeyPairExists: Boolean + get() = keyStore.getKey(KEY_ALIAS, null) != null - fun encrypt(plainText: String): String { - if (plainText.isEmpty()) throw ScramblerException("Text to be encrypted is empty") +private val keyStore: KeyStore + get() = KeyStore.getInstance(KEYSTORE_NAME).apply { load(null) } - return try { - if (!isKeyPairExists) generateKeyPair() +private val cipher: Cipher + get() { + return if (SDK_INT >= M) Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", "AndroidKeyStoreBCWorkaround") + else Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL") + } - cipher.let { - if (SDK_INT >= M) { - OAEPParameterSpec("SHA-256", "MGF1", SHA1, PSpecified.DEFAULT).let { spec -> - it.init(ENCRYPT_MODE, keyStore.getCertificate(KEY_ALIAS).publicKey, spec) - } - } else it.init(ENCRYPT_MODE, keyStore.getCertificate(KEY_ALIAS).publicKey) +fun encrypt(plainText: String, context: Context): String { + if (plainText.isEmpty()) throw ScramblerException("Text to be encrypted is empty") - ByteArrayOutputStream().let { output -> - CipherOutputStream(output, it).apply { - write(plainText.toByteArray(keyCharset)) - close() - } - encodeToString(output.toByteArray(), DEFAULT) + if (SDK_INT < JELLY_BEAN_MR2) { + return String(encode(plainText.toByteArray(KEY_CHARSET), DEFAULT), KEY_CHARSET) + } + + return try { + if (!isKeyPairExists) generateKeyPair(context) + + cipher.let { + if (SDK_INT >= M) { + OAEPParameterSpec("SHA-256", "MGF1", SHA1, PSpecified.DEFAULT).let { spec -> + it.init(ENCRYPT_MODE, keyStore.getCertificate(KEY_ALIAS).publicKey, spec) } - } - } catch (exception: Exception) { - Timber.e(exception, "An error occurred while encrypting text") - String(encode(plainText.toByteArray(keyCharset), DEFAULT), keyCharset) - } - } + } else it.init(ENCRYPT_MODE, keyStore.getCertificate(KEY_ALIAS).publicKey) - fun decrypt(cipherText: String): String { - if (cipherText.isEmpty()) throw ScramblerException("Text to be encrypted is empty") - - return try { - if (!isKeyPairExists) throw ScramblerException("KeyPair doesn't exist") - - cipher.let { - if (SDK_INT >= M) { - OAEPParameterSpec("SHA-256", "MGF1", SHA1, PSpecified.DEFAULT).let { spec -> - it.init(DECRYPT_MODE, keyStore.getKey(KEY_ALIAS, null), spec) - } - } else it.init(DECRYPT_MODE, keyStore.getKey(KEY_ALIAS, null)) - - CipherInputStream( - ByteArrayInputStream(decode(cipherText, DEFAULT)), - it - ).let { input -> - val values = ArrayList() - var nextByte: Int - while (run { nextByte = input.read(); nextByte } != -1) { - values.add(nextByte.toByte()) - } - val bytes = ByteArray(values.size) - for (i in bytes.indices) { - bytes[i] = values[i] - } - String(bytes, 0, bytes.size, keyCharset) + ByteArrayOutputStream().let { output -> + CipherOutputStream(output, it).apply { + write(plainText.toByteArray(KEY_CHARSET)) + close() } - } - } catch (e: Exception) { - throw ScramblerException("An error occurred while decrypting text", e) - } - } - - private fun generateKeyPair() { - (if (SDK_INT >= M) { - KeyGenParameterSpec.Builder(KEY_ALIAS, PURPOSE_DECRYPT or PURPOSE_ENCRYPT) - .setDigests(DIGEST_SHA256, DIGEST_SHA512) - .setEncryptionPaddings(ENCRYPTION_PADDING_RSA_OAEP) - .setCertificateSerialNumber(BigInteger.TEN) - .setCertificateSubject(X500Principal("CN=Wulkanowy")) - .build() - } else { - KeyPairGeneratorSpec.Builder(context) - .setAlias(KEY_ALIAS) - .setSubject(X500Principal("CN=Wulkanowy")) - .setSerialNumber(BigInteger.TEN) - .setStartDate(Calendar.getInstance().time) - .setEndDate(Calendar.getInstance().apply { add(YEAR, 99) }.time) - .build() - }).let { - KeyPairGenerator.getInstance("RSA", KEYSTORE_NAME).apply { - initialize(it) - genKeyPair() + encodeToString(output.toByteArray(), DEFAULT) } } - Timber.i("A new KeyPair has been generated") - } - - fun clearKeyPair() { - keyStore.deleteEntry(KEY_ALIAS) - Timber.i("KeyPair has been cleared") - } - - private companion object { - private const val KEYSTORE_NAME = "AndroidKeyStore" - private const val KEY_ALIAS = "wulkanowy_password" + } catch (exception: Exception) { + Timber.e(exception, "An error occurred while encrypting text") + String(encode(plainText.toByteArray(KEY_CHARSET), DEFAULT), KEY_CHARSET) } } + +fun decrypt(cipherText: String): String { + if (cipherText.isEmpty()) throw ScramblerException("Text to be encrypted is empty") + + return try { + if (SDK_INT < JELLY_BEAN_MR2 || cipherText.length < 250) { + return String(decode(cipherText.toByteArray(KEY_CHARSET), DEFAULT), KEY_CHARSET) + } + + if (!isKeyPairExists) throw ScramblerException("KeyPair doesn't exist") + + cipher.let { + if (SDK_INT >= M) { + OAEPParameterSpec("SHA-256", "MGF1", SHA1, PSpecified.DEFAULT).let { spec -> + it.init(DECRYPT_MODE, keyStore.getKey(KEY_ALIAS, null), spec) + } + } else it.init(DECRYPT_MODE, keyStore.getKey(KEY_ALIAS, null)) + + CipherInputStream(ByteArrayInputStream(decode(cipherText, DEFAULT)), it).let { input -> + val values = ArrayList() + var nextByte = 0 + while ({ nextByte = input.read(); nextByte }() != -1) { + values.add(nextByte.toByte()) + } + val bytes = ByteArray(values.size) + for (i in bytes.indices) { + bytes[i] = values[i] + } + String(bytes, 0, bytes.size, KEY_CHARSET) + } + } + } catch (e: Exception) { + throw ScramblerException("An error occurred while decrypting text", e) + } +} + +@TargetApi(JELLY_BEAN_MR2) +private fun generateKeyPair(context: Context) { + (if (SDK_INT >= M) { + KeyGenParameterSpec.Builder(KEY_ALIAS, PURPOSE_DECRYPT or PURPOSE_ENCRYPT) + .setDigests(DIGEST_SHA256, DIGEST_SHA512) + .setEncryptionPaddings(ENCRYPTION_PADDING_RSA_OAEP) + .setCertificateSerialNumber(BigInteger.TEN) + .setCertificateSubject(X500Principal("CN=Wulkanowy")) + .build() + } else { + KeyPairGeneratorSpec.Builder(context) + .setAlias(KEY_ALIAS) + .setSubject(X500Principal("CN=Wulkanowy")) + .setSerialNumber(BigInteger.TEN) + .setStartDate(Calendar.getInstance().time) + .setEndDate(Calendar.getInstance().apply { add(YEAR, 99) }.time) + .build() + }).let { + KeyPairGenerator.getInstance("RSA", KEYSTORE_NAME).apply { + initialize(it) + genKeyPair() + } + } + Timber.i("A new KeyPair has been generated") +} diff --git a/app/src/main/play/listings/cs-CZ/full-description.txt b/app/src/main/play/listings/cs-CZ/full-description.txt deleted file mode 100644 index 3d142ebf..00000000 --- a/app/src/main/play/listings/cs-CZ/full-description.txt +++ /dev/null @@ -1,14 +0,0 @@ -Aplikace je určena pro uživatele deníku VULCAN UONET+. - -Zvýrazněné vlastnosti a funkce: -- výpočet váženého průměru, -- procentuální zobrazení docházky, -- šťastné číslo, -- náhled na další a dokončené lekce, -- tmavý motiv, -- volitelné reklamy, -- offline režim, -- upozornění. - -GitHub: https://github.com/wulkanowy/wulkanowy -Discord: https://discord.gg/vccAQBr diff --git a/app/src/main/play/listings/cs-CZ/short-description.txt b/app/src/main/play/listings/cs-CZ/short-description.txt deleted file mode 100644 index 0f29ab1b..00000000 --- a/app/src/main/play/listings/cs-CZ/short-description.txt +++ /dev/null @@ -1 +0,0 @@ -Neoficiální aplikace žáka a rodiče pro deníku VULCAN UONET+ diff --git a/app/src/main/play/listings/cs-CZ/title.txt b/app/src/main/play/listings/cs-CZ/title.txt deleted file mode 100644 index b7f42a5b..00000000 --- a/app/src/main/play/listings/cs-CZ/title.txt +++ /dev/null @@ -1 +0,0 @@ -Wulkanowy Deníček diff --git a/app/src/main/play/listings/pl-PL/full-description.txt b/app/src/main/play/listings/pl-PL/full-description.txt index b0193b5d..641b7706 100644 --- a/app/src/main/play/listings/pl-PL/full-description.txt +++ b/app/src/main/play/listings/pl-PL/full-description.txt @@ -4,9 +4,9 @@ Wyróżnione cechy i funkcje: - obliczanie średniej ważonej, - procentowy podgląd frekwencji, - szczęśliwy numerek, -- podgląd lekcji dodatkowych i zrealizowanych, +- podgląd lekcji zrealizowanych, - ciemny motyw. -- opcjonalne reklam, +- brak reklam, - tryb offline, - powiadomienia. diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-grades.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-grades.png new file mode 100644 index 00000000..56768bf5 Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-grades.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-start.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-start.jpg deleted file mode 100644 index 19b96d9a..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/1-start.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2-timetable-dialog.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2-timetable-dialog.png new file mode 100644 index 00000000..83d9353a Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2-timetable-dialog.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2.jpg deleted file mode 100644 index fe81aadc..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/2.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-exams.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-exams.png new file mode 100644 index 00000000..f83a7af8 Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-exams.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-timetable-dialog.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-timetable-dialog.jpg deleted file mode 100644 index 0e62c2e1..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/3-timetable-dialog.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-exams.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-exams.jpg deleted file mode 100644 index 980993af..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-exams.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-timetable-widget.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-timetable-widget.png new file mode 100644 index 00000000..90d5fef4 Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/4-timetable-widget.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-messages.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-messages.png new file mode 100644 index 00000000..eadbf2db Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-messages.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-timetable-widget.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-timetable-widget.jpg deleted file mode 100644 index 6ee7eeb9..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/5-timetable-widget.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-account-switcher.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-account-switcher.png new file mode 100644 index 00000000..2a11a3db Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-account-switcher.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-class-grades.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-class-grades.jpg deleted file mode 100644 index ec86cdb0..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/6-class-grades.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-account-switcher.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-account-switcher.jpg deleted file mode 100644 index 66c0db40..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-account-switcher.jpg and /dev/null differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-class-grades.png b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-class-grades.png new file mode 100644 index 00000000..d9b2f1c7 Binary files /dev/null and b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/7-class-grades.png differ diff --git a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/8-themes.jpg b/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/8-themes.jpg deleted file mode 100644 index 94788cd7..00000000 Binary files a/app/src/main/play/listings/pl-PL/graphics/phone-screenshots/8-themes.jpg and /dev/null differ diff --git a/app/src/main/play/listings/sk/full-description.txt b/app/src/main/play/listings/sk/full-description.txt deleted file mode 100644 index 23682598..00000000 --- a/app/src/main/play/listings/sk/full-description.txt +++ /dev/null @@ -1,14 +0,0 @@ -Aplikácia je určená pre užívateľov denníka VULCAN UONET+. - -Zvýraznené vlastnosti a funkcie: -- výpočet váženého priemeru, -- percentuálne zobrazenie dochádzky, -- šťastné číslo, -- náhľad na ďalšie a dokončené lekcie, -- tmavý motív, -- voliteľné reklamy, -- offline režim, -- upozornenia. - -GitHub: https://github.com/wulkanowy/wulkanowy -Discord: https://discord.gg/vccAQBr diff --git a/app/src/main/play/listings/sk/short-description.txt b/app/src/main/play/listings/sk/short-description.txt deleted file mode 100644 index 645ebbb6..00000000 --- a/app/src/main/play/listings/sk/short-description.txt +++ /dev/null @@ -1 +0,0 @@ -Neoficiálna aplikácia žiaka a rodiča pre denníka VULCAN UONET+ diff --git a/app/src/main/play/listings/sk/title.txt b/app/src/main/play/listings/sk/title.txt deleted file mode 100644 index aa50ce77..00000000 --- a/app/src/main/play/listings/sk/title.txt +++ /dev/null @@ -1 +0,0 @@ -Wulkanowy Denníček diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt index 889591fa..908a97d5 100644 --- a/app/src/main/play/release-notes/pl-PL/default.txt +++ b/app/src/main/play/release-notes/pl-PL/default.txt @@ -1,6 +1,5 @@ -Wersja 2.6.8 - -— i znowu aktualizacja, żeby wiadomości działały chociaż w piątek. Później już pewnie nie będą -— a i jeszcze naprawiliśmy dostęp mobilny, bo prosiliście +Wersja 0.23.1 +- naprawiliśmy opis pola na email/login przy wyborze niestandardowych dzienników +- naprawiliśmy obsługę dziennika lubelskiego i koszalińskiego na starszych urządzeniach (z Androidem 5 i starszymi) Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases diff --git a/app/src/main/res/drawable/ic_stat_grade.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_grade.xml similarity index 100% rename from app/src/main/res/drawable/ic_stat_grade.xml rename to app/src/main/res/drawable-anydpi-v24/ic_stat_grade.xml diff --git a/app/src/main/res/drawable/ic_stat_luckynumber.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml similarity index 100% rename from app/src/main/res/drawable/ic_stat_luckynumber.xml rename to app/src/main/res/drawable-anydpi-v24/ic_stat_luckynumber.xml diff --git a/app/src/main/res/drawable/ic_stat_message.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml similarity index 100% rename from app/src/main/res/drawable/ic_stat_message.xml rename to app/src/main/res/drawable-anydpi-v24/ic_stat_message.xml diff --git a/app/src/main/res/drawable/ic_stat_note.xml b/app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml similarity index 100% rename from app/src/main/res/drawable/ic_stat_note.xml rename to app/src/main/res/drawable-anydpi-v24/ic_stat_note.xml diff --git a/app/src/main/res/drawable-hdpi/ic_stat_grade.png b/app/src/main/res/drawable-hdpi/ic_stat_grade.png new file mode 100644 index 00000000..d97efb5d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_grade.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_luckynumber.png b/app/src/main/res/drawable-hdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..b91c4ae6 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_luckynumber.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_message.png b/app/src/main/res/drawable-hdpi/ic_stat_message.png new file mode 100644 index 00000000..ce0fdabc Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_message.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_note.png b/app/src/main/res/drawable-hdpi/ic_stat_note.png new file mode 100644 index 00000000..7318c419 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_note.png differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_all.png b/app/src/main/res/drawable-hdpi/ic_stat_push.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_stat_all.png rename to app/src/main/res/drawable-hdpi/ic_stat_push.png diff --git a/app/src/main/res/drawable-hdpi/ic_stat_timetable.png b/app/src/main/res/drawable-hdpi/ic_stat_timetable.png new file mode 100644 index 00000000..201419d5 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_stat_timetable.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_grade.png b/app/src/main/res/drawable-mdpi/ic_stat_grade.png new file mode 100644 index 00000000..c85b2702 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_grade.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_luckynumber.png b/app/src/main/res/drawable-mdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..bfced4eb Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_luckynumber.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_message.png b/app/src/main/res/drawable-mdpi/ic_stat_message.png new file mode 100644 index 00000000..b357b321 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_message.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_note.png b/app/src/main/res/drawable-mdpi/ic_stat_note.png new file mode 100644 index 00000000..55a4fbbf Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_note.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_all.png b/app/src/main/res/drawable-mdpi/ic_stat_push.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_stat_all.png rename to app/src/main/res/drawable-mdpi/ic_stat_push.png diff --git a/app/src/main/res/drawable-mdpi/ic_stat_timetable.png b/app/src/main/res/drawable-mdpi/ic_stat_timetable.png new file mode 100644 index 00000000..dcfe95f2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_stat_timetable.png differ diff --git a/app/src/main/res/drawable-night/background_header_note.xml b/app/src/main/res/drawable-night/background_header_note.xml new file mode 100644 index 00000000..6b594e7c --- /dev/null +++ b/app/src/main/res/drawable-night/background_header_note.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable-night/ic_all_divider.xml b/app/src/main/res/drawable-night/ic_all_divider.xml new file mode 100644 index 00000000..cd444a28 --- /dev/null +++ b/app/src/main/res/drawable-night/ic_all_divider.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/drawable-v23/compat_splash_screen_no_icon_background.xml b/app/src/main/res/drawable-v23/compat_splash_screen_no_icon_background.xml deleted file mode 100644 index dad56a17..00000000 --- a/app/src/main/res/drawable-v23/compat_splash_screen_no_icon_background.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable-v23/img_splash_logo.png b/app/src/main/res/drawable-v23/img_splash_logo.png new file mode 100644 index 00000000..61489d81 Binary files /dev/null and b/app/src/main/res/drawable-v23/img_splash_logo.png differ diff --git a/app/src/main/res/drawable-v23/layer_splash_background.xml b/app/src/main/res/drawable-v23/layer_splash_background.xml new file mode 100644 index 00000000..1b4b64ec --- /dev/null +++ b/app/src/main/res/drawable-v23/layer_splash_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_grade.png b/app/src/main/res/drawable-xhdpi/ic_stat_grade.png new file mode 100644 index 00000000..c55ca7fd Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_grade.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_luckynumber.png b/app/src/main/res/drawable-xhdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..49e502ac Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_luckynumber.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_message.png b/app/src/main/res/drawable-xhdpi/ic_stat_message.png new file mode 100644 index 00000000..0e67ade3 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_message.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_note.png b/app/src/main/res/drawable-xhdpi/ic_stat_note.png new file mode 100644 index 00000000..ea674a79 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_note.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_all.png b/app/src/main/res/drawable-xhdpi/ic_stat_push.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_stat_all.png rename to app/src/main/res/drawable-xhdpi/ic_stat_push.png diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_timetable.png b/app/src/main/res/drawable-xhdpi/ic_stat_timetable.png new file mode 100644 index 00000000..7264bd92 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_stat_timetable.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_grade.png b/app/src/main/res/drawable-xxhdpi/ic_stat_grade.png new file mode 100644 index 00000000..eeb6fa41 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_grade.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_luckynumber.png b/app/src/main/res/drawable-xxhdpi/ic_stat_luckynumber.png new file mode 100644 index 00000000..9bab1373 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_luckynumber.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_message.png b/app/src/main/res/drawable-xxhdpi/ic_stat_message.png new file mode 100644 index 00000000..2e881824 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_message.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_note.png b/app/src/main/res/drawable-xxhdpi/ic_stat_note.png new file mode 100644 index 00000000..174e1509 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_note.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_all.png b/app/src/main/res/drawable-xxhdpi/ic_stat_push.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_stat_all.png rename to app/src/main/res/drawable-xxhdpi/ic_stat_push.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_timetable.png b/app/src/main/res/drawable-xxhdpi/ic_stat_timetable.png new file mode 100644 index 00000000..1fb37b09 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_stat_timetable.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_all.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_push.png similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/ic_stat_all.png rename to app/src/main/res/drawable-xxxhdpi/ic_stat_push.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_timetable.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_timetable.png new file mode 100644 index 00000000..a95cc4f5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_stat_timetable.png differ diff --git a/app/src/main/res/drawable/background_grade_details_rounded.xml b/app/src/main/res/drawable/background_grade_details_rounded.xml deleted file mode 100644 index e24088a0..00000000 --- a/app/src/main/res/drawable/background_grade_details_rounded.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_grade_details_weight_rounded.xml b/app/src/main/res/drawable/background_grade_details_weight_rounded.xml deleted file mode 100644 index 4b210912..00000000 --- a/app/src/main/res/drawable/background_grade_details_weight_rounded.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_grade_rounded.xml b/app/src/main/res/drawable/background_grade_rounded.xml deleted file mode 100644 index 52c10c2f..00000000 --- a/app/src/main/res/drawable/background_grade_rounded.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_grade_small_rounded.xml b/app/src/main/res/drawable/background_grade_small_rounded.xml deleted file mode 100644 index dd50417f..00000000 --- a/app/src/main/res/drawable/background_grade_small_rounded.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_header_note.xml b/app/src/main/res/drawable/background_header_note.xml index 8cf84a1c..c21e55c6 100644 --- a/app/src/main/res/drawable/background_header_note.xml +++ b/app/src/main/res/drawable/background_header_note.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/drawable/background_luckynumber_widget_button.xml b/app/src/main/res/drawable/background_luckynumber_widget.xml similarity index 62% rename from app/src/main/res/drawable/background_luckynumber_widget_button.xml rename to app/src/main/res/drawable/background_luckynumber_widget.xml index 66b1685f..f29744d0 100644 --- a/app/src/main/res/drawable/background_luckynumber_widget_button.xml +++ b/app/src/main/res/drawable/background_luckynumber_widget.xml @@ -1,6 +1,6 @@ - - + + diff --git a/app/src/main/res/drawable/background_luckynumber_widget_dark.xml b/app/src/main/res/drawable/background_luckynumber_widget_dark.xml new file mode 100644 index 00000000..fa15fd85 --- /dev/null +++ b/app/src/main/res/drawable/background_luckynumber_widget_dark.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/background_material_alert_dialog.xml b/app/src/main/res/drawable/background_material_alert_dialog.xml deleted file mode 100644 index 5ab8a350..00000000 --- a/app/src/main/res/drawable/background_material_alert_dialog.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/background_timetable_widget_avatar.xml b/app/src/main/res/drawable/background_timetable_widget_avatar.xml deleted file mode 100644 index 48298d67..00000000 --- a/app/src/main/res/drawable/background_timetable_widget_avatar.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_widget_item_timetable.xml b/app/src/main/res/drawable/background_widget_item_timetable.xml deleted file mode 100644 index 510c70c0..00000000 --- a/app/src/main/res/drawable/background_widget_item_timetable.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/background_widget_timetable.xml b/app/src/main/res/drawable/background_widget_timetable.xml deleted file mode 100644 index b589ad29..00000000 --- a/app/src/main/res/drawable/background_widget_timetable.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/ic_all_home.xml b/app/src/main/res/drawable/ic_about_homepage.xml similarity index 100% rename from app/src/main/res/drawable/ic_all_home.xml rename to app/src/main/res/drawable/ic_about_homepage.xml diff --git a/app/src/main/res/drawable/ic_about_twitter.xml b/app/src/main/res/drawable/ic_about_twitter.xml deleted file mode 100644 index 7b7cf6d5..00000000 --- a/app/src/main/res/drawable/ic_about_twitter.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_account_details_family.xml b/app/src/main/res/drawable/ic_account_details_family.xml deleted file mode 100644 index 363b4f58..00000000 --- a/app/src/main/res/drawable/ic_account_details_family.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_all_about.xml b/app/src/main/res/drawable/ic_all_about.xml index 3868f85c..3dfbbda1 100644 --- a/app/src/main/res/drawable/ic_all_about.xml +++ b/app/src/main/res/drawable/ic_all_about.xml @@ -2,7 +2,6 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:tint="?colorOnSurface" android:viewportHeight="24"> - - - diff --git a/app/src/main/res/drawable/ic_all_divider.xml b/app/src/main/res/drawable/ic_all_divider.xml index 922882c2..61e96497 100644 --- a/app/src/main/res/drawable/ic_all_divider.xml +++ b/app/src/main/res/drawable/ic_all_divider.xml @@ -1,5 +1,9 @@ - + diff --git a/app/src/main/res/drawable/ic_all_round_check.xml b/app/src/main/res/drawable/ic_all_round_check.xml deleted file mode 100644 index aecaf234..00000000 --- a/app/src/main/res/drawable/ic_all_round_check.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_auth_success.xml b/app/src/main/res/drawable/ic_auth_success.xml deleted file mode 100644 index 015553c0..00000000 --- a/app/src/main/res/drawable/ic_auth_success.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_calendar_all.xml b/app/src/main/res/drawable/ic_calendar_all.xml deleted file mode 100644 index 5908035e..00000000 --- a/app/src/main/res/drawable/ic_calendar_all.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chevron_left.xml b/app/src/main/res/drawable/ic_chevron_left.xml index 4250fae4..ee3ff4be 100644 --- a/app/src/main/res/drawable/ic_chevron_left.xml +++ b/app/src/main/res/drawable/ic_chevron_left.xml @@ -1,10 +1,5 @@ - - + + diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml index de5037cf..a6d73497 100644 --- a/app/src/main/res/drawable/ic_chevron_right.xml +++ b/app/src/main/res/drawable/ic_chevron_right.xml @@ -1,10 +1,5 @@ - - + + diff --git a/app/src/main/res/drawable/ic_circle.xml b/app/src/main/res/drawable/ic_circle.xml deleted file mode 100644 index d2932fe6..00000000 --- a/app/src/main/res/drawable/ic_circle.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_circle_notification.xml b/app/src/main/res/drawable/ic_circle_notification.xml deleted file mode 100644 index 6059212c..00000000 --- a/app/src/main/res/drawable/ic_circle_notification.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml deleted file mode 100644 index 1d6c0046..00000000 --- a/app/src/main/res/drawable/ic_close.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_dashboard_warning.xml b/app/src/main/res/drawable/ic_dashboard_warning.xml deleted file mode 100644 index e7a5dc5a..00000000 --- a/app/src/main/res/drawable/ic_dashboard_warning.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_error_filled.xml b/app/src/main/res/drawable/ic_error_filled.xml deleted file mode 100644 index 61b575dc..00000000 --- a/app/src/main/res/drawable/ic_error_filled.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_help.xml b/app/src/main/res/drawable/ic_help.xml deleted file mode 100644 index 9c6ba292..00000000 --- a/app/src/main/res/drawable/ic_help.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_history.xml b/app/src/main/res/drawable/ic_history.xml deleted file mode 100644 index f20e2094..00000000 --- a/app/src/main/res/drawable/ic_history.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml deleted file mode 100644 index b1b01a0b..00000000 --- a/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/drawable/ic_launcher_foreground_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_mono.xml deleted file mode 100644 index e2e74731..00000000 --- a/app/src/main/res/drawable/ic_launcher_foreground_mono.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_login.xml b/app/src/main/res/drawable/ic_login.xml deleted file mode 100644 index 57aef3dc..00000000 --- a/app/src/main/res/drawable/ic_login.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_main_dashboard.xml b/app/src/main/res/drawable/ic_main_dashboard.xml deleted file mode 100644 index ed226925..00000000 --- a/app/src/main/res/drawable/ic_main_dashboard.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_main_timetable.xml b/app/src/main/res/drawable/ic_main_timetable.xml index e33aae16..b8f5cb85 100644 --- a/app/src/main/res/drawable/ic_main_timetable.xml +++ b/app/src/main/res/drawable/ic_main_timetable.xml @@ -5,5 +5,5 @@ android:viewportHeight="24"> + android:pathData="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,9h14v10zM5,7L5,5h14v2L5,7zM7,11h10v2L7,13zM7,15h7v2L7,17z" /> diff --git a/app/src/main/res/drawable/ic_menu_attendance_calculator.xml b/app/src/main/res/drawable/ic_menu_attendance_calculator.xml deleted file mode 100644 index 8a7d209a..00000000 --- a/app/src/main/res/drawable/ic_menu_attendance_calculator.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_menu_message_delete_forever.xml b/app/src/main/res/drawable/ic_menu_message_delete_forever.xml deleted file mode 100644 index a7b5ac53..00000000 --- a/app/src/main/res/drawable/ic_menu_message_delete_forever.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_menu_message_restore.xml b/app/src/main/res/drawable/ic_menu_message_restore.xml deleted file mode 100644 index 5c8544f2..00000000 --- a/app/src/main/res/drawable/ic_menu_message_restore.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_menu_order_drag.xml b/app/src/main/res/drawable/ic_menu_order_drag.xml deleted file mode 100644 index 623c67d2..00000000 --- a/app/src/main/res/drawable/ic_menu_order_drag.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_menu_timetable_lessons_additional.xml b/app/src/main/res/drawable/ic_menu_timetable_lessons_additional.xml deleted file mode 100644 index ddb6d2f5..00000000 --- a/app/src/main/res/drawable/ic_menu_timetable_lessons_additional.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_message_select_all.xml b/app/src/main/res/drawable/ic_message_select_all.xml deleted file mode 100644 index eab195d9..00000000 --- a/app/src/main/res/drawable/ic_message_select_all.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/ic_message_unselect_all.xml b/app/src/main/res/drawable/ic_message_unselect_all.xml deleted file mode 100644 index c388522e..00000000 --- a/app/src/main/res/drawable/ic_message_unselect_all.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_more_conferences.xml b/app/src/main/res/drawable/ic_more_conferences.xml index 65d6b6e8..87be8e05 100644 --- a/app/src/main/res/drawable/ic_more_conferences.xml +++ b/app/src/main/res/drawable/ic_more_conferences.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_notifications_off.xml b/app/src/main/res/drawable/ic_notifications_off.xml deleted file mode 100644 index 094ed75f..00000000 --- a/app/src/main/res/drawable/ic_notifications_off.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_scale_balance.xml b/app/src/main/res/drawable/ic_scale_balance.xml deleted file mode 100644 index c65467a6..00000000 --- a/app/src/main/res/drawable/ic_scale_balance.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_all_phone.xml b/app/src/main/res/drawable/ic_school_phone.xml similarity index 100% rename from app/src/main/res/drawable/ic_all_phone.xml rename to app/src/main/res/drawable/ic_school_phone.xml diff --git a/app/src/main/res/drawable/ic_settings_ads.xml b/app/src/main/res/drawable/ic_settings_ads.xml deleted file mode 100644 index c333ea76..00000000 --- a/app/src/main/res/drawable/ic_settings_ads.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_settings_advanced.xml b/app/src/main/res/drawable/ic_settings_advanced.xml deleted file mode 100644 index 2fd7e590..00000000 --- a/app/src/main/res/drawable/ic_settings_advanced.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_settings_appearance.xml b/app/src/main/res/drawable/ic_settings_appearance.xml deleted file mode 100644 index afea27f2..00000000 --- a/app/src/main/res/drawable/ic_settings_appearance.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_settings_notifications.xml b/app/src/main/res/drawable/ic_settings_notifications.xml deleted file mode 100644 index f4ff247f..00000000 --- a/app/src/main/res/drawable/ic_settings_notifications.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_settings_sync.xml b/app/src/main/res/drawable/ic_settings_sync.xml deleted file mode 100644 index 3697ac0b..00000000 --- a/app/src/main/res/drawable/ic_settings_sync.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_splash_logo.xml b/app/src/main/res/drawable/ic_splash_logo.xml deleted file mode 100644 index e2e74731..00000000 --- a/app/src/main/res/drawable/ic_splash_logo.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_stat_timetable.xml b/app/src/main/res/drawable/ic_stat_timetable.xml deleted file mode 100644 index 9efc0348..00000000 --- a/app/src/main/res/drawable/ic_stat_timetable.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/ic_timetable_widget_swap.xml b/app/src/main/res/drawable/ic_timetable_widget_swap.xml deleted file mode 100644 index 09c50b4f..00000000 --- a/app/src/main/res/drawable/ic_timetable_widget_swap.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_widget_chevron.png b/app/src/main/res/drawable/ic_widget_chevron.png new file mode 100644 index 00000000..34345521 Binary files /dev/null and b/app/src/main/res/drawable/ic_widget_chevron.png differ diff --git a/app/src/main/res/drawable/ic_widget_chevron.xml b/app/src/main/res/drawable/ic_widget_chevron.xml deleted file mode 100644 index 871aca9b..00000000 --- a/app/src/main/res/drawable/ic_widget_chevron.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/img_luckynumber_widget_preview.png b/app/src/main/res/drawable/img_luckynumber_widget_preview.png index 26701855..539b0a59 100644 Binary files a/app/src/main/res/drawable/img_luckynumber_widget_preview.png and b/app/src/main/res/drawable/img_luckynumber_widget_preview.png differ diff --git a/app/src/main/res/drawable/img_splash_logo.png b/app/src/main/res/drawable/img_splash_logo.png new file mode 100644 index 00000000..fb521bf6 Binary files /dev/null and b/app/src/main/res/drawable/img_splash_logo.png differ diff --git a/app/src/main/res/drawable/img_timetable_widget_preview.png b/app/src/main/res/drawable/img_timetable_widget_preview.png index 5c1752cb..55026025 100644 Binary files a/app/src/main/res/drawable/img_timetable_widget_preview.png and b/app/src/main/res/drawable/img_timetable_widget_preview.png differ diff --git a/app/src/main/res/drawable/layer_splash_background.xml b/app/src/main/res/drawable/layer_splash_background.xml new file mode 100644 index 00000000..2cf46d1d --- /dev/null +++ b/app/src/main/res/drawable/layer_splash_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/shape_badge.xml b/app/src/main/res/drawable/shape_badge.xml deleted file mode 100644 index 3153f592..00000000 --- a/app/src/main/res/drawable/shape_badge.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout-v31/widget_timetable_preview.xml b/app/src/main/res/layout-v31/widget_timetable_preview.xml deleted file mode 100644 index 2c47836c..00000000 --- a/app/src/main/res/layout-v31/widget_timetable_preview.xml +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 91279263..3841b25c 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -1,20 +1,17 @@ + android:layout_height="wrap_content" /> - - + android:layout_height="match_parent" /> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index a9284234..2f88ecc8 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,44 +1,28 @@ - - - - + app:contentInsetStartWithNavigation="0dp" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintBottom_toTopOf="@id/mainBottomNav" + app:layout_constraintTop_toBottomOf="@id/mainToolbar" /> - - - diff --git a/app/src/main/res/layout/activity_send_message.xml b/app/src/main/res/layout/activity_send_message.xml index e50cf6b3..e0ec52bb 100644 --- a/app/src/main/res/layout/activity_send_message.xml +++ b/app/src/main/res/layout/activity_send_message.xml @@ -7,30 +7,31 @@ android:layout_height="match_parent" android:orientation="vertical"> - - - - + android:elevation="4dp" + app:layout_constraintBottom_toTopOf="@id/sendMessageScroll" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:targetApi="lollipop" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/sendMessageToolbar"> + android:layout_height="match_parent"> - - - + app:layout_constraintTop_toBottomOf="@id/sendMessageToolbar" /> diff --git a/app/src/main/res/layout/dialog_account_quick.xml b/app/src/main/res/layout/dialog_account.xml similarity index 58% rename from app/src/main/res/layout/dialog_account_quick.xml rename to app/src/main/res/layout/dialog_account.xml index d8be4842..d56de3a2 100644 --- a/app/src/main/res/layout/dialog_account_quick.xml +++ b/app/src/main/res/layout/dialog_account.xml @@ -2,30 +2,29 @@ + android:orientation="vertical"> + android:text="@string/account_add_new" + android:textColor="?android:textColorPrimary" /> + + + + diff --git a/app/src/main/res/layout/dialog_account_edit.xml b/app/src/main/res/layout/dialog_account_edit.xml deleted file mode 100644 index ec5f93a6..00000000 --- a/app/src/main/res/layout/dialog_account_edit.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_additional_add.xml b/app/src/main/res/layout/dialog_additional_add.xml deleted file mode 100644 index c042afd4..00000000 --- a/app/src/main/res/layout/dialog_additional_add.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_attendance.xml b/app/src/main/res/layout/dialog_attendance.xml index b9c63539..22268aac 100644 --- a/app/src/main/res/layout/dialog_attendance.xml +++ b/app/src/main/res/layout/dialog_attendance.xml @@ -1,167 +1,92 @@ - - + android:orientation="vertical" + android:padding="20dp"> + android:textSize="20sp" /> + android:textSize="17sp" /> - + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> - + android:layout_gravity="end" + android:layout_marginTop="15dp" + android:text="@string/all_close" /> + diff --git a/app/src/main/res/layout/dialog_auth.xml b/app/src/main/res/layout/dialog_auth.xml deleted file mode 100644 index a0b9d6ea..00000000 --- a/app/src/main/res/layout/dialog_auth.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_captcha.xml b/app/src/main/res/layout/dialog_captcha.xml deleted file mode 100644 index 019d8932..00000000 --- a/app/src/main/res/layout/dialog_captcha.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_conference.xml b/app/src/main/res/layout/dialog_conference.xml deleted file mode 100644 index 3d33fd56..00000000 --- a/app/src/main/res/layout/dialog_conference.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_error.xml b/app/src/main/res/layout/dialog_error.xml index 98b9c8b1..2d4e5d0b 100644 --- a/app/src/main/res/layout/dialog_error.xml +++ b/app/src/main/res/layout/dialog_error.xml @@ -4,11 +4,18 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:minWidth="300dp" - android:orientation="vertical" - tools:context=".ui.base.ErrorDialog"> + android:orientation="vertical"> + + - + + + + + + + + + + + + android:background="@drawable/ic_all_divider" + android:gravity="end" + android:minHeight="52dp" + android:orientation="horizontal"> - + - + - - - + + + + diff --git a/app/src/main/res/layout/dialog_exam.xml b/app/src/main/res/layout/dialog_exam.xml index e2f77e1f..8e46dc4f 100644 --- a/app/src/main/res/layout/dialog_exam.xml +++ b/app/src/main/res/layout/dialog_exam.xml @@ -1,255 +1,113 @@ - + android:orientation="vertical" + android:padding="20dp"> + android:textSize="20sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> - - - - + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> - - + android:textSize="12sp" /> - + android:layout_gravity="end" + android:layout_marginTop="20dp" + android:text="@string/all_close" /> + diff --git a/app/src/main/res/layout/dialog_excuse.xml b/app/src/main/res/layout/dialog_excuse.xml index 8297bc14..4ed9294c 100644 --- a/app/src/main/res/layout/dialog_excuse.xml +++ b/app/src/main/res/layout/dialog_excuse.xml @@ -1,26 +1,20 @@ + android:layout_height="wrap_content"> + android:hint="@string/attendance_excuse_dialog_reason" /> diff --git a/app/src/main/res/layout/dialog_grade.xml b/app/src/main/res/layout/dialog_grade.xml index 8606a5ce..be0570c2 100644 --- a/app/src/main/res/layout/dialog_grade.xml +++ b/app/src/main/res/layout/dialog_grade.xml @@ -8,20 +8,19 @@ + android:minWidth="300dp"> - - - - - - + android:background="@color/grade_black" + android:gravity="center" + android:maxLines="2" + android:minHeight="32dp" + android:textColor="@android:color/white" + android:textIsSelectable="true" + android:textSize="14sp" + tools:text="Waga: 1.00" /> + android:textIsSelectable="true" + android:textSize="20sp" /> + android:textColor="?android:textColorSecondary" + android:textIsSelectable="true" + android:textSize="16sp" /> - - - - + android:textSize="17sp" /> + android:textIsSelectable="true" + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textIsSelectable="true" + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textIsSelectable="true" + android:textSize="12sp" /> - + + + + diff --git a/app/src/main/res/layout/dialog_homework.xml b/app/src/main/res/layout/dialog_homework.xml index 10b71907..7c149d4b 100644 --- a/app/src/main/res/layout/dialog_homework.xml +++ b/app/src/main/res/layout/dialog_homework.xml @@ -1,58 +1,47 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> - + android:paddingHorizontal="10dp" + android:paddingVertical="5dp"> - + - - + + + diff --git a/app/src/main/res/layout/dialog_homework_add.xml b/app/src/main/res/layout/dialog_homework_add.xml deleted file mode 100644 index dc7ae32d..00000000 --- a/app/src/main/res/layout/dialog_homework_add.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_lesson_completed.xml b/app/src/main/res/layout/dialog_lesson_completed.xml index fc32a252..31ca7dd3 100644 --- a/app/src/main/res/layout/dialog_lesson_completed.xml +++ b/app/src/main/res/layout/dialog_lesson_completed.xml @@ -1,230 +1,145 @@ - - + android:orientation="vertical" + android:padding="20dp"> + android:textColor="?android:textColorPrimary" + android:textSize="20sp" /> + android:textColor="?android:textColorPrimary" + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textColor="?android:textColorPrimary" + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textColor="?android:textColorPrimary" + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textColor="?colorPrimary" + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textColor="?android:textColorPrimary" + android:textSize="17sp" /> + android:textSize="12sp" /> + android:layout_gravity="end" + android:layout_marginTop="15dp" + android:text="@string/all_close" /> - + diff --git a/app/src/main/res/layout/dialog_login_support.xml b/app/src/main/res/layout/dialog_login_support.xml deleted file mode 100644 index c04d7812..00000000 --- a/app/src/main/res/layout/dialog_login_support.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_mailbox_chooser.xml b/app/src/main/res/layout/dialog_mailbox_chooser.xml deleted file mode 100644 index 5c93acb5..00000000 --- a/app/src/main/res/layout/dialog_mailbox_chooser.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_mobile_device.xml b/app/src/main/res/layout/dialog_mobile_device.xml index c526ed74..7b128605 100644 --- a/app/src/main/res/layout/dialog_mobile_device.xml +++ b/app/src/main/res/layout/dialog_mobile_device.xml @@ -1,151 +1,98 @@ - + android:orientation="vertical" + android:padding="20dp"> - - - - - - - - - - - - - - - - - + tools:visibility="visible"> - + + + + + + + + + + + + + + + + + - - + diff --git a/app/src/main/res/layout/dialog_note.xml b/app/src/main/res/layout/dialog_note.xml index 3b88ea5f..71506b01 100644 --- a/app/src/main/res/layout/dialog_note.xml +++ b/app/src/main/res/layout/dialog_note.xml @@ -1,197 +1,109 @@ - - + android:orientation="vertical" + android:padding="20dp"> + android:textSize="20sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> - + android:layout_gravity="end" + android:layout_marginTop="15dp" + android:text="@string/all_close" /> + diff --git a/app/src/main/res/layout/dialog_school_announcement.xml b/app/src/main/res/layout/dialog_school_announcement.xml deleted file mode 100644 index a771b772..00000000 --- a/app/src/main/res/layout/dialog_school_announcement.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/dialog_timetable.xml b/app/src/main/res/layout/dialog_timetable.xml index de269648..f3d4cf1c 100644 --- a/app/src/main/res/layout/dialog_timetable.xml +++ b/app/src/main/res/layout/dialog_timetable.xml @@ -1,280 +1,167 @@ + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools"> - + android:orientation="vertical" + android:padding="20dp"> + android:textSize="20sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> + android:textSize="17sp" /> + android:textSize="12sp" /> - + android:layout_gravity="end" + android:layout_marginTop="15dp" + android:text="@string/all_close" /> + diff --git a/app/src/main/res/layout/fragment_account.xml b/app/src/main/res/layout/fragment_account.xml deleted file mode 100644 index b7873833..00000000 --- a/app/src/main/res/layout/fragment_account.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/layout/fragment_account_details.xml b/app/src/main/res/layout/fragment_account_details.xml deleted file mode 100644 index 0e42348d..00000000 --- a/app/src/main/res/layout/fragment_account_details.xml +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_attendance.xml b/app/src/main/res/layout/fragment_attendance.xml index 078daf61..39b00d30 100644 --- a/app/src/main/res/layout/fragment_attendance.xml +++ b/app/src/main/res/layout/fragment_attendance.xml @@ -1,18 +1,18 @@ - + android:layout_height="match_parent" + android:layout_marginBottom="50dp"> - @@ -105,7 +106,7 @@ + tools:ignore="UnusedAttribute"> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_left" /> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_right" /> - + diff --git a/app/src/main/res/layout/fragment_attendance_calculator.xml b/app/src/main/res/layout/fragment_attendance_calculator.xml deleted file mode 100644 index 346c6aec..00000000 --- a/app/src/main/res/layout/fragment_attendance_calculator.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_attendance_summary.xml b/app/src/main/res/layout/fragment_attendance_summary.xml index 6b92e23f..da0ce7f2 100644 --- a/app/src/main/res/layout/fragment_attendance_summary.xml +++ b/app/src/main/res/layout/fragment_attendance_summary.xml @@ -49,8 +49,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_debug.xml b/app/src/main/res/layout/fragment_debug.xml deleted file mode 100644 index 2d71d89c..00000000 --- a/app/src/main/res/layout/fragment_debug.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/fragment_debug_notifications.xml b/app/src/main/res/layout/fragment_debug_notifications.xml deleted file mode 100644 index 372e1055..00000000 --- a/app/src/main/res/layout/fragment_debug_notifications.xml +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/app/src/main/res/layout/fragment_exam.xml b/app/src/main/res/layout/fragment_exam.xml index 8dba5361..ed4094a5 100644 --- a/app/src/main/res/layout/fragment_exam.xml +++ b/app/src/main/res/layout/fragment_exam.xml @@ -10,8 +10,9 @@ android:layout_height="match_parent" android:layout_marginBottom="50dp"> - + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_left" /> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_grade.xml b/app/src/main/res/layout/fragment_grade.xml index f76419d1..0bc864b2 100644 --- a/app/src/main/res/layout/fragment_grade.xml +++ b/app/src/main/res/layout/fragment_grade.xml @@ -11,14 +11,13 @@ android:layout_height="48dp" android:background="?colorSurface" android:visibility="invisible" - android:outlineProvider="none" app:tabMode="scrollable" app:tabSelectedTextColor="?colorPrimary" app:tabTextColor="@color/material_on_surface_emphasis_medium" tools:ignore="UnusedAttribute" tools:visibility="visible" /> - - - + android:layout_height="match_parent" + android:orientation="vertical" + tools:context=".ui.modules.grade.statistics.GradeStatisticsFragment"> - + android:layout_height="wrap_content" + android:background="?android:windowBackground" + android:padding="5dp" + android:visibility="gone" + tools:ignore="UnusedAttribute" + tools:listitem="@layout/item_attendance_summary" + tools:visibility="visible"> - + android:ellipsize="middle" + android:paddingStart="10dp" + android:paddingLeft="10dp" + android:paddingTop="10dp" + android:paddingEnd="30dp" + android:paddingRight="30dp" + android:paddingBottom="10dp" + android:spinnerMode="dialog" /> + - + + + + - + android:orientation="vertical"> - - - - - + android:layout_gravity="center"> - + + + + + + + + + + + android:layout_height="match_parent"> - - - + android:layout_height="match_parent" + tools:listitem="@layout/item_grade_statistics_pie" /> + + + + + + + + + + + + + + + + + android:orientation="horizontal"> - - - - + android:layout_marginEnd="8dp" + android:layout_marginRight="8dp" + android:text="@string/all_details" /> - - - - - - - - - - - - + android:text="@string/all_retry" /> - - - - - - + + + + + + diff --git a/app/src/main/res/layout/fragment_grade_summary.xml b/app/src/main/res/layout/fragment_grade_summary.xml index de2d0f3b..3f21e61c 100644 --- a/app/src/main/res/layout/fragment_grade_summary.xml +++ b/app/src/main/res/layout/fragment_grade_summary.xml @@ -17,8 +17,9 @@ tools:listitem="@layout/item_grade_summary" /> - - @@ -93,7 +92,7 @@ - - + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_left" /> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_license.xml b/app/src/main/res/layout/fragment_license.xml index 5551d4f1..f4105355 100644 --- a/app/src/main/res/layout/fragment_license.xml +++ b/app/src/main/res/layout/fragment_license.xml @@ -4,8 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - @@ -185,34 +186,9 @@ tools:ignore="Deprecated,LabelFor" /> - - - - - + app:layout_constraintTop_toBottomOf="@+id/loginFormHostLayout"> - - - - - + app:layout_constraintTop_toBottomOf="@+id/loginFormContact" + app:layout_constraintVertical_chainStyle="packed" /> - + app:layout_constraintTop_toBottomOf="@+id/loginFormHeader"> + app:layout_constraintTop_toBottomOf="@+id/loginFormUsernameLayout" + app:passwordToggleEnabled="true"> + @@ -250,41 +214,15 @@ tools:ignore="Deprecated,LabelFor" /> - - - - - + app:layout_constraintTop_toBottomOf="@+id/loginFormHostLayout" /> - + android:paddingBottom="16dp" + android:visibility="visible"> @@ -94,7 +96,7 @@ + tools:visibility="invisible"> - + android:layout_marginTop="16dp" + android:gravity="center" + android:orientation="horizontal"> + android:text="@string/all_details" /> - + android:text="@string/all_retry" /> + + tools:visibility="invisible"> + diff --git a/app/src/main/res/layout/fragment_login_student_select.xml b/app/src/main/res/layout/fragment_login_student_select.xml index 6b603c9f..f9c6c157 100644 --- a/app/src/main/res/layout/fragment_login_student_select.xml +++ b/app/src/main/res/layout/fragment_login_student_select.xml @@ -3,25 +3,92 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical" - tools:context=".ui.modules.login.studentselect.LoginStudentSelectFragment"> + android:orientation="vertical"> + + - + tools:visibility="visible"> + + + + + + + + + + + + + + + tools:itemCount="6" + tools:listitem="@layout/item_login_student_select" /> - - diff --git a/app/src/main/res/layout/fragment_login_symbol.xml b/app/src/main/res/layout/fragment_login_symbol.xml index 612e8c21..77f44d21 100644 --- a/app/src/main/res/layout/fragment_login_symbol.xml +++ b/app/src/main/res/layout/fragment_login_symbol.xml @@ -5,8 +5,9 @@ android:layout_height="match_parent" tools:context=".ui.modules.login.symbol.LoginSymbolFragment"> - - - + app:layout_constraintTop_toBottomOf="@+id/loginSymbolHelper"> + tools:context=".ui.modules.about.logviewer.LogViewerFragment"> + app:srcCompat="@drawable/ic_refresh" /> + diff --git a/app/src/main/res/layout/fragment_lucky_number.xml b/app/src/main/res/layout/fragment_lucky_number.xml index 7c48523b..a6b9b822 100644 --- a/app/src/main/res/layout/fragment_lucky_number.xml +++ b/app/src/main/res/layout/fragment_lucky_number.xml @@ -5,8 +5,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_menu_order.xml b/app/src/main/res/layout/fragment_menu_order.xml deleted file mode 100644 index 1773b45a..00000000 --- a/app/src/main/res/layout/fragment_menu_order.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/fragment_message.xml b/app/src/main/res/layout/fragment_message.xml index b3dac0dd..b4cc0c2f 100644 --- a/app/src/main/res/layout/fragment_message.xml +++ b/app/src/main/res/layout/fragment_message.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - + tools:listitem="@layout/item_message_preview" /> - - - + app:srcCompat="@drawable/ic_all_add" /> diff --git a/app/src/main/res/layout/fragment_more.xml b/app/src/main/res/layout/fragment_more.xml index f0b0285f..dbd5470c 100644 --- a/app/src/main/res/layout/fragment_more.xml +++ b/app/src/main/res/layout/fragment_more.xml @@ -1,12 +1,10 @@ + android:layout_height="match_parent" /> diff --git a/app/src/main/res/layout/fragment_note.xml b/app/src/main/res/layout/fragment_note.xml index dc3b9ef2..e55f0007 100644 --- a/app/src/main/res/layout/fragment_note.xml +++ b/app/src/main/res/layout/fragment_note.xml @@ -4,8 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" /> - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_notifications_center.xml b/app/src/main/res/layout/fragment_notifications_center.xml deleted file mode 100644 index ba2f0ff4..00000000 --- a/app/src/main/res/layout/fragment_notifications_center.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_school.xml b/app/src/main/res/layout/fragment_school.xml index a7c3551d..a7e9a213 100644 --- a/app/src/main/res/layout/fragment_school.xml +++ b/app/src/main/res/layout/fragment_school.xml @@ -5,8 +5,9 @@ android:layout_height="match_parent" tools:context=".ui.modules.schoolandteachers.school.SchoolFragment"> - + android:layout_height="match_parent" + android:paddingStart="8dp" + android:paddingLeft="8dp" + android:paddingTop="8dp" + android:paddingEnd="12dp" + android:paddingRight="12dp" + android:paddingBottom="8dp"> + android:orientation="vertical"> - + android:layout_marginLeft="8dp" + android:layout_gravity="center_vertical" /> - + android:layout_marginLeft="8dp" + android:layout_gravity="center_vertical" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_schoolandteachers.xml b/app/src/main/res/layout/fragment_schoolandteachers.xml index ae8c6c20..6414abb9 100644 --- a/app/src/main/res/layout/fragment_schoolandteachers.xml +++ b/app/src/main/res/layout/fragment_schoolandteachers.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_teacher.xml b/app/src/main/res/layout/fragment_teacher.xml index 1253e312..484bf065 100644 --- a/app/src/main/res/layout/fragment_teacher.xml +++ b/app/src/main/res/layout/fragment_teacher.xml @@ -4,8 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - + android:indeterminate="true" /> + tools:listitem="@layout/item_timetable" /> - - + tools:ignore="UnusedAttribute"> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_left" /> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_timetable_additional.xml b/app/src/main/res/layout/fragment_timetable_additional.xml deleted file mode 100644 index e50fd6b5..00000000 --- a/app/src/main/res/layout/fragment_timetable_additional.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_timetable_completed.xml b/app/src/main/res/layout/fragment_timetable_completed.xml index 8d647ff6..4934327c 100644 --- a/app/src/main/res/layout/fragment_timetable_completed.xml +++ b/app/src/main/res/layout/fragment_timetable_completed.xml @@ -10,8 +10,9 @@ android:layout_height="match_parent" android:layout_marginBottom="50dp"> - + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_left" /> + android:tint="?colorPrimary" + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/header_account.xml b/app/src/main/res/layout/header_account.xml index 86252552..6219c26d 100644 --- a/app/src/main/res/layout/header_account.xml +++ b/app/src/main/res/layout/header_account.xml @@ -4,22 +4,15 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingHorizontal="16dp" - android:paddingBottom="16dp" + android:paddingHorizontal="24dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" tools:context=".ui.modules.account.AccountAdapter"> - - @@ -28,6 +21,7 @@ android:id="@+id/accountHeaderType" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="2dp" android:textColor="?android:textColorSecondary" android:textSize="12sp" tools:text="Konto ucznia" /> diff --git a/app/src/main/res/layout/header_grade_details.xml b/app/src/main/res/layout/header_grade_details.xml index 1765d9d1..f2ba9a8c 100644 --- a/app/src/main/res/layout/header_grade_details.xml +++ b/app/src/main/res/layout/header_grade_details.xml @@ -45,43 +45,19 @@ android:textColor="?android:textColorSecondary" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/gradeHeaderAverageAllYear" - app:layout_constraintHorizontal_bias="0" - app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintStart_toStartOf="@id/gradeHeaderSubject" app:layout_constraintTop_toBottomOf="@+id/gradeHeaderSubject" tools:text="Average: 6,00" /> - - @@ -91,13 +67,8 @@ android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="5dp" - android:layout_marginEnd="8dp" - android:ellipsize="end" - android:maxLines="1" android:textColor="?android:textColorSecondary" android:textSize="12sp" - app:layout_constrainedWidth="true" - app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/gradeHeaderPointsSum" app:layout_constraintTop_toBottomOf="@id/gradeHeaderSubject" tools:text="12 grades" /> @@ -114,9 +85,6 @@ android:paddingRight="5dp" android:textColor="?colorOnPrimary" android:textSize="14sp" - app:autoSizeMaxTextSize="16dp" - app:autoSizeMinTextSize="10dp" - app:autoSizeTextType="uniform" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" diff --git a/app/src/main/res/layout/item_account.xml b/app/src/main/res/layout/item_account.xml index 563e6b1e..9568b345 100644 --- a/app/src/main/res/layout/item_account.xml +++ b/app/src/main/res/layout/item_account.xml @@ -5,11 +5,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?selectableItemBackground" - android:clickable="true" - android:focusable="true" android:orientation="horizontal" - android:paddingHorizontal="16dp" android:paddingVertical="8dp" + android:paddingHorizontal="16dp" tools:context=".ui.modules.account.AccountAdapter"> - - + tools:tint="@color/colorPrimary" /> - - - - - diff --git a/app/src/main/res/layout/item_attendance.xml b/app/src/main/res/layout/item_attendance.xml index f3015283..e25b51f6 100644 --- a/app/src/main/res/layout/item_attendance.xml +++ b/app/src/main/res/layout/item_attendance.xml @@ -52,8 +52,7 @@ android:layout_height="32dp" android:visibility="gone" app:srcCompat="@drawable/ic_excuse_waiting" - app:tint="?attr/colorOnSurface" - tools:ignore="ContentDescription" /> + app:tint="?attr/colorOnSurface" /> - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_attendance_summary.xml b/app/src/main/res/layout/item_attendance_summary.xml index 340ea892..15552629 100644 --- a/app/src/main/res/layout/item_attendance_summary.xml +++ b/app/src/main/res/layout/item_attendance_summary.xml @@ -37,6 +37,7 @@ @@ -61,14 +62,10 @@ tools:text="50" /> - - @@ -93,14 +90,10 @@ tools:text="0" /> - - @@ -125,14 +118,10 @@ tools:text="25" /> - - @@ -157,14 +146,10 @@ tools:text="0" /> - - @@ -189,14 +174,10 @@ tools:text="6" /> - - @@ -221,14 +202,10 @@ tools:text="0" /> - - @@ -252,9 +229,4 @@ android:textSize="12sp" tools:text="0" /> - - diff --git a/app/src/main/res/layout/item_dashboard_account.xml b/app/src/main/res/layout/item_dashboard_account.xml deleted file mode 100644 index 7ae0c84d..00000000 --- a/app/src/main/res/layout/item_dashboard_account.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_admin_message.xml b/app/src/main/res/layout/item_dashboard_admin_message.xml deleted file mode 100644 index 407e1292..00000000 --- a/app/src/main/res/layout/item_dashboard_admin_message.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_ads.xml b/app/src/main/res/layout/item_dashboard_ads.xml deleted file mode 100644 index b75bb27e..00000000 --- a/app/src/main/res/layout/item_dashboard_ads.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_announcements.xml b/app/src/main/res/layout/item_dashboard_announcements.xml deleted file mode 100644 index b9ddb757..00000000 --- a/app/src/main/res/layout/item_dashboard_announcements.xml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_conferences.xml b/app/src/main/res/layout/item_dashboard_conferences.xml deleted file mode 100644 index b02b8e18..00000000 --- a/app/src/main/res/layout/item_dashboard_conferences.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_exams.xml b/app/src/main/res/layout/item_dashboard_exams.xml deleted file mode 100644 index 84302403..00000000 --- a/app/src/main/res/layout/item_dashboard_exams.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_grades.xml b/app/src/main/res/layout/item_dashboard_grades.xml deleted file mode 100644 index 345d8a5e..00000000 --- a/app/src/main/res/layout/item_dashboard_grades.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_homework.xml b/app/src/main/res/layout/item_dashboard_homework.xml deleted file mode 100644 index b36afc57..00000000 --- a/app/src/main/res/layout/item_dashboard_homework.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_horizontal_group.xml b/app/src/main/res/layout/item_dashboard_horizontal_group.xml deleted file mode 100644 index 1c9246a1..00000000 --- a/app/src/main/res/layout/item_dashboard_horizontal_group.xml +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_dashboard_lessons.xml b/app/src/main/res/layout/item_dashboard_lessons.xml deleted file mode 100644 index a40f17f2..00000000 --- a/app/src/main/res/layout/item_dashboard_lessons.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_debug.xml b/app/src/main/res/layout/item_debug.xml deleted file mode 100644 index f0f9f09f..00000000 --- a/app/src/main/res/layout/item_debug.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/item_debug_notifications.xml b/app/src/main/res/layout/item_debug_notifications.xml deleted file mode 100644 index 204f7000..00000000 --- a/app/src/main/res/layout/item_debug_notifications.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/layout/item_grade_details.xml b/app/src/main/res/layout/item_grade_details.xml index 6849e929..2f3bd2de 100644 --- a/app/src/main/res/layout/item_grade_details.xml +++ b/app/src/main/res/layout/item_grade_details.xml @@ -20,12 +20,11 @@ android:id="@+id/gradeItemValue" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@drawable/background_grade_rounded" - android:backgroundTint="@color/grade_material_default" + android:background="@color/grade_material_default" android:gravity="center" android:maxLength="5" android:minWidth="45dp" - android:minHeight="45dp" + android:minHeight="40dp" android:textColor="@android:color/white" android:textSize="16sp" app:layout_constraintBottom_toBottomOf="@+id/gradeDetailsContainer" diff --git a/app/src/main/res/layout/item_grade_statistics_header.xml b/app/src/main/res/layout/item_grade_statistics_header.xml deleted file mode 100644 index cc35f606..00000000 --- a/app/src/main/res/layout/item_grade_statistics_header.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - -