Compare commits
105 Commits
Author | SHA1 | Date | |
---|---|---|---|
ba84f2be6e | |||
db7b7dbadf | |||
6bd07d2651 | |||
070fba734c | |||
72ef366829 | |||
4adfb268a3 | |||
bf0ea1b012 | |||
1267a39e32 | |||
462b917832 | |||
c5b16bb0d0 | |||
91268dcc67 | |||
13f9981be6 | |||
f9b3bd7b3a | |||
39916c2796 | |||
03f5ddaf0d | |||
ea4f55c06d | |||
5b0232f77e | |||
0b68091e55 | |||
7136c9282e | |||
09303153a5 | |||
bdf0fba95b | |||
86f24e5821 | |||
35f094b983 | |||
12cf1e0b66 | |||
68b37fc5dd | |||
ba5bad042a | |||
c5323ee811 | |||
df9c685217 | |||
73fa21d45f | |||
344fa1bbd7 | |||
01318c8c29 | |||
851486df28 | |||
d8b3c5d9d6 | |||
2883b21ddf | |||
4956cf3988 | |||
bdbcec786a | |||
c40bbf2398 | |||
08ecbb5341 | |||
e38e458386 | |||
14674b7778 | |||
c6f0588165 | |||
7591af0de1 | |||
cbfed09b52 | |||
5c185c5eca | |||
4a026e4a70 | |||
0bccbc6011 | |||
ed6a0f8cd0 | |||
58d5e4da0e | |||
ba6fb1a4b9 | |||
b6b862d4c3 | |||
9b044a19fe | |||
7485cb2a39 | |||
75122d0dcd | |||
39af56484b | |||
05f7e1d115 | |||
9cd5377438 | |||
7a61b233f0 | |||
83dbd9874e | |||
1d9a49d552 | |||
6175081b88 | |||
116e551186 | |||
713500d892 | |||
dfdbe374c2 | |||
b1e3bab5e7 | |||
0b2ef367da | |||
28f27db2b5 | |||
5c70cd8b8c | |||
0f75ff3206 | |||
383cab4dae | |||
e1b0db76c2 | |||
f10684097c | |||
35d4342bec | |||
068aee215a | |||
033074c66b | |||
0de534cb66 | |||
26e4619dde | |||
cf08d1ff24 | |||
96c400a0bd | |||
e238f65dde | |||
ba7966125b | |||
1536208e45 | |||
24cc07264a | |||
1ad5232520 | |||
07f3333029 | |||
214afb82a6 | |||
7a69710261 | |||
64d3afbdb3 | |||
387e46f72d | |||
89acc2f384 | |||
4ef1439878 | |||
6efd170e03 | |||
82cd39329a | |||
b38e0d04e7 | |||
90b2ffe250 | |||
33951dff54 | |||
9ced00c4d7 | |||
2ac1638911 | |||
463a7e2744 | |||
d14382f3b4 | |||
efa0b19cc1 | |||
7cb893a254 | |||
f7371f7b73 | |||
9c626ad517 | |||
9c4c6b0192 | |||
8efc4d750d |
@ -7,7 +7,7 @@ references:
|
|||||||
|
|
||||||
container_config: &container_config
|
container_config: &container_config
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/android:api-28
|
- image: circleci/android@sha256:5cdc8626cc6f13efe5ed982cdcdb432b0472f8740fed8743a6461e025ad6cdfc
|
||||||
working_directory: *workspace_root
|
working_directory: *workspace_root
|
||||||
environment:
|
environment:
|
||||||
environment:
|
environment:
|
||||||
@ -35,7 +35,7 @@ jobs:
|
|||||||
command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true
|
command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true
|
||||||
- run:
|
- run:
|
||||||
name: Initial build
|
name: Initial build
|
||||||
command: ./gradlew build -x test -x lint -x fabricGenerateResourcesRelease -x packageRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
command: ./gradlew build -x test -x lint -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease -x packageRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||||
- run:
|
- run:
|
||||||
name: Run FOSSA
|
name: Run FOSSA
|
||||||
command: fossa --no-ansi || true
|
command: fossa --no-ansi || true
|
||||||
@ -56,7 +56,7 @@ jobs:
|
|||||||
<<: *general_cache_key
|
<<: *general_cache_key
|
||||||
- run:
|
- run:
|
||||||
name: Run lint
|
name: Run lint
|
||||||
command: ./gradlew lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
command: ./gradlew lint -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: ./app/build/reports/
|
path: ./app/build/reports/
|
||||||
destination: lint_reports/app/
|
destination: lint_reports/app/
|
||||||
@ -75,7 +75,7 @@ jobs:
|
|||||||
<<: *general_cache_key
|
<<: *general_cache_key
|
||||||
- run:
|
- run:
|
||||||
name: Run app tests
|
name: Run app tests
|
||||||
command: ./gradlew :app:test :app:jacocoTestReport -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
command: ./gradlew :app:test :app:jacocoTestReport -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||||
- run:
|
- run:
|
||||||
name: Upload unit code coverage to codecov
|
name: Upload unit code coverage to codecov
|
||||||
command: bash <(curl -s https://codecov.io/bash) -F app
|
command: bash <(curl -s https://codecov.io/bash) -F app
|
||||||
@ -93,6 +93,9 @@ jobs:
|
|||||||
<<: *container_config
|
<<: *container_config
|
||||||
steps:
|
steps:
|
||||||
- *attach_workspace
|
- *attach_workspace
|
||||||
|
- run:
|
||||||
|
name: Accept licenses
|
||||||
|
command: yes | sdkmanager --licenses && yes | sdkmanager --update
|
||||||
- run:
|
- run:
|
||||||
name: Setup emulator
|
name: Setup emulator
|
||||||
command: sdkmanager "system-images;android-19;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-19;default;armeabi-v7a"
|
command: sdkmanager "system-images;android-19;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-19;default;armeabi-v7a"
|
||||||
@ -113,7 +116,7 @@ jobs:
|
|||||||
adb shell input keyevent 82
|
adb shell input keyevent 82
|
||||||
- run:
|
- run:
|
||||||
name: Run instrumented tests
|
name: Run instrumented tests
|
||||||
command: ./gradlew clean createDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex
|
command: ./gradlew clean createPlayDebugCoverageReport jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex
|
||||||
- run:
|
- run:
|
||||||
name: Collect logs from emulator
|
name: Collect logs from emulator
|
||||||
command: adb logcat -d > ./app/build/reports/logcat_emulator.txt
|
command: adb logcat -d > ./app/build/reports/logcat_emulator.txt
|
||||||
@ -159,7 +162,7 @@ jobs:
|
|||||||
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
|
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
|
||||||
- run:
|
- run:
|
||||||
name: Publish release
|
name: Publish release
|
||||||
command: ./gradlew publish --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
|
command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
|
113
.gitignore
vendored
113
.gitignore
vendored
@ -1,39 +1,90 @@
|
|||||||
/captures
|
# Created by https://www.gitignore.io
|
||||||
.externalNativeBuild
|
|
||||||
|
|
||||||
## https://gist.github.com/iainconnor/8605514
|
|
||||||
|
|
||||||
# Built application files
|
# Built application files
|
||||||
/build
|
*.apk
|
||||||
/*/build/
|
*.ap_
|
||||||
|
*.aab
|
||||||
|
|
||||||
# Crashlytics configuations
|
# Files for the ART/Dalvik VM
|
||||||
com_crashlytics_export_strings.xml
|
*.dex
|
||||||
|
|
||||||
|
# Java class files
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
bin/
|
||||||
|
gen/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Gradle files
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
|
||||||
# Local configuration file (sdk path, etc)
|
# Local configuration file (sdk path, etc)
|
||||||
local.properties
|
local.properties
|
||||||
|
|
||||||
# Gradle generated files
|
# Proguard folder generated by Eclipse
|
||||||
.gradle/
|
proguard/
|
||||||
|
|
||||||
# Signing files
|
# Log Files
|
||||||
.signing/
|
*.log
|
||||||
|
|
||||||
# User-specific configurations
|
# Android Studio Navigation editor temp files
|
||||||
.idea/copyright/profiles_settings.xml
|
.navigation/
|
||||||
|
|
||||||
|
# Android Studio captures folder
|
||||||
|
captures/
|
||||||
|
|
||||||
|
# IntelliJ configurations
|
||||||
|
*.iml
|
||||||
|
.idea/workspace.xml
|
||||||
|
.idea/tasks.xml
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/assetWizardSettings.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
.idea/libraries
|
||||||
|
.idea/caches
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/navEditor.xml
|
||||||
|
.idea/caches/
|
||||||
.idea/libraries/
|
.idea/libraries/
|
||||||
.idea/inspectionProfiles/
|
.idea/shelf/
|
||||||
.idea/.name
|
.idea/.name
|
||||||
.idea/compiler.xml
|
.idea/compiler.xml
|
||||||
|
.idea/copyright/profiles_settings.xml
|
||||||
.idea/encodings.xml
|
.idea/encodings.xml
|
||||||
.idea/misc.xml
|
.idea/misc.xml
|
||||||
.idea/modules.xml
|
|
||||||
.idea/scopes/scope_settings.xml
|
.idea/scopes/scope_settings.xml
|
||||||
.idea/tasks.xml
|
|
||||||
.idea/vcs.xml
|
.idea/vcs.xml
|
||||||
.idea/workspace.xml
|
.idea/jsLibraryMappings.xml
|
||||||
.idea/caches/
|
.idea/datasources.xml
|
||||||
*.iml
|
.idea/dataSources.ids
|
||||||
|
.idea/sqlDataSources.xml
|
||||||
|
.idea/dynamic.xml
|
||||||
|
.idea/uiDesigner.xml
|
||||||
|
.idea/runConfigurations.xml
|
||||||
|
|
||||||
|
# Keystore files
|
||||||
|
*.jks
|
||||||
|
*.keystore
|
||||||
|
*.p12
|
||||||
|
|
||||||
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
|
.externalNativeBuild
|
||||||
|
|
||||||
|
# Version control
|
||||||
|
vcs.xml
|
||||||
|
|
||||||
|
# lint
|
||||||
|
lint/intermediates/
|
||||||
|
lint/generated/
|
||||||
|
lint/outputs/
|
||||||
|
lint/tmp/
|
||||||
|
lint/reports/
|
||||||
|
|
||||||
|
### Android Patch ###
|
||||||
|
gen-external-apklibs
|
||||||
|
output.json
|
||||||
|
|
||||||
# OS-specific files
|
# OS-specific files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@ -43,8 +94,20 @@ local.properties
|
|||||||
.Trashes
|
.Trashes
|
||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
.idea/caches/
|
|
||||||
app/key.p12
|
# Legacy Eclipse project files
|
||||||
app/upload-key.jks
|
.classpath
|
||||||
*.log
|
.project
|
||||||
.idea/assetWizardSettings.xml
|
.cproject
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
|
||||||
|
### AndroidStudio Patch ###
|
||||||
|
|
||||||
|
!/gradle/wrapper/gradle-wrapper.jar
|
@ -12,7 +12,7 @@ build:
|
|||||||
script:
|
script:
|
||||||
- ./gradlew --no-daemon --stacktrace dependencies || true
|
- ./gradlew --no-daemon --stacktrace dependencies || true
|
||||||
- ./gradlew --no-daemon --stacktrace assembleDebug
|
- ./gradlew --no-daemon --stacktrace assembleDebug
|
||||||
- mv app/build/outputs/apk/debug/app-debug.apk .
|
- mv app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk .
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}"
|
name: "${CI_PROJECT_NAME}_${CI_BUILD_REF_NAME}-${CI_BUILD_ID}"
|
||||||
paths:
|
paths:
|
||||||
@ -26,7 +26,7 @@ tests:
|
|||||||
- .gradle
|
- .gradle
|
||||||
policy: pull
|
policy: pull
|
||||||
script:
|
script:
|
||||||
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease test
|
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease test
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- app/build/reports/tests
|
- app/build/reports/tests
|
||||||
@ -39,7 +39,7 @@ lint:
|
|||||||
- .gradle
|
- .gradle
|
||||||
policy: pull
|
policy: pull
|
||||||
script:
|
script:
|
||||||
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesRelease lint
|
- ./gradlew --no-daemon --stacktrace -x fabricGenerateResourcesFdroidRelease -x fabricGenerateResourcesPlayRelease lint
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- app/build/reports
|
- app/build/reports
|
||||||
|
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@ -21,6 +21,9 @@
|
|||||||
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
||||||
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
|
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
|
<MarkdownNavigatorCodeStyleSettings>
|
||||||
|
<option name="RIGHT_MARGIN" value="72" />
|
||||||
|
</MarkdownNavigatorCodeStyleSettings>
|
||||||
<XML>
|
<XML>
|
||||||
<option name="XML_KEEP_LINE_BREAKS" value="false" />
|
<option name="XML_KEEP_LINE_BREAKS" value="false" />
|
||||||
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
|
||||||
|
18
.idea/gradle.xml
generated
18
.idea/gradle.xml
generated
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
18
.travis.yml
18
.travis.yml
@ -11,10 +11,10 @@ cache:
|
|||||||
- $HOME/.gradle/caches/
|
- $HOME/.gradle/caches/
|
||||||
- $HOME/.gradle/wrapper/
|
- $HOME/.gradle/wrapper/
|
||||||
|
|
||||||
#branches:
|
branches:
|
||||||
# only:
|
only:
|
||||||
# - master
|
- develop
|
||||||
# - 0.8.x
|
- 0.9.4
|
||||||
|
|
||||||
android:
|
android:
|
||||||
licenses:
|
licenses:
|
||||||
@ -48,20 +48,20 @@ before_script:
|
|||||||
script:
|
script:
|
||||||
- ./gradlew dependencies --stacktrace --daemon
|
- ./gradlew dependencies --stacktrace --daemon
|
||||||
- fossa --no-ansi || true
|
- fossa --no-ansi || true
|
||||||
- ./gradlew lint -x fabricGenerateResourcesRelease --stacktrace --daemon
|
#- ./gradlew lintPlayRelease -x fabricGenerateResourcesPlayRelease --stacktrace --daemon
|
||||||
- ./gradlew test -x fabricGenerateResourcesRelease --stacktrace --daemon
|
- ./gradlew testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
|
||||||
- ./gradlew createDebugCoverageReport --stacktrace --daemon
|
- ./gradlew createPlayDebugCoverageReport --stacktrace --daemon
|
||||||
- ./gradlew jacocoTestReport --stacktrace --daemon
|
- ./gradlew jacocoTestReport --stacktrace --daemon
|
||||||
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
|
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
|
||||||
git fetch --unshallow;
|
git fetch --unshallow;
|
||||||
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;
|
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesPlayRelease -x fabricGenerateResourcesFdroidRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [ $TRAVIS_TAG ]; then
|
if [ $TRAVIS_TAG ]; then
|
||||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
|
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
|
||||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
|
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
|
||||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
|
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
|
||||||
./gradlew publish -PenableCrashlytics --stacktrace;
|
./gradlew publishPlayRelease -PenableCrashlytics --stacktrace;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2017 wulkanowy
|
Copyright 2019 Wulkanowy
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
61
README.en.md
Normal file
61
README.en.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
[Polska wersja README](README.md)
|
||||||
|
|
||||||
|
# Wulkanowy
|
||||||
|
[](https://travis-ci.com/wulkanowy/wulkanowy)
|
||||||
|
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||||
|
[](https://discord.gg/vccAQBr)
|
||||||
|
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||||
|
[](https://github.com/wulkanowy/wulkanowy/releases)
|
||||||
|
|
||||||
|
Unofficial android VULCAN UONET+ register client for student and parent
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* logging in using the email and password
|
||||||
|
* 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
|
||||||
|
* notifications, e.g. about a new grade
|
||||||
|
* dark and black (AMOLED) theme
|
||||||
|
* offline mode
|
||||||
|
* no ads
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
You can download the current beta from the Google Play or Fdroid store
|
||||||
|
|
||||||
|
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
|
||||||
|
alt="Get it on Google Play"
|
||||||
|
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
|
||||||
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
|
alt="Get it on Fdroid"
|
||||||
|
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||||
|
|
||||||
|
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features prepared for the next release
|
||||||
|
|
||||||
|
## Built With
|
||||||
|
|
||||||
|
|
||||||
|
* [Wulkanowy API](https://github.com/wulkanowy/api)
|
||||||
|
* [RxJava 2](https://github.com/ReactiveX/RxJava)
|
||||||
|
* [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
|
64
README.md
64
README.md
@ -1,22 +1,62 @@
|
|||||||
|
[English version of README](README.en.md)
|
||||||
|
|
||||||
# Wulkanowy
|
# Wulkanowy
|
||||||
|
|
||||||
[](https://circleci.com/gh/wulkanowy/wulkanowy)
|
|
||||||
[](https://travis-ci.com/wulkanowy/wulkanowy)
|
[](https://travis-ci.com/wulkanowy/wulkanowy)
|
||||||
[](https://www.bitrise.io/app/daeff1893f3c8128)
|
|
||||||
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
[](https://codecov.io/gh/wulkanowy/wulkanowy)
|
||||||
[](https://bettercodehub.com/)
|
|
||||||
[](https://sonarcloud.io/dashboard?id=io.github.wulkanowy%3Aapp)
|
|
||||||
[](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_shield)
|
|
||||||
[](https://discord.gg/vccAQBr)
|
[](https://discord.gg/vccAQBr)
|
||||||
|
[](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||||
|
[](https://github.com/wulkanowy/wulkanowy/releases)
|
||||||
|
|
||||||
[Pobierz wersję beta z Google Play](https://play.google.com/store/apps/details?id=io.github.wulkanowy&utm_source=vcs)
|
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
|
||||||
|
|
||||||
[Pobierz wersję DEV](https://bitrise-redirector.herokuapp.com/v0.1/apps/f841f20d8f8b1dc8/builds/master/artifacts/0)
|
## Funkcje
|
||||||
[(Więcej wersji DEV)](https://wulkanowy.github.io/dev.html)
|
|
||||||
|
|
||||||
Androidowy klient dziennika VULCAN UONET+.
|
* logowanie za pomocą e-maila i hasła
|
||||||
|
* 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
|
||||||
|
* powiadomienia np. o nowej ocenie
|
||||||
|
* ciemny i czarny (AMOLED) motyw
|
||||||
|
* tryb offilne
|
||||||
|
* brak reklam
|
||||||
|
|
||||||
|
## Pobierz
|
||||||
|
|
||||||
|
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub Fdroid
|
||||||
|
|
||||||
|
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
|
||||||
|
alt="Pobierz z Google Play"
|
||||||
|
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
|
||||||
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||||
|
alt="Pobierz z Fdroid"
|
||||||
|
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
|
||||||
|
|
||||||
|
|
||||||
## License
|
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania
|
||||||
|
|
||||||
[](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_large)
|
|
||||||
|
## Zbudowana za pomocą
|
||||||
|
|
||||||
|
* [Wulkanowy API](https://github.com/wulkanowy/api)
|
||||||
|
* [RxJava 2](https://github.com/ReactiveX/RxJava)
|
||||||
|
* [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 jest licencjonowany w ramach Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)
|
1
app/.gitignore
vendored
1
app/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
117
app/build.gradle
117
app/build.gradle
@ -6,6 +6,7 @@ apply plugin: 'io.fabric'
|
|||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
apply from: 'jacoco.gradle'
|
apply from: 'jacoco.gradle'
|
||||||
apply from: 'sonarqube.gradle'
|
apply from: 'sonarqube.gradle'
|
||||||
|
apply from: 'hooks.gradle'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 28
|
||||||
@ -14,10 +15,10 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "io.github.wulkanowy"
|
applicationId "io.github.wulkanowy"
|
||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 15
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 37
|
versionCode 42
|
||||||
versionName "0.8.4"
|
versionName "0.9.4"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@ -63,6 +64,18 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flavorDimensions "platform"
|
||||||
|
productFlavors {
|
||||||
|
play {
|
||||||
|
dimension "platform"
|
||||||
|
}
|
||||||
|
|
||||||
|
fdroid {
|
||||||
|
buildConfigField "boolean", "CRASHLYTICS_ENABLED", "false"
|
||||||
|
dimension "platform"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'HardwareIds'
|
disable 'HardwareIds'
|
||||||
}
|
}
|
||||||
@ -84,71 +97,91 @@ play {
|
|||||||
track = 'alpha'
|
track = 'alpha'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
work_manager = "2.1.0"
|
||||||
|
room = "2.1.0"
|
||||||
|
dagger = "2.24"
|
||||||
|
chucker = "2.0.4"
|
||||||
|
mockk = "1.9.2"
|
||||||
|
mockito_core = "3.0.4"
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.wulkanowy:api:0.8.4'
|
implementation "io.github.wulkanowy:api:0.9.4"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
implementation "androidx.core:core:1.0.2"
|
||||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation "androidx.fragment:fragment:1.0.0"
|
||||||
|
implementation "androidx.annotation:annotation:1.1.0"
|
||||||
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
|
||||||
implementation "androidx.cardview:cardview:1.0.0"
|
implementation "androidx.recyclerview:recyclerview:1.0.0"
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||||
implementation "com.google.android.material:material:1.1.0-alpha05"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||||
implementation 'com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f'
|
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||||
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
|
implementation "androidx.coordinatorlayout:coordinatorlayout:1.0.0"
|
||||||
|
implementation "com.google.android.material:material:1.1.0-alpha07"
|
||||||
|
implementation "com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f"
|
||||||
|
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime:2.0.1"
|
implementation "androidx.work:work-runtime:$work_manager"
|
||||||
implementation "androidx.work:work-rxjava2:2.0.1"
|
implementation "androidx.work:work-rxjava2:$work_manager"
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:2.1.0-alpha07"
|
implementation "androidx.room:room-runtime:$room"
|
||||||
implementation "androidx.room:room-rxjava2:2.1.0-alpha07"
|
implementation "androidx.room:room-rxjava2:$room"
|
||||||
kapt "androidx.room:room-compiler:2.1.0-alpha07"
|
kapt "androidx.room:room-compiler:$room"
|
||||||
|
|
||||||
implementation "com.google.dagger:dagger-android-support:2.22.1"
|
implementation "com.google.dagger:dagger-android-support:$dagger"
|
||||||
kapt "com.google.dagger:dagger-compiler:2.22.1"
|
kapt "com.google.dagger:dagger-compiler:$dagger"
|
||||||
kapt "com.google.dagger:dagger-android-processor:2.22.1"
|
kapt "com.google.dagger:dagger-android-processor:$dagger"
|
||||||
implementation 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
|
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0"
|
||||||
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'
|
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.0"
|
||||||
|
|
||||||
implementation "eu.davidea:flexible-adapter:5.1.0"
|
implementation "eu.davidea:flexible-adapter:5.1.0"
|
||||||
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
|
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
|
||||||
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
||||||
implementation 'com.ncapdevi:frag-nav:3.2.0'
|
implementation "com.ncapdevi:frag-nav:3.3.0"
|
||||||
|
|
||||||
implementation 'com.github.pwittchen:reactivenetwork-rx2:3.0.2'
|
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.4"
|
||||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||||
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
|
implementation "io.reactivex.rxjava2:rxjava:2.2.11"
|
||||||
|
|
||||||
implementation 'com.google.code.gson:gson:2.8.5'
|
implementation "com.google.code.gson:gson:2.8.5"
|
||||||
implementation "com.jakewharton.threetenabp:threetenabp:1.2.0"
|
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
|
||||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||||
implementation "com.squareup.okhttp3:logging-interceptor:3.12.1"
|
implementation "com.squareup.okhttp3:logging-interceptor:3.12.3"
|
||||||
|
|
||||||
implementation "com.mikepenz:aboutlibraries:6.2.3"
|
implementation "com.mikepenz:aboutlibraries:6.2.3"
|
||||||
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
|
implementation "com.takisoft.preferencex:preferencex:1.0.0"
|
||||||
|
|
||||||
implementation 'com.google.firebase:firebase-core:16.0.8'
|
playImplementation "com.google.firebase:firebase-core:17.0.1"
|
||||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
|
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
|
||||||
|
|
||||||
releaseImplementation 'fr.o80.chucker:library-no-op:2.0.4'
|
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
|
||||||
|
|
||||||
debugImplementation 'fr.o80.chucker:library:2.0.4'
|
debugImplementation "fr.o80.chucker:library:$chucker"
|
||||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
|
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
|
||||||
|
|
||||||
testImplementation "junit:junit:4.12"
|
testImplementation "junit:junit:4.12"
|
||||||
testImplementation "io.mockk:mockk:1.9.2"
|
testImplementation "io.mockk:mockk:$mockk"
|
||||||
testImplementation "org.mockito:mockito-inline:2.27.0"
|
testImplementation "org.threeten:threetenbp:1.4.0"
|
||||||
testImplementation 'org.threeten:threetenbp:1.3.8'
|
testImplementation "org.mockito:mockito-core:$mockito_core"
|
||||||
|
testImplementation("org.mockito:mockito-inline:3.0.4") {
|
||||||
|
exclude group: "org.mockito", module: "mockito-core"
|
||||||
|
}
|
||||||
|
|
||||||
androidTestImplementation 'androidx.test:core:1.1.0'
|
androidTestImplementation "androidx.test:core:1.2.0"
|
||||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
androidTestImplementation "androidx.test:runner:1.2.0"
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
|
androidTestImplementation "androidx.test.ext:junit:1.1.1"
|
||||||
androidTestImplementation "io.mockk:mockk-android:1.9.2"
|
androidTestImplementation "io.mockk:mockk-android:$mockk"
|
||||||
androidTestImplementation 'org.mockito:mockito-android:2.27.0'
|
androidTestImplementation "androidx.room:room-testing:$room"
|
||||||
androidTestImplementation "androidx.room:room-testing:2.1.0-alpha07"
|
|
||||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
|
androidTestImplementation "org.mockito:mockito-core:$mockito_core"
|
||||||
|
androidTestImplementation("org.mockito:mockito-android:3.0.4") {
|
||||||
|
exclude group: 'org.mockito', module: 'mockito-core'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
10
app/hooks.gradle
Normal file
10
app/hooks.gradle
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
apply plugin: "com.star-zero.gradle.githook"
|
||||||
|
|
||||||
|
githook {
|
||||||
|
failOnMissingHooksDir = false
|
||||||
|
hooks {
|
||||||
|
"pre-push" {
|
||||||
|
shell = "./app/play-publish-lint.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -35,11 +35,14 @@ task jacocoTestReport(type: JacocoReport) {
|
|||||||
dir: "$buildDir/intermediates/classes/debug",
|
dir: "$buildDir/intermediates/classes/debug",
|
||||||
excludes: excludes
|
excludes: excludes
|
||||||
) + fileTree(
|
) + fileTree(
|
||||||
dir: "$buildDir/tmp/kotlin-classes/debug",
|
dir: "$buildDir/tmp/kotlin-classes/playDebug",
|
||||||
excludes: excludes
|
excludes: excludes
|
||||||
))
|
))
|
||||||
|
|
||||||
sourceDirectories.setFrom(files("$project.projectDir/src/main/java"))
|
sourceDirectories.setFrom(files([
|
||||||
|
"src/main/java",
|
||||||
|
"src/play/java"
|
||||||
|
]))
|
||||||
executionData.setFrom(fileTree(
|
executionData.setFrom(fileTree(
|
||||||
dir: project.projectDir,
|
dir: project.projectDir,
|
||||||
includes: ["**/*.exec", "**/*.ec"]
|
includes: ["**/*.exec", "**/*.ec"]
|
||||||
|
Binary file not shown.
7
app/play-publish-lint.sh
Executable file
7
app/play-publish-lint.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash -
|
||||||
|
|
||||||
|
content=$(cat < "app/src/main/play/release-notes/pl-PL/default.txt") || exit
|
||||||
|
if [[ "${#content}" -gt 500 ]]; then
|
||||||
|
echo >&2 "Release notes content has reached the limit of 500 characters"
|
||||||
|
exit 1
|
||||||
|
fi
|
3
app/proguard-rules.pro
vendored
3
app/proguard-rules.pro
vendored
@ -37,3 +37,6 @@
|
|||||||
|
|
||||||
#Config for API
|
#Config for API
|
||||||
-keep class io.github.wulkanowy.api.** {*;}
|
-keep class io.github.wulkanowy.api.** {*;}
|
||||||
|
|
||||||
|
#Config for Material Components
|
||||||
|
-keep class com.google.android.material.tabs.** {*;}
|
||||||
|
1386
app/schemas/io.github.wulkanowy.data.db.AppDatabase/14.json
Normal file
1386
app/schemas/io.github.wulkanowy.data.db.AppDatabase/14.json
Normal file
File diff suppressed because it is too large
Load Diff
1430
app/schemas/io.github.wulkanowy.data.db.AppDatabase/15.json
Normal file
1430
app/schemas/io.github.wulkanowy.data.db.AppDatabase/15.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,5 +29,6 @@ sonarqube {
|
|||||||
property "sonar.java.coveragePlugin", "jacoco"
|
property "sonar.java.coveragePlugin", "jacoco"
|
||||||
property "sonar.android.lint.report", "build/reports/lint-results.xml"
|
property "sonar.android.lint.report", "build/reports/lint-results.xml"
|
||||||
property "sonar.jacoco.reportPaths", fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec'])
|
property "sonar.jacoco.reportPaths", fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec'])
|
||||||
|
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoTestReport/jacocoTestReport.xml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,12 @@ abstract class AbstractMigrationTest {
|
|||||||
fun getMigratedRoomDatabase(): AppDatabase {
|
fun getMigratedRoomDatabase(): AppDatabase {
|
||||||
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
|
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
|
||||||
AppDatabase::class.java, dbName)
|
AppDatabase::class.java, dbName)
|
||||||
.addMigrations(Migration12(), Migration13())
|
.addMigrations(
|
||||||
|
Migration12(),
|
||||||
|
Migration13(),
|
||||||
|
Migration14(),
|
||||||
|
Migration15()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
// close the database and release any stream resources when the test finishes
|
// close the database and release any stream resources when the test finishes
|
||||||
helper.closeWhenFinished(database)
|
helper.closeWhenFinished(database)
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
@file:Suppress("UNUSED_PARAMETER")
|
||||||
|
|
||||||
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
fun initCrashlytics(context: Context, appInfo: AppInfo) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
class CrashlyticsTree : Timber.Tree() {
|
||||||
|
|
||||||
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class FirebaseAnalyticsHelper @Inject constructor() {
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
|
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,6 @@
|
|||||||
package="io.github.wulkanowy"
|
package="io.github.wulkanowy"
|
||||||
android:installLocation="internalOnly">
|
android:installLocation="internalOnly">
|
||||||
|
|
||||||
<uses-sdk tools:overrideLibrary="com.readystatesoftware.chuck" />
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
@ -80,7 +78,6 @@
|
|||||||
android:name="android.appwidget.provider"
|
android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/provider_widget_timetable" />
|
android:resource="@xml/provider_widget_timetable" />
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
|
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
|
||||||
android:label="@string/lucky_number_title">
|
android:label="@string/lucky_number_title">
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
package io.github.wulkanowy
|
package io.github.wulkanowy
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Log.INFO
|
||||||
|
import android.util.Log.VERBOSE
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.crashlytics.android.Crashlytics
|
|
||||||
import com.crashlytics.android.core.CrashlyticsCore
|
|
||||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.support.DaggerApplication
|
import dagger.android.support.DaggerApplication
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.utils.Log
|
import eu.davidea.flexibleadapter.utils.Log
|
||||||
import io.fabric.sdk.android.Fabric
|
|
||||||
import io.github.wulkanowy.BuildConfig.CRASHLYTICS_ENABLED
|
|
||||||
import io.github.wulkanowy.BuildConfig.DEBUG
|
|
||||||
import io.github.wulkanowy.di.DaggerAppComponent
|
import io.github.wulkanowy.di.DaggerAppComponent
|
||||||
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||||
import io.github.wulkanowy.utils.ActivityLifecycleLogger
|
import io.github.wulkanowy.utils.ActivityLifecycleLogger
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||||
import io.github.wulkanowy.utils.DebugLogTree
|
import io.github.wulkanowy.utils.DebugLogTree
|
||||||
|
import io.github.wulkanowy.utils.initCrashlytics
|
||||||
import io.reactivex.exceptions.UndeliverableException
|
import io.reactivex.exceptions.UndeliverableException
|
||||||
import io.reactivex.plugins.RxJavaPlugins
|
import io.reactivex.plugins.RxJavaPlugins
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -30,6 +29,9 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var workerFactory: SyncWorkerFactory
|
lateinit var workerFactory: SyncWorkerFactory
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
override fun attachBaseContext(base: Context?) {
|
override fun attachBaseContext(base: Context?) {
|
||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
MultiDex.install(this)
|
MultiDex.install(this)
|
||||||
@ -38,15 +40,23 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
AndroidThreeTen.init(this)
|
AndroidThreeTen.init(this)
|
||||||
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
|
|
||||||
RxJavaPlugins.setErrorHandler(::onError)
|
RxJavaPlugins.setErrorHandler(::onError)
|
||||||
|
|
||||||
initCrashlytics()
|
initWorkManager()
|
||||||
initLogging()
|
initLogging()
|
||||||
|
initCrashlytics(this, appInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initWorkManager() {
|
||||||
|
WorkManager.initialize(this,
|
||||||
|
Configuration.Builder()
|
||||||
|
.setWorkerFactory(workerFactory)
|
||||||
|
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
|
||||||
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initLogging() {
|
private fun initLogging() {
|
||||||
if (DEBUG) {
|
if (appInfo.isDebug) {
|
||||||
Timber.plant(DebugLogTree())
|
Timber.plant(DebugLogTree())
|
||||||
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
|
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
|
||||||
} else {
|
} else {
|
||||||
@ -55,15 +65,11 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
|
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initCrashlytics() {
|
|
||||||
Fabric.with(Fabric.Builder(this).kits(
|
|
||||||
Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!CRASHLYTICS_ENABLED).build()).build()
|
|
||||||
).debuggable(DEBUG).build())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onError(error: Throwable) {
|
private fun onError(error: Throwable) {
|
||||||
if (error is UndeliverableException && error.cause is IOException || error.cause is InterruptedException) {
|
//RxJava's too deep stack traces may cause SOE on older android devices
|
||||||
Timber.e(error.cause, "An undeliverable error occurred")
|
val cause = error.cause
|
||||||
|
if (error is UndeliverableException && cause is IOException || cause is InterruptedException || cause is StackOverflowError) {
|
||||||
|
Timber.e(cause, "An undeliverable error occurred")
|
||||||
} else throw error
|
} else throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,4 +132,8 @@ internal class RepositoryModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideRecipientDao(database: AppDatabase) = database.recipientDao
|
fun provideRecipientDao(database: AppDatabase) = database.recipientDao
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideMobileDevicesDao(database: AppDatabase) = database.mobileDeviceDao
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
|||||||
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
||||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||||
|
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
|
||||||
import io.github.wulkanowy.data.db.dao.NoteDao
|
import io.github.wulkanowy.data.db.dao.NoteDao
|
||||||
import io.github.wulkanowy.data.db.dao.RecipientDao
|
import io.github.wulkanowy.data.db.dao.RecipientDao
|
||||||
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
|
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
|
||||||
@ -33,6 +34,7 @@ import io.github.wulkanowy.data.db.entities.GradeSummary
|
|||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
|
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||||
import io.github.wulkanowy.data.db.entities.Note
|
import io.github.wulkanowy.data.db.entities.Note
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
import io.github.wulkanowy.data.db.entities.Recipient
|
||||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
||||||
@ -44,6 +46,8 @@ import io.github.wulkanowy.data.db.migrations.Migration10
|
|||||||
import io.github.wulkanowy.data.db.migrations.Migration11
|
import io.github.wulkanowy.data.db.migrations.Migration11
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration12
|
import io.github.wulkanowy.data.db.migrations.Migration12
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration13
|
import io.github.wulkanowy.data.db.migrations.Migration13
|
||||||
|
import io.github.wulkanowy.data.db.migrations.Migration14
|
||||||
|
import io.github.wulkanowy.data.db.migrations.Migration15
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration2
|
import io.github.wulkanowy.data.db.migrations.Migration2
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||||
@ -73,7 +77,8 @@ import javax.inject.Singleton
|
|||||||
LuckyNumber::class,
|
LuckyNumber::class,
|
||||||
CompletedLesson::class,
|
CompletedLesson::class,
|
||||||
ReportingUnit::class,
|
ReportingUnit::class,
|
||||||
Recipient::class
|
Recipient::class,
|
||||||
|
MobileDevice::class
|
||||||
],
|
],
|
||||||
version = AppDatabase.VERSION_SCHEMA,
|
version = AppDatabase.VERSION_SCHEMA,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
@ -82,7 +87,7 @@ import javax.inject.Singleton
|
|||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VERSION_SCHEMA = 13
|
const val VERSION_SCHEMA = 15
|
||||||
|
|
||||||
fun newInstance(context: Context): AppDatabase {
|
fun newInstance(context: Context): AppDatabase {
|
||||||
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
|
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
|
||||||
@ -101,7 +106,9 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
Migration10(),
|
Migration10(),
|
||||||
Migration11(),
|
Migration11(),
|
||||||
Migration12(),
|
Migration12(),
|
||||||
Migration13()
|
Migration13(),
|
||||||
|
Migration14(),
|
||||||
|
Migration15()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@ -140,4 +147,6 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
abstract val reportingUnitDao: ReportingUnitDao
|
abstract val reportingUnitDao: ReportingUnitDao
|
||||||
|
|
||||||
abstract val recipientDao: RecipientDao
|
abstract val recipientDao: RecipientDao
|
||||||
|
|
||||||
|
abstract val mobileDeviceDao: MobileDeviceDao
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package io.github.wulkanowy.data.db.dao
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.Query
|
||||||
|
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface MobileDeviceDao {
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
fun insertAll(devices: List<MobileDevice>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
fun deleteAll(devices: List<MobileDevice>)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC")
|
||||||
|
fun loadAll(studentId: Int): Maybe<List<MobileDevice>>
|
||||||
|
}
|
@ -13,11 +13,26 @@ data class GradeSummary(
|
|||||||
@ColumnInfo(name = "student_id")
|
@ColumnInfo(name = "student_id")
|
||||||
val studentId: Int,
|
val studentId: Int,
|
||||||
|
|
||||||
|
val position: Int,
|
||||||
|
|
||||||
val subject: String,
|
val subject: String,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "predicted_grade")
|
||||||
val predictedGrade: String,
|
val predictedGrade: String,
|
||||||
|
|
||||||
val finalGrade: String
|
@ColumnInfo(name = "final_grade")
|
||||||
|
val finalGrade: String,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "proposed_points")
|
||||||
|
val proposedPoints: String,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "final_points")
|
||||||
|
val finalPoints: String,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "points_sum")
|
||||||
|
val pointsSum: String,
|
||||||
|
|
||||||
|
val average: Double
|
||||||
) {
|
) {
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.github.wulkanowy.data.db.entities
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import org.threeten.bp.LocalDateTime
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity(tableName = "MobileDevices")
|
||||||
|
data class MobileDevice(
|
||||||
|
|
||||||
|
@ColumnInfo(name = "student_id")
|
||||||
|
val studentId: Int,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "device_id")
|
||||||
|
val deviceId: Int,
|
||||||
|
|
||||||
|
val name: String,
|
||||||
|
|
||||||
|
val date: LocalDateTime
|
||||||
|
) : Serializable {
|
||||||
|
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Long = 0
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package io.github.wulkanowy.data.db.migrations
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration14 : Migration(13, 14) {
|
||||||
|
|
||||||
|
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,
|
||||||
|
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
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.github.wulkanowy.data.db.migrations
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration15 : Migration(14, 15) {
|
||||||
|
|
||||||
|
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,
|
||||||
|
device_id INTEGER NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
date INTEGER NOT NULL
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package io.github.wulkanowy.data.pojos
|
||||||
|
|
||||||
|
data class MobileDeviceToken(
|
||||||
|
|
||||||
|
val token: String,
|
||||||
|
|
||||||
|
val symbol: String,
|
||||||
|
|
||||||
|
val pin: String,
|
||||||
|
|
||||||
|
val qr: String
|
||||||
|
)
|
@ -18,9 +18,14 @@ class GradeSummaryRemote @Inject constructor(private val api: Api) {
|
|||||||
GradeSummary(
|
GradeSummary(
|
||||||
semesterId = semester.semesterId,
|
semesterId = semester.semesterId,
|
||||||
studentId = semester.studentId,
|
studentId = semester.studentId,
|
||||||
|
position = it.order,
|
||||||
subject = it.name,
|
subject = it.name,
|
||||||
predictedGrade = it.predicted,
|
predictedGrade = it.predicted,
|
||||||
finalGrade = it.final
|
finalGrade = it.final,
|
||||||
|
pointsSum = it.pointsSum,
|
||||||
|
proposedPoints = it.proposedPoints,
|
||||||
|
finalPoints = it.finalPoints,
|
||||||
|
average = it.average
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
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 io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.reactivex.Maybe
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class MobileDeviceLocal @Inject constructor(private val mobileDb: MobileDeviceDao) {
|
||||||
|
|
||||||
|
fun saveDevices(devices: List<MobileDevice>) {
|
||||||
|
mobileDb.insertAll(devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteDevices(devices: List<MobileDevice>) {
|
||||||
|
mobileDb.deleteAll(devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDevices(semester: Semester): Maybe<List<MobileDevice>> {
|
||||||
|
return mobileDb.loadAll(semester.studentId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.mobiledevice
|
||||||
|
|
||||||
|
import io.github.wulkanowy.api.Api
|
||||||
|
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.pojos.MobileDeviceToken
|
||||||
|
import io.github.wulkanowy.utils.toLocalDateTime
|
||||||
|
import io.reactivex.Single
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class MobileDeviceRemote @Inject constructor(private val api: Api) {
|
||||||
|
|
||||||
|
fun getDevices(semester: Semester): Single<List<MobileDevice>> {
|
||||||
|
return Single.just(api.apply { diaryId = semester.diaryId })
|
||||||
|
.flatMap { api.getRegisteredDevices() }
|
||||||
|
.map { devices ->
|
||||||
|
devices.map {
|
||||||
|
MobileDevice(
|
||||||
|
studentId = semester.studentId,
|
||||||
|
date = it.date.toLocalDateTime(),
|
||||||
|
deviceId = it.id,
|
||||||
|
name = it.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
|
||||||
|
return Single.just(api.apply { diaryId = semester.diaryId })
|
||||||
|
.flatMap { api.unregisterDevice(device.deviceId) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getToken(semester: Semester): Single<MobileDeviceToken> {
|
||||||
|
return Single.just(api.apply { diaryId = semester.diaryId })
|
||||||
|
.flatMap { api.getToken() }
|
||||||
|
.map {
|
||||||
|
MobileDeviceToken(
|
||||||
|
token = it.token,
|
||||||
|
symbol = it.symbol,
|
||||||
|
pin = it.pin,
|
||||||
|
qr = it.qrCodeImage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.mobiledevice
|
||||||
|
|
||||||
|
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||||
|
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||||
|
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.pojos.MobileDeviceToken
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
|
import io.reactivex.Single
|
||||||
|
import java.net.UnknownHostException
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class MobileDeviceRepository @Inject constructor(
|
||||||
|
private val settings: InternetObservingSettings,
|
||||||
|
private val local: MobileDeviceLocal,
|
||||||
|
private val remote: MobileDeviceRemote
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun getDevices(semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
|
||||||
|
return local.getDevices(semester).filter { !forceRefresh }
|
||||||
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
.flatMap {
|
||||||
|
if (it) remote.getDevices(semester)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}.flatMap { new ->
|
||||||
|
local.getDevices(semester).toSingle(emptyList())
|
||||||
|
.doOnSuccess { old ->
|
||||||
|
local.deleteDevices(old uniqueSubtract new)
|
||||||
|
local.saveDevices(new uniqueSubtract old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).flatMap { local.getDevices(semester).toSingle(emptyList()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
|
||||||
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
.flatMap {
|
||||||
|
if (it) remote.unregisterDevice(semester, device)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getToken(semester: Semester): Single<MobileDeviceToken> {
|
||||||
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
.flatMap {
|
||||||
|
if (it) remote.getToken(semester)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,9 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val gradeAverageMode: String
|
val gradeAverageMode: String
|
||||||
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_average_mode), "only_one_semester") ?: "only_one_semester"
|
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_average_mode), "only_one_semester") ?: "only_one_semester"
|
||||||
|
|
||||||
|
val gradeAverageForceCalc: Boolean
|
||||||
|
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_grade_average_force_calc), false)
|
||||||
|
|
||||||
val isGradeExpandable: Boolean
|
val isGradeExpandable: Boolean
|
||||||
get() = !sharedPref.getBoolean(context.getString(R.string.pref_key_expand_grade), false)
|
get() = !sharedPref.getBoolean(context.getString(R.string.pref_key_expand_grade), false)
|
||||||
|
|
||||||
@ -40,7 +43,7 @@ class PreferencesRepository @Inject constructor(
|
|||||||
|
|
||||||
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
|
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only)
|
||||||
val isServicesOnlyWifi: Boolean
|
val isServicesOnlyWifi: Boolean
|
||||||
get() = sharedPref.getBoolean(servicesOnlyWifiKey, true)
|
get() = sharedPref.getBoolean(servicesOnlyWifiKey, false)
|
||||||
|
|
||||||
val isNotificationsEnable: Boolean
|
val isNotificationsEnable: Boolean
|
||||||
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_notifications_enable), true)
|
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_notifications_enable), true)
|
||||||
|
@ -2,15 +2,13 @@ package io.github.wulkanowy.di
|
|||||||
|
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.BuildConfig.DEBUG
|
|
||||||
import io.github.wulkanowy.WulkanowyApp
|
import io.github.wulkanowy.WulkanowyApp
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import javax.inject.Named
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@ -27,16 +25,11 @@ internal class AppModule {
|
|||||||
@Provides
|
@Provides
|
||||||
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
fun provideFirebaseAnalytics(context: Context) = FirebaseAnalytics.getInstance(context)
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context)
|
fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("isDebug")
|
|
||||||
@Provides
|
@Provides
|
||||||
fun provideIsDebug() = DEBUG
|
fun provideAppInfo() = AppInfo()
|
||||||
}
|
}
|
||||||
|
@ -10,30 +10,46 @@ import androidx.work.NetworkType.CONNECTED
|
|||||||
import androidx.work.NetworkType.UNMETERED
|
import androidx.work.NetworkType.UNMETERED
|
||||||
import androidx.work.PeriodicWorkRequest
|
import androidx.work.PeriodicWorkRequest
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
|
import io.github.wulkanowy.data.db.SharedPrefHelper
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit.MINUTES
|
import java.util.concurrent.TimeUnit.MINUTES
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class SyncManager @Inject constructor(
|
class SyncManager @Inject constructor(
|
||||||
private val workManager: WorkManager,
|
private val workManager: WorkManager,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
|
sharedPrefHelper: SharedPrefHelper,
|
||||||
newEntriesChannel: NewEntriesChannel,
|
newEntriesChannel: NewEntriesChannel,
|
||||||
debugChannel: DebugChannel,
|
debugChannel: DebugChannel,
|
||||||
@Named("isDebug") isDebug: Boolean
|
appInfo: AppInfo
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val APP_VERSION_CODE_KEY = "app_version_code"
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (SDK_INT >= O) newEntriesChannel.create()
|
|
||||||
if (SDK_INT >= O && isDebug) debugChannel.create()
|
|
||||||
if (now().isHolidays) stopSyncWorker()
|
if (now().isHolidays) stopSyncWorker()
|
||||||
|
|
||||||
|
if (SDK_INT > O) {
|
||||||
|
newEntriesChannel.create()
|
||||||
|
if (appInfo.isDebug) debugChannel.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sharedPrefHelper.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
|
||||||
|
startSyncWorker(true)
|
||||||
|
sharedPrefHelper.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
|
||||||
|
}
|
||||||
|
|
||||||
Timber.i("SyncManager was initialized")
|
Timber.i("SyncManager was initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import dagger.android.DispatchingAndroidInjector
|
import dagger.android.DispatchingAndroidInjector
|
||||||
import dagger.android.support.HasSupportFragmentInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class BaseActivity : AppCompatActivity(), BaseView, HasSupportFragmentInjector {
|
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>
|
lateinit var androidInjector: DispatchingAndroidInjector<Any>
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var fragmentLifecycleLogger: FragmentLifecycleLogger
|
lateinit var fragmentLifecycleLogger: FragmentLifecycleLogger
|
||||||
@ -28,6 +31,8 @@ abstract class BaseActivity : AppCompatActivity(), BaseView, HasSupportFragmentI
|
|||||||
|
|
||||||
protected var messageContainer: View? = null
|
protected var messageContainer: View? = null
|
||||||
|
|
||||||
|
abstract var presenter: T
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
AndroidInjection.inject(this)
|
AndroidInjection.inject(this)
|
||||||
themeManager.applyTheme(this)
|
themeManager.applyTheme(this)
|
||||||
@ -51,10 +56,25 @@ abstract class BaseActivity : AppCompatActivity(), BaseView, HasSupportFragmentI
|
|||||||
else Toast.makeText(this, text, Toast.LENGTH_LONG).show()
|
else Toast.makeText(this, text, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.onExpiredLoginSelected() }
|
||||||
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openClearLoginView() {
|
||||||
|
startActivity(LoginActivity.getStartIntent(this)
|
||||||
|
.apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) })
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
|
presenter.onDetachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun supportFragmentInjector() = supportFragmentInjector
|
override fun androidInjector() = androidInjector
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
|
|||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
(activity as? BaseActivity)?.showError(text, error)
|
(activity as? BaseActivity<*>)?.showError(text, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,15 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
|
|||||||
if (messageContainer != null) {
|
if (messageContainer != null) {
|
||||||
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
|
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
|
||||||
} else {
|
} else {
|
||||||
(activity as? BaseActivity)?.showMessage(text)
|
(activity as? BaseActivity<*>)?.showMessage(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun showExpiredDialog() {
|
||||||
|
(activity as? BaseActivity<*>)?.showExpiredDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun openClearLoginView() {
|
||||||
|
(activity as? BaseActivity<*>)?.openClearLoginView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.reactivex.Completable
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
open class BasePresenter<T : BaseView>(private val errorHandler: ErrorHandler) {
|
open class BasePresenter<T : BaseView>(
|
||||||
|
protected val errorHandler: ErrorHandler,
|
||||||
|
protected val studentRepository: StudentRepository,
|
||||||
|
protected val schedulers: SchedulersProvider
|
||||||
|
) {
|
||||||
|
|
||||||
val disposable = CompositeDisposable()
|
val disposable = CompositeDisposable()
|
||||||
|
|
||||||
@ -10,7 +18,33 @@ open class BasePresenter<T : BaseView>(private val errorHandler: ErrorHandler) {
|
|||||||
|
|
||||||
open fun onAttachView(view: T) {
|
open fun onAttachView(view: T) {
|
||||||
this.view = view
|
this.view = view
|
||||||
errorHandler.showErrorMessage = { text, error -> view.showError(text, error) }
|
errorHandler.apply {
|
||||||
|
showErrorMessage = view::showError
|
||||||
|
onSessionExpired = view::showExpiredDialog
|
||||||
|
onNoCurrentStudent = view::openClearLoginView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onExpiredLoginSelected() {
|
||||||
|
Timber.i("Attempt to switch the student after the session expires")
|
||||||
|
disposable.add(studentRepository.getCurrentStudent(false)
|
||||||
|
.flatMapCompletable { studentRepository.logoutStudent(it) }
|
||||||
|
.andThen(studentRepository.getSavedStudents(false))
|
||||||
|
.flatMapCompletable {
|
||||||
|
if (it.isNotEmpty()) {
|
||||||
|
Timber.i("Switching current student")
|
||||||
|
studentRepository.switchStudent(it[0])
|
||||||
|
} else Completable.complete()
|
||||||
|
}
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
Timber.i("Switch student result: Open login view")
|
||||||
|
view?.openClearLoginView()
|
||||||
|
}, {
|
||||||
|
Timber.i("Switch student result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun onDetachView() {
|
open fun onDetachView() {
|
||||||
|
@ -5,4 +5,8 @@ interface BaseView {
|
|||||||
fun showError(text: String, error: Throwable)
|
fun showError(text: String, error: Throwable)
|
||||||
|
|
||||||
fun showMessage(text: String)
|
fun showMessage(text: String)
|
||||||
|
|
||||||
|
fun showExpiredDialog()
|
||||||
|
|
||||||
|
fun openClearLoginView()
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import com.readystatesoftware.chuck.api.ChuckCollector
|
|||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.api.interceptor.FeatureDisabledException
|
import io.github.wulkanowy.api.interceptor.FeatureDisabledException
|
||||||
import io.github.wulkanowy.api.interceptor.ServiceUnavailableException
|
import io.github.wulkanowy.api.interceptor.ServiceUnavailableException
|
||||||
|
import io.github.wulkanowy.api.login.BadCredentialsException
|
||||||
import io.github.wulkanowy.api.login.NotLoggedInException
|
import io.github.wulkanowy.api.login.NotLoggedInException
|
||||||
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
|
import io.github.wulkanowy.utils.security.ScramblerException
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
@ -15,6 +18,10 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
|
|||||||
|
|
||||||
var showErrorMessage: (String, Throwable) -> Unit = { _, _ -> }
|
var showErrorMessage: (String, Throwable) -> Unit = { _, _ -> }
|
||||||
|
|
||||||
|
var onSessionExpired: () -> Unit = {}
|
||||||
|
|
||||||
|
var onNoCurrentStudent: () -> Unit = {}
|
||||||
|
|
||||||
fun dispatch(error: Throwable) {
|
fun dispatch(error: Throwable) {
|
||||||
chuckCollector.onError(error.javaClass.simpleName, error)
|
chuckCollector.onError(error.javaClass.simpleName, error)
|
||||||
Timber.e(error, "An exception occurred while the Wulkanowy was running")
|
Timber.e(error, "An exception occurred while the Wulkanowy was running")
|
||||||
@ -22,17 +29,23 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun proceed(error: Throwable) {
|
protected open fun proceed(error: Throwable) {
|
||||||
showErrorMessage((when (error) {
|
resources.run {
|
||||||
is UnknownHostException -> resources.getString(R.string.error_no_internet)
|
when (error) {
|
||||||
is SocketTimeoutException -> resources.getString(R.string.error_timeout)
|
is UnknownHostException -> showErrorMessage(getString(R.string.error_no_internet), error)
|
||||||
is NotLoggedInException -> resources.getString(R.string.error_login_failed)
|
is SocketTimeoutException -> showErrorMessage(getString(R.string.error_timeout), error)
|
||||||
is ServiceUnavailableException -> resources.getString(R.string.error_service_unavailable)
|
is NotLoggedInException -> showErrorMessage(getString(R.string.error_login_failed), error)
|
||||||
is FeatureDisabledException -> resources.getString(R.string.error_feature_disabled)
|
is ServiceUnavailableException -> showErrorMessage(getString(R.string.error_service_unavailable), error)
|
||||||
else -> resources.getString(R.string.error_unknown)
|
is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error)
|
||||||
}), error)
|
is ScramblerException, is BadCredentialsException -> onSessionExpired()
|
||||||
|
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||||
|
else -> showErrorMessage(getString(R.string.error_unknown), error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun clear() {
|
open fun clear() {
|
||||||
showErrorMessage = { _, _ -> }
|
showErrorMessage = { _, _ -> }
|
||||||
|
onSessionExpired = {}
|
||||||
|
onNoCurrentStudent = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.base.session
|
|
||||||
|
|
||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
|
||||||
|
|
||||||
open class BaseSessionFragment : BaseFragment(), BaseSessionView {
|
|
||||||
|
|
||||||
override fun showExpiredDialog() {
|
|
||||||
(activity as? MainActivity)?.showExpiredDialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun openLoginView() {
|
|
||||||
activity?.also {
|
|
||||||
startActivity(LoginActivity.getStartIntent(it)
|
|
||||||
.apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.base.session
|
|
||||||
|
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
|
||||||
|
|
||||||
open class BaseSessionPresenter<T : BaseSessionView>(private val errorHandler: SessionErrorHandler) :
|
|
||||||
BasePresenter<T>(errorHandler) {
|
|
||||||
|
|
||||||
override fun onAttachView(view: T) {
|
|
||||||
super.onAttachView(view)
|
|
||||||
errorHandler.apply {
|
|
||||||
onDecryptionFail = { view.showExpiredDialog() }
|
|
||||||
onNoCurrentStudent = { view.openLoginView() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.base.session
|
|
||||||
|
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
|
||||||
|
|
||||||
interface BaseSessionView : BaseView {
|
|
||||||
|
|
||||||
fun showExpiredDialog()
|
|
||||||
|
|
||||||
fun openLoginView()
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.base.session
|
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
import com.readystatesoftware.chuck.api.ChuckCollector
|
|
||||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
|
||||||
import io.github.wulkanowy.utils.security.ScramblerException
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
open class SessionErrorHandler @Inject constructor(
|
|
||||||
resources: Resources,
|
|
||||||
chuckCollector: ChuckCollector
|
|
||||||
) : ErrorHandler(resources, chuckCollector) {
|
|
||||||
|
|
||||||
var onDecryptionFail: () -> Unit = {}
|
|
||||||
|
|
||||||
var onNoCurrentStudent: () -> Unit = {}
|
|
||||||
|
|
||||||
override fun proceed(error: Throwable) {
|
|
||||||
when (error) {
|
|
||||||
is ScramblerException -> onDecryptionFail()
|
|
||||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
|
||||||
else -> super.proceed(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun clear() {
|
|
||||||
super.clear()
|
|
||||||
onDecryptionFail = {}
|
|
||||||
onNoCurrentStudent = {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,10 +8,10 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||||
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
import com.mikepenz.aboutlibraries.LibsFragmentCompat
|
||||||
import io.github.wulkanowy.BuildConfig
|
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
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.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.withOnExtraListener
|
import io.github.wulkanowy.utils.withOnExtraListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -24,6 +24,9 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var fragmentCompat: LibsFragmentCompat
|
lateinit var fragmentCompat: LibsFragmentCompat
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = AboutFragment()
|
fun newInstance() = AboutFragment()
|
||||||
}
|
}
|
||||||
@ -71,9 +74,9 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
putExtra(Intent.EXTRA_EMAIL, Array(1) { "wulkanowyinc@gmail.com" })
|
putExtra(Intent.EXTRA_EMAIL, Array(1) { "wulkanowyinc@gmail.com" })
|
||||||
putExtra(Intent.EXTRA_SUBJECT, "Zgłoszenie błędu")
|
putExtra(Intent.EXTRA_SUBJECT, "Zgłoszenie błędu")
|
||||||
putExtra(Intent.EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n" + "-".repeat(40) + "\n" + """
|
putExtra(Intent.EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n" + "-".repeat(40) + "\n" + """
|
||||||
Build: ${BuildConfig.VERSION_CODE}
|
Build: ${appInfo.versionCode}
|
||||||
SDK: ${android.os.Build.VERSION.SDK_INT}
|
SDK: ${appInfo.systemVersion}
|
||||||
Device: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}
|
Device: ${appInfo.systemManufacturer} ${appInfo.systemModel}
|
||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,16 +4,20 @@ import com.mikepenz.aboutlibraries.Libs
|
|||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL3
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL3
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AboutPresenter @Inject constructor(
|
class AboutPresenter @Inject constructor(
|
||||||
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<AboutView>(errorHandler) {
|
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: AboutView) {
|
override fun onAttachView(view: AboutView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account
|
package io.github.wulkanowy.ui.modules.account
|
||||||
|
|
||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -14,6 +12,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.dialog_account.*
|
import kotlinx.android.synthetic.main.dialog_account.*
|
||||||
@ -73,16 +72,17 @@ class AccountDialog : DaggerAppCompatDialogFragment(), AccountView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun openLoginView() {
|
override fun openLoginView() {
|
||||||
activity?.also {
|
activity?.let {
|
||||||
startActivity(LoginActivity.getStartIntent(it))
|
startActivity(LoginActivity.getStartIntent(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openClearLoginView() {
|
override fun showExpiredDialog() {
|
||||||
activity?.also {
|
(activity as? BaseActivity<*>)?.showExpiredDialog()
|
||||||
startActivity(LoginActivity.getStartIntent(it)
|
|
||||||
.apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun openClearLoginView() {
|
||||||
|
(activity as? BaseActivity<*>)?.openClearLoginView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showConfirmDialog() {
|
override fun showConfirmDialog() {
|
||||||
|
@ -11,11 +11,11 @@ import timber.log.Timber
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AccountPresenter @Inject constructor(
|
class AccountPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val studentRepository: StudentRepository,
|
errorHandler: ErrorHandler,
|
||||||
private val syncManager: SyncManager,
|
studentRepository: StudentRepository,
|
||||||
private val schedulers: SchedulersProvider
|
private val syncManager: SyncManager
|
||||||
) : BasePresenter<AccountView>(errorHandler) {
|
) : BasePresenter<AccountView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: AccountView) {
|
override fun onAttachView(view: AccountView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
@ -14,8 +14,6 @@ interface AccountView : BaseView {
|
|||||||
|
|
||||||
fun openLoginView()
|
fun openLoginView()
|
||||||
|
|
||||||
fun openClearLoginView()
|
|
||||||
|
|
||||||
fun recreateMainView()
|
fun recreateMainView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
|||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Attendance
|
import io.github.wulkanowy.data.db.entities.Attendance
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
@ -21,7 +21,7 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
|||||||
import kotlinx.android.synthetic.main.fragment_attendance.*
|
import kotlinx.android.synthetic.main.fragment_attendance.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendanceFragment : BaseSessionFragment(), AttendanceView, MainView.MainChildView, MainView.TitledView {
|
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: AttendancePresenter
|
lateinit var presenter: AttendancePresenter
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance
|
package io.github.wulkanowy.ui.modules.attendance
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
||||||
@ -23,14 +23,16 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendancePresenter @Inject constructor(
|
class AttendancePresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val attendanceRepository: AttendanceRepository,
|
private val attendanceRepository: AttendanceRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val prefRepository: PreferencesRepository,
|
private val prefRepository: PreferencesRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<AttendanceView>(errorHandler) {
|
) : BasePresenter<AttendanceView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
|
private var baseDate: LocalDate = now().previousOrSameSchoolDay
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
private set
|
private set
|
||||||
@ -39,7 +41,8 @@ class AttendancePresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.initView()
|
view.initView()
|
||||||
Timber.i("Attendance view was initialized")
|
Timber.i("Attendance view was initialized")
|
||||||
loadData(ofEpochDay(date ?: now().previousOrSameSchoolDay.toEpochDay()))
|
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
||||||
|
if (currentDate.isHolidays) setBaseDateOnHolidays()
|
||||||
reloadView()
|
reloadView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +65,7 @@ class AttendancePresenter @Inject constructor(
|
|||||||
Timber.i("Attendance view is reselected")
|
Timber.i("Attendance view is reselected")
|
||||||
view?.also { view ->
|
view?.also { view ->
|
||||||
if (view.currentStackSize == 1) {
|
if (view.currentStackSize == 1) {
|
||||||
now().previousOrSameSchoolDay.also {
|
baseDate.also {
|
||||||
if (currentDate != it) {
|
if (currentDate != it) {
|
||||||
loadData(it)
|
loadData(it)
|
||||||
reloadView()
|
reloadView()
|
||||||
@ -84,6 +87,20 @@ class AttendancePresenter @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setBaseDateOnHolidays() {
|
||||||
|
disposable.add(studentRepository.getCurrentStudent()
|
||||||
|
.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
|
currentDate = baseDate
|
||||||
|
reloadNavigation()
|
||||||
|
}) {
|
||||||
|
Timber.i("Loading semester result: An exception occurred")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading attendance data started")
|
Timber.i("Loading attendance data started")
|
||||||
currentDate = date
|
currentDate = date
|
||||||
@ -115,7 +132,7 @@ class AttendancePresenter @Inject constructor(
|
|||||||
showEmpty(it.isEmpty())
|
showEmpty(it.isEmpty())
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_attendance", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
analytics.logEvent("load_attendance", "items" to it.size, "force_refresh" to forceRefresh)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading attendance result: An exception occurred")
|
Timber.i("Loading attendance result: An exception occurred")
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
@ -133,8 +150,14 @@ class AttendancePresenter @Inject constructor(
|
|||||||
showContent(false)
|
showContent(false)
|
||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
clearData()
|
clearData()
|
||||||
showNextButton(!currentDate.plusDays(1).isHolidays)
|
reloadNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reloadNavigation() {
|
||||||
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(1).isHolidays)
|
showPreButton(!currentDate.minusDays(1).isHolidays)
|
||||||
|
showNextButton(!currentDate.plusDays(1).isHolidays)
|
||||||
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize())
|
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance
|
package io.github.wulkanowy.ui.modules.attendance
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Attendance
|
import io.github.wulkanowy.data.db.entities.Attendance
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface AttendanceView : BaseSessionView {
|
interface AttendanceView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
||||||
import kotlinx.android.synthetic.main.fragment_attendance_summary.*
|
import kotlinx.android.synthetic.main.fragment_attendance_summary.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendanceSummaryFragment : BaseSessionFragment(), AttendanceSummaryView, MainView.TitledView {
|
class AttendanceSummaryFragment : BaseFragment(), AttendanceSummaryView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: AttendanceSummaryPresenter
|
lateinit var presenter: AttendanceSummaryPresenter
|
||||||
|
@ -6,8 +6,8 @@ import io.github.wulkanowy.data.repositories.attendancesummary.AttendanceSummary
|
|||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.subject.SubjectRepository
|
import io.github.wulkanowy.data.repositories.subject.SubjectRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.calculatePercentage
|
import io.github.wulkanowy.utils.calculatePercentage
|
||||||
@ -19,14 +19,14 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendanceSummaryPresenter @Inject constructor(
|
class AttendanceSummaryPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val attendanceSummaryRepository: AttendanceSummaryRepository,
|
private val attendanceSummaryRepository: AttendanceSummaryRepository,
|
||||||
private val subjectRepository: SubjectRepository,
|
private val subjectRepository: SubjectRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val schedulers: SchedulersProvider,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<AttendanceSummaryView>(errorHandler) {
|
) : BasePresenter<AttendanceSummaryView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var subjects = emptyList<Subject>()
|
private var subjects = emptyList<Subject>()
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance.summary
|
package io.github.wulkanowy.ui.modules.attendance.summary
|
||||||
|
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface AttendanceSummaryView : BaseSessionView {
|
interface AttendanceSummaryView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -13,14 +13,14 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
|||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_exam.*
|
import kotlinx.android.synthetic.main.fragment_exam.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExamFragment : BaseSessionFragment(), ExamView, MainView.MainChildView, MainView.TitledView {
|
class ExamFragment : BaseFragment(), ExamView, MainView.MainChildView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: ExamPresenter
|
lateinit var presenter: ExamPresenter
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.exam
|
package io.github.wulkanowy.ui.modules.exam
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
@ -23,13 +23,15 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExamPresenter @Inject constructor(
|
class ExamPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val examRepository: ExamRepository,
|
private val examRepository: ExamRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<ExamView>(errorHandler) {
|
) : BasePresenter<ExamView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
|
private var baseDate: LocalDate = now().nextOrSameSchoolDay
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
private set
|
private set
|
||||||
@ -38,7 +40,8 @@ class ExamPresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.initView()
|
view.initView()
|
||||||
Timber.i("Exam view was initialized")
|
Timber.i("Exam view was initialized")
|
||||||
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay()))
|
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
||||||
|
if (currentDate.isHolidays) setBaseDateOnHolidays()
|
||||||
reloadView()
|
reloadView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +69,7 @@ class ExamPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onViewReselected() {
|
fun onViewReselected() {
|
||||||
Timber.i("Exam view is reselected")
|
Timber.i("Exam view is reselected")
|
||||||
now().nextOrSameSchoolDay.also {
|
baseDate.also {
|
||||||
if (currentDate != it) {
|
if (currentDate != it) {
|
||||||
loadData(it)
|
loadData(it)
|
||||||
reloadView()
|
reloadView()
|
||||||
@ -74,6 +77,20 @@ class ExamPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setBaseDateOnHolidays() {
|
||||||
|
disposable.add(studentRepository.getCurrentStudent()
|
||||||
|
.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
|
currentDate = baseDate
|
||||||
|
reloadNavigation()
|
||||||
|
}) {
|
||||||
|
Timber.i("Loading semester result: An exception occurred")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading exam data started")
|
Timber.i("Loading exam data started")
|
||||||
currentDate = date
|
currentDate = date
|
||||||
@ -82,9 +99,8 @@ class ExamPresenter @Inject constructor(
|
|||||||
add(studentRepository.getCurrentStudent()
|
add(studentRepository.getCurrentStudent()
|
||||||
.delay(200, MILLISECONDS)
|
.delay(200, MILLISECONDS)
|
||||||
.flatMap { semesterRepository.getCurrentSemester(it) }
|
.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||||
.flatMap {
|
.flatMap { examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh) }
|
||||||
examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh)
|
.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
||||||
}.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
|
||||||
.map { createExamItems(it) }
|
.map { createExamItems(it) }
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
@ -102,7 +118,7 @@ class ExamPresenter @Inject constructor(
|
|||||||
showEmpty(it.isEmpty())
|
showEmpty(it.isEmpty())
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_exam", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
analytics.logEvent("load_exam", "items" to it.size, "force_refresh" to forceRefresh)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading exam result: An exception occurred")
|
Timber.i("Loading exam result: An exception occurred")
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
@ -127,6 +143,12 @@ class ExamPresenter @Inject constructor(
|
|||||||
showContent(false)
|
showContent(false)
|
||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
clearData()
|
clearData()
|
||||||
|
reloadNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reloadNavigation() {
|
||||||
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.exam
|
package io.github.wulkanowy.ui.modules.exam
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface ExamView : BaseSessionView {
|
interface ExamView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -3,16 +3,20 @@ package io.github.wulkanowy.ui.modules.grade
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.utils.calcAverage
|
import io.github.wulkanowy.utils.calcAverage
|
||||||
import io.github.wulkanowy.utils.changeModifier
|
import io.github.wulkanowy.utils.changeModifier
|
||||||
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeAverageProvider @Inject constructor(
|
class GradeAverageProvider @Inject constructor(
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val gradeRepository: GradeRepository
|
private val gradeRepository: GradeRepository,
|
||||||
|
private val gradeSummaryRepository: GradeSummaryRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getGradeAverage(student: Student, semesters: List<Semester>, selectedSemesterId: Int, forceRefresh: Boolean): Single<Map<String, Double>> {
|
fun getGradeAverage(student: Student, semesters: List<Semester>, selectedSemesterId: Int, forceRefresh: Boolean): Single<Map<String, Double>> {
|
||||||
return when (preferencesRepository.gradeAverageMode) {
|
return when (preferencesRepository.gradeAverageMode) {
|
||||||
"all_year" -> getAllYearAverage(student, semesters, selectedSemesterId, forceRefresh)
|
"all_year" -> getAllYearAverage(student, semesters, selectedSemesterId, forceRefresh)
|
||||||
@ -27,16 +31,19 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
val plusModifier = preferencesRepository.gradePlusModifier
|
val plusModifier = preferencesRepository.gradePlusModifier
|
||||||
val minusModifier = preferencesRepository.gradeMinusModifier
|
val minusModifier = preferencesRepository.gradeMinusModifier
|
||||||
|
|
||||||
return gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
return getAverageFromGradeSummary(selectedSemester, forceRefresh)
|
||||||
|
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
||||||
.flatMap { firstGrades ->
|
.flatMap { firstGrades ->
|
||||||
if (selectedSemester == firstSemester) Single.just(firstGrades)
|
if (selectedSemester == firstSemester) Single.just(firstGrades)
|
||||||
else gradeRepository.getGrades(student, firstSemester)
|
else {
|
||||||
|
gradeRepository.getGrades(student, firstSemester)
|
||||||
.map { secondGrades -> secondGrades + firstGrades }
|
.map { secondGrades -> secondGrades + firstGrades }
|
||||||
|
}
|
||||||
}.map { grades ->
|
}.map { grades ->
|
||||||
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
||||||
.groupBy { it.subject }
|
.groupBy { it.subject }
|
||||||
.mapValues { it.value.calcAverage() }
|
.mapValues { it.value.calcAverage() }
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOnlyOneSemesterAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<Map<String, Double>> {
|
private fun getOnlyOneSemesterAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<Map<String, Double>> {
|
||||||
@ -44,11 +51,22 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
val plusModifier = preferencesRepository.gradePlusModifier
|
val plusModifier = preferencesRepository.gradePlusModifier
|
||||||
val minusModifier = preferencesRepository.gradeMinusModifier
|
val minusModifier = preferencesRepository.gradeMinusModifier
|
||||||
|
|
||||||
return gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
return getAverageFromGradeSummary(selectedSemester, forceRefresh)
|
||||||
|
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
|
||||||
.map { grades ->
|
.map { grades ->
|
||||||
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
||||||
.groupBy { it.subject }
|
.groupBy { it.subject }
|
||||||
.mapValues { it.value.calcAverage() }
|
.mapValues { it.value.calcAverage() }
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAverageFromGradeSummary(selectedSemester: Semester, forceRefresh: Boolean): Maybe<Map<String, Double>> {
|
||||||
|
return gradeSummaryRepository.getGradesSummary(selectedSemester, forceRefresh)
|
||||||
|
.toMaybe()
|
||||||
|
.flatMap {
|
||||||
|
if (it.any { summary -> summary.average != .0 }) {
|
||||||
|
Maybe.just(it.map { summary -> summary.subject to summary.average }.toMap())
|
||||||
|
} else Maybe.empty()
|
||||||
|
}.filter { !preferencesRepository.gradeAverageForceCalc }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ import android.view.View.VISIBLE
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
|
||||||
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
|
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
import io.github.wulkanowy.ui.modules.grade.statistics.GradeStatisticsFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
|
||||||
@ -21,7 +21,7 @@ import io.github.wulkanowy.utils.setOnSelectPageListener
|
|||||||
import kotlinx.android.synthetic.main.fragment_grade.*
|
import kotlinx.android.synthetic.main.fragment_grade.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView, MainView.TitledView {
|
class GradeFragment : BaseFragment(), GradeView, MainView.MainChildView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: GradePresenter
|
lateinit var presenter: GradePresenter
|
||||||
|
@ -3,20 +3,20 @@ package io.github.wulkanowy.ui.modules.grade
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradePresenter @Inject constructor(
|
class GradePresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
private val studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<GradeView>(errorHandler) {
|
) : BasePresenter<GradeView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
var selectedIndex = 0
|
var selectedIndex = 0
|
||||||
private set
|
private set
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeView : BaseSessionView {
|
interface GradeView : BaseView {
|
||||||
|
|
||||||
val currentPageIndex: Int
|
val currentPageIndex: Int
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import eu.davidea.flexibleadapter.items.IExpandable
|
|||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeView
|
import io.github.wulkanowy.ui.modules.grade.GradeView
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
@ -25,7 +25,7 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
|||||||
import kotlinx.android.synthetic.main.fragment_grade_details.*
|
import kotlinx.android.synthetic.main.fragment_grade_details.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeDetailsFragment : BaseSessionFragment(), GradeDetailsView, GradeView.GradeChildView {
|
class GradeDetailsFragment : BaseFragment(), GradeDetailsView, GradeView.GradeChildView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: GradeDetailsPresenter
|
lateinit var presenter: GradeDetailsPresenter
|
||||||
|
@ -6,8 +6,8 @@ import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
|||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
@ -16,15 +16,15 @@ import timber.log.Timber
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeDetailsPresenter @Inject constructor(
|
class GradeDetailsPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val gradeRepository: GradeRepository,
|
private val gradeRepository: GradeRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val averageProvider: GradeAverageProvider,
|
private val averageProvider: GradeAverageProvider,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<GradeDetailsView>(errorHandler) {
|
) : BasePresenter<GradeDetailsView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var currentSemesterId = 0
|
private var currentSemesterId = 0
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
.flatMap { (student, semesters) ->
|
.flatMap { (student, semesters) ->
|
||||||
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh)
|
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh)
|
||||||
.flatMap { averages ->
|
.flatMap { averages ->
|
||||||
gradeRepository.getGrades(student, semesters.first { semester -> semester.semesterId == semesterId })
|
gradeRepository.getGrades(student, semesters.first { it.semesterId == semesterId }, forceRefresh)
|
||||||
.map { it.sortedByDescending { grade -> grade.date } }
|
.map { it.sortedByDescending { grade -> grade.date } }
|
||||||
.map { it.groupBy { grade -> grade.subject }.toSortedMap() }
|
.map { it.groupBy { grade -> grade.subject }.toSortedMap() }
|
||||||
.map { createGradeItems(it, averages) }
|
.map { createGradeItems(it, averages) }
|
||||||
|
@ -4,9 +4,9 @@ import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|||||||
import eu.davidea.flexibleadapter.items.IExpandable
|
import eu.davidea.flexibleadapter.items.IExpandable
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeDetailsView : BaseSessionView {
|
interface GradeDetailsView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import com.github.mikephil.charting.data.PieEntry
|
|||||||
import com.github.mikephil.charting.formatter.ValueFormatter
|
import com.github.mikephil.charting.formatter.ValueFormatter
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeView
|
import io.github.wulkanowy.ui.modules.grade.GradeView
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
@ -24,7 +24,7 @@ import io.github.wulkanowy.utils.setOnItemSelectedListener
|
|||||||
import kotlinx.android.synthetic.main.fragment_grade_statistics.*
|
import kotlinx.android.synthetic.main.fragment_grade_statistics.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeStatisticsFragment : BaseSessionFragment(), GradeStatisticsView, GradeView.GradeChildView {
|
class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.GradeChildView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: GradeStatisticsPresenter
|
lateinit var presenter: GradeStatisticsPresenter
|
||||||
|
@ -6,23 +6,23 @@ import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
|||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.subject.SubjectRepository
|
import io.github.wulkanowy.data.repositories.subject.SubjectRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeStatisticsPresenter @Inject constructor(
|
class GradeStatisticsPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val gradeStatisticsRepository: GradeStatisticsRepository,
|
private val gradeStatisticsRepository: GradeStatisticsRepository,
|
||||||
private val subjectRepository: SubjectRepository,
|
private val subjectRepository: SubjectRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val schedulers: SchedulersProvider,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<GradeStatisticsView>(errorHandler) {
|
) : BasePresenter<GradeStatisticsView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var subjects = emptyList<Subject>()
|
private var subjects = emptyList<Subject>()
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.statistics
|
package io.github.wulkanowy.ui.modules.grade.statistics
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeStatisticsView : BaseSessionView {
|
interface GradeStatisticsView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
|||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeView
|
import io.github.wulkanowy.ui.modules.grade.GradeView
|
||||||
import kotlinx.android.synthetic.main.fragment_grade_summary.*
|
import kotlinx.android.synthetic.main.fragment_grade_summary.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeSummaryFragment : BaseSessionFragment(), GradeSummaryView, GradeView.GradeChildView {
|
class GradeSummaryFragment : BaseFragment(), GradeSummaryView, GradeView.GradeChildView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: GradeSummaryPresenter
|
lateinit var presenter: GradeSummaryPresenter
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.summary
|
package io.github.wulkanowy.ui.modules.grade.summary
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
import eu.davidea.flexibleadapter.items.IFlexible
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
import eu.davidea.viewholders.FlexibleViewHolder
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import kotlinx.android.synthetic.main.item_grade_summary.*
|
import kotlinx.android.synthetic.main.item_grade_summary.*
|
||||||
|
|
||||||
class GradeSummaryItem(
|
class GradeSummaryItem(
|
||||||
private val title: String,
|
val summary: GradeSummary,
|
||||||
private val average: String,
|
private val average: String
|
||||||
private val predictedGrade: String,
|
|
||||||
private val finalGrade: String
|
|
||||||
) : AbstractFlexibleItem<GradeSummaryItem.ViewHolder>() {
|
) : AbstractFlexibleItem<GradeSummaryItem.ViewHolder>() {
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.item_grade_summary
|
override fun getLayoutRes() = R.layout.item_grade_summary
|
||||||
@ -22,12 +24,16 @@ class GradeSummaryItem(
|
|||||||
return ViewHolder(view, adapter)
|
return ViewHolder(view, adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>?) {
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>?) {
|
||||||
holder.run {
|
holder.run {
|
||||||
gradeSummaryItemTitle.text = title
|
gradeSummaryItemTitle.text = summary.subject
|
||||||
|
gradeSummaryItemPoints.text = summary.pointsSum
|
||||||
gradeSummaryItemAverage.text = average
|
gradeSummaryItemAverage.text = average
|
||||||
gradeSummaryItemPredicted.text = predictedGrade
|
gradeSummaryItemPredicted.text = "${summary.predictedGrade} ${summary.proposedPoints}".trim()
|
||||||
gradeSummaryItemFinal.text = finalGrade
|
gradeSummaryItemFinal.text = "${summary.finalGrade} ${summary.finalPoints}".trim()
|
||||||
|
|
||||||
|
gradeSummaryItemPointsContainer.visibility = if (summary.pointsSum.isBlank()) GONE else VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,18 +44,16 @@ class GradeSummaryItem(
|
|||||||
other as GradeSummaryItem
|
other as GradeSummaryItem
|
||||||
|
|
||||||
if (average != other.average) return false
|
if (average != other.average) return false
|
||||||
if (title != other.title) return false
|
if (summary != other.summary) return false
|
||||||
if (predictedGrade != other.predictedGrade) return false
|
if (summary.id != other.summary.id) return false
|
||||||
if (finalGrade != other.finalGrade) return false
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = title.hashCode()
|
var result = summary.hashCode()
|
||||||
|
result = 31 * result + summary.id.hashCode()
|
||||||
result = 31 * result + average.hashCode()
|
result = 31 * result + average.hashCode()
|
||||||
result = 31 * result + predictedGrade.hashCode()
|
|
||||||
result = 31 * result + finalGrade.hashCode()
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ import io.github.wulkanowy.data.db.entities.GradeSummary
|
|||||||
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
@ -16,14 +16,14 @@ import java.util.Locale.FRANCE
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeSummaryPresenter @Inject constructor(
|
class GradeSummaryPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val gradeSummaryRepository: GradeSummaryRepository,
|
private val gradeSummaryRepository: GradeSummaryRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val averageProvider: GradeAverageProvider,
|
private val averageProvider: GradeAverageProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<GradeSummaryView>(errorHandler) {
|
) : BasePresenter<GradeSummaryView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: GradeSummaryView) {
|
override fun onAttachView(view: GradeSummaryView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -96,10 +96,8 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
gradesSummary.filter { !checkEmpty(it, filteredAverages) }
|
gradesSummary.filter { !checkEmpty(it, filteredAverages) }
|
||||||
.map {
|
.map {
|
||||||
GradeSummaryItem(
|
GradeSummaryItem(
|
||||||
title = it.subject,
|
summary = it,
|
||||||
average = formatAverage(filteredAverages.getOrElse(it.subject) { 0.0 }, ""),
|
average = formatAverage(filteredAverages.getOrElse(it.subject) { 0.0 }, "")
|
||||||
predictedGrade = it.predictedGrade,
|
|
||||||
finalGrade = it.finalGrade
|
|
||||||
)
|
)
|
||||||
}.let {
|
}.let {
|
||||||
it to GradeSummaryScrollableHeader(
|
it to GradeSummaryScrollableHeader(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.summary
|
package io.github.wulkanowy.ui.modules.grade.summary
|
||||||
|
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeSummaryView : BaseSessionView {
|
interface GradeSummaryView : BaseView {
|
||||||
|
|
||||||
val isViewEmpty: Boolean
|
val isViewEmpty: Boolean
|
||||||
|
|
||||||
|
@ -10,14 +10,14 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
|||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
import io.github.wulkanowy.utils.setOnItemClickListener
|
||||||
import kotlinx.android.synthetic.main.fragment_homework.*
|
import kotlinx.android.synthetic.main.fragment_homework.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeworkFragment : BaseSessionFragment(), HomeworkView, MainView.TitledView {
|
class HomeworkFragment : BaseFragment(), HomeworkView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: HomeworkPresenter
|
lateinit var presenter: HomeworkPresenter
|
||||||
|
@ -1,33 +1,36 @@
|
|||||||
package io.github.wulkanowy.ui.modules.homework
|
package io.github.wulkanowy.ui.modules.homework
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
|
import org.threeten.bp.LocalDate.ofEpochDay
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class HomeworkPresenter @Inject constructor(
|
class HomeworkPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val homeworkRepository: HomeworkRepository,
|
private val homeworkRepository: HomeworkRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<HomeworkView>(errorHandler) {
|
) : BasePresenter<HomeworkView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
|
private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
private set
|
private set
|
||||||
@ -36,7 +39,8 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.initView()
|
view.initView()
|
||||||
Timber.i("Homework view was initialized")
|
Timber.i("Homework view was initialized")
|
||||||
loadData(LocalDate.ofEpochDay(date ?: LocalDate.now().nextOrSameSchoolDay.toEpochDay()))
|
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
||||||
|
if (currentDate.isHolidays) setBaseDateOnHolidays()
|
||||||
reloadView()
|
reloadView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +66,20 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setBaseDateOnHolidays() {
|
||||||
|
disposable.add(studentRepository.getCurrentStudent()
|
||||||
|
.flatMap { semesterRepository.getCurrentSemester(it) }
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
|
currentDate = baseDate
|
||||||
|
reloadNavigation()
|
||||||
|
}) {
|
||||||
|
Timber.i("Loading semester result: An exception occurred")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading homework data started")
|
Timber.i("Loading homework data started")
|
||||||
currentDate = date
|
currentDate = date
|
||||||
@ -89,7 +107,7 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
showEmpty(it.isEmpty())
|
showEmpty(it.isEmpty())
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_homework", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
analytics.logEvent("load_homework", "items" to it.size, "force_refresh" to forceRefresh)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading homework result: An exception occurred")
|
Timber.i("Loading homework result: An exception occurred")
|
||||||
view?.run { showEmpty(isViewEmpty()) }
|
view?.run { showEmpty(isViewEmpty()) }
|
||||||
@ -114,8 +132,14 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
showContent(false)
|
showContent(false)
|
||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
clearData()
|
clearData()
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
reloadNavigation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reloadNavigation() {
|
||||||
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
currentDate.friday.toFormattedString("dd.MM"))
|
currentDate.friday.toFormattedString("dd.MM"))
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.homework
|
package io.github.wulkanowy.ui.modules.homework
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface HomeworkView : BaseSessionView {
|
interface HomeworkView : BaseView {
|
||||||
|
|
||||||
fun initView()
|
fun initView()
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@ import io.github.wulkanowy.utils.setOnSelectPageListener
|
|||||||
import kotlinx.android.synthetic.main.activity_login.*
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginActivity : BaseActivity(), LoginView {
|
class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: LoginPresenter
|
override lateinit var presenter: LoginPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var loginAdapter: BaseFragmentPagerAdapter
|
lateinit var loginAdapter: BaseFragmentPagerAdapter
|
||||||
@ -81,9 +81,4 @@ class LoginActivity : BaseActivity(), LoginView {
|
|||||||
fun onSymbolFragmentAccountLogged(students: List<Student>) {
|
fun onSymbolFragmentAccountLogged(students: List<Student>) {
|
||||||
presenter.onSymbolViewAccountLogged(students)
|
presenter.onSymbolViewAccountLogged(students)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun onDestroy() {
|
|
||||||
presenter.onDetachView()
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login
|
package io.github.wulkanowy.ui.modules.login
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter<LoginView>(errorHandler) {
|
class LoginPresenter @Inject constructor(
|
||||||
|
schedulers: SchedulersProvider,
|
||||||
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository
|
||||||
|
) : BasePresenter<LoginView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: LoginView) {
|
override fun onAttachView(view: LoginView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
@ -10,11 +10,11 @@ import android.view.ViewGroup
|
|||||||
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||||
import android.view.inputmethod.EditorInfo.IME_NULL
|
import android.view.inputmethod.EditorInfo.IME_NULL
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import io.github.wulkanowy.BuildConfig.VERSION_NAME
|
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.hideSoftInput
|
import io.github.wulkanowy.utils.hideSoftInput
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
import io.github.wulkanowy.utils.setOnItemSelectedListener
|
||||||
@ -28,6 +28,9 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: LoginFormPresenter
|
lateinit var presenter: LoginFormPresenter
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = LoginFormFragment()
|
fun newInstance() = LoginFormFragment()
|
||||||
}
|
}
|
||||||
@ -128,7 +131,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
override fun showVersion() {
|
override fun showVersion() {
|
||||||
loginFormVersion.apply {
|
loginFormVersion.apply {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
text = "${getString(R.string.app_name)} $VERSION_NAME"
|
text = "${getString(R.string.app_name)} ${appInfo.versionName}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.form
|
package io.github.wulkanowy.ui.modules.login.form
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Named
|
|
||||||
|
|
||||||
class LoginFormPresenter @Inject constructor(
|
class LoginFormPresenter @Inject constructor(
|
||||||
private val schedulers: SchedulersProvider,
|
schedulers: SchedulersProvider,
|
||||||
private val errorHandler: LoginErrorHandler,
|
studentRepository: StudentRepository,
|
||||||
private val studentRepository: StudentRepository,
|
private val loginErrorHandler: LoginErrorHandler,
|
||||||
private val analytics: FirebaseAnalyticsHelper,
|
private val analytics: FirebaseAnalyticsHelper,
|
||||||
@param:Named("isDebug") private val isDebug: Boolean
|
private val appInfo: AppInfo
|
||||||
) : BasePresenter<LoginFormView>(errorHandler) {
|
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: LoginFormView) {
|
override fun onAttachView(view: LoginFormView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.run {
|
view.run {
|
||||||
initView()
|
initView()
|
||||||
if (isDebug) showVersion() else showPrivacyPolicy()
|
if (appInfo.isDebug) showVersion() else showPrivacyPolicy()
|
||||||
|
|
||||||
errorHandler.onBadCredentials = {
|
loginErrorHandler.onBadCredentials = {
|
||||||
setErrorPassIncorrect()
|
setErrorPassIncorrect()
|
||||||
showSoftKeyboard()
|
showSoftKeyboard()
|
||||||
Timber.i("Entered wrong username or password")
|
Timber.i("Entered wrong username or password")
|
||||||
@ -78,12 +78,12 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
.subscribe({
|
.subscribe({
|
||||||
Timber.i("Login result: Success")
|
Timber.i("Login result: Success")
|
||||||
analytics.logEvent("registration_form", SUCCESS to true, "students" to it.size, "endpoint" to endpoint, "error" to "No error")
|
analytics.logEvent("registration_form", "success" to true, "students" to it.size, "endpoint" to endpoint, "error" to "No error")
|
||||||
view?.notifyParentAccountLogged(it)
|
view?.notifyParentAccountLogged(it)
|
||||||
}, {
|
}, {
|
||||||
Timber.i("Login result: An exception occurred")
|
Timber.i("Login result: An exception occurred")
|
||||||
analytics.logEvent("registration_form", SUCCESS to false, "students" to -1, "endpoint" to endpoint, "error" to it.localizedMessage)
|
analytics.logEvent("registration_form", "success" to false, "students" to -1, "endpoint" to endpoint, "error" to it.message.ifNullOrBlank { "No message" })
|
||||||
errorHandler.dispatch(it)
|
loginErrorHandler.dispatch(it)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
@ -8,27 +7,28 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
|||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginStudentSelectPresenter @Inject constructor(
|
class LoginStudentSelectPresenter @Inject constructor(
|
||||||
private val errorHandler: LoginErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val schedulers: SchedulersProvider,
|
private val loginErrorHandler: LoginErrorHandler,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<LoginStudentSelectView>(errorHandler) {
|
) : BasePresenter<LoginStudentSelectView>(loginErrorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
var students = emptyList<Student>()
|
var students = emptyList<Student>()
|
||||||
|
|
||||||
var selectedStudents = mutableListOf<Student>()
|
private var selectedStudents = mutableListOf<Student>()
|
||||||
|
|
||||||
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
|
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.run {
|
view.run {
|
||||||
initView()
|
initView()
|
||||||
enableSignIn(false)
|
enableSignIn(false)
|
||||||
errorHandler.onStudentDuplicate = {
|
loginErrorHandler.onStudentDuplicate = {
|
||||||
showMessage(it)
|
showMessage(it)
|
||||||
Timber.i("The student already registered in the app was selected")
|
Timber.i("The student already registered in the app was selected")
|
||||||
}
|
}
|
||||||
@ -78,13 +78,13 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
Timber.i("Registration started")
|
Timber.i("Registration started")
|
||||||
}
|
}
|
||||||
.subscribe({
|
.subscribe({
|
||||||
students.forEach { analytics.logEvent("registration_student_select", SUCCESS to true, "endpoint" to it.endpoint, "symbol" to it.symbol, "error" to "No error") }
|
students.forEach { analytics.logEvent("registration_student_select", "success" to true, "endpoint" to it.endpoint, "symbol" to it.symbol, "error" to "No error") }
|
||||||
Timber.i("Registration result: Success")
|
Timber.i("Registration result: Success")
|
||||||
view?.openMainView()
|
view?.openMainView()
|
||||||
}, { error ->
|
}, { error ->
|
||||||
students.forEach { analytics.logEvent("registration_student_select", SUCCESS to false, "endpoint" to it.endpoint, "symbol" to it.symbol, "error" to error.localizedMessage) }
|
students.forEach { analytics.logEvent("registration_student_select", "success" to false, "endpoint" to it.endpoint, "symbol" to it.symbol, "error" to error.message.ifNullOrBlank { "No message" }) }
|
||||||
Timber.i("Registration result: An exception occurred ")
|
Timber.i("Registration result: An exception occurred ")
|
||||||
errorHandler.dispatch(error)
|
loginErrorHandler.dispatch(error)
|
||||||
view?.apply {
|
view?.apply {
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showContent(true)
|
showContent(true)
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.symbol
|
package io.github.wulkanowy.ui.modules.login.symbol
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginSymbolPresenter @Inject constructor(
|
class LoginSymbolPresenter @Inject constructor(
|
||||||
private val studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val errorHandler: LoginErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
private val loginErrorHandler: LoginErrorHandler,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<LoginSymbolView>(errorHandler) {
|
) : BasePresenter<LoginSymbolView>(loginErrorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
var loginData: Triple<String, String, String>? = null
|
var loginData: Triple<String, String, String>? = null
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.subscribe({
|
.subscribe({
|
||||||
analytics.logEvent("registration_symbol", SUCCESS to true, "students" to it.size, "endpoint" to loginData?.third, "symbol" to symbol, "error" to "No error")
|
analytics.logEvent("registration_symbol", "success" to true, "students" to it.size, "endpoint" to loginData?.third, "symbol" to symbol, "error" to "No error")
|
||||||
view?.apply {
|
view?.apply {
|
||||||
if (it.isEmpty()) {
|
if (it.isEmpty()) {
|
||||||
Timber.i("Login with symbol result: Empty student list")
|
Timber.i("Login with symbol result: Empty student list")
|
||||||
@ -71,8 +71,8 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
Timber.i("Login with symbol result: An exception occurred")
|
Timber.i("Login with symbol result: An exception occurred")
|
||||||
analytics.logEvent("registration_symbol", SUCCESS to false, "students" to -1, "endpoint" to loginData?.third, "symbol" to symbol, "error" to it.localizedMessage)
|
analytics.logEvent("registration_symbol", "success" to false, "students" to -1, "endpoint" to loginData?.third, "symbol" to symbol, "error" to it.message.ifNullOrBlank { "No message" })
|
||||||
errorHandler.dispatch(it)
|
loginErrorHandler.dispatch(it)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import kotlinx.android.synthetic.main.fragment_lucky_number.*
|
import kotlinx.android.synthetic.main.fragment_lucky_number.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LuckyNumberFragment : BaseSessionFragment(), LuckyNumberView, MainView.TitledView {
|
class LuckyNumberFragment : BaseFragment(), LuckyNumberView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: LuckyNumberPresenter
|
lateinit var presenter: LuckyNumberPresenter
|
||||||
|
@ -4,20 +4,20 @@ import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository
|
|||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LuckyNumberPresenter @Inject constructor(
|
class LuckyNumberPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val luckyNumberRepository: LuckyNumberRepository,
|
private val luckyNumberRepository: LuckyNumberRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<LuckyNumberView>(errorHandler) {
|
) : BasePresenter<LuckyNumberView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: LuckyNumberView) {
|
override fun onAttachView(view: LuckyNumberView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumber
|
package io.github.wulkanowy.ui.modules.luckynumber
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface LuckyNumberView : BaseSessionView {
|
interface LuckyNumberView : BaseView {
|
||||||
|
|
||||||
fun initView()
|
fun initView()
|
||||||
|
|
||||||
|
@ -16,13 +16,14 @@ import io.github.wulkanowy.utils.setOnItemClickListener
|
|||||||
import kotlinx.android.synthetic.main.activity_widget_configure.*
|
import kotlinx.android.synthetic.main.activity_widget_configure.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LuckyNumberWidgetConfigureActivity : BaseActivity(), LuckyNumberWidgetConfigureView {
|
class LuckyNumberWidgetConfigureActivity : BaseActivity<LuckyNumberWidgetConfigurePresenter>(),
|
||||||
|
LuckyNumberWidgetConfigureView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var configureAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
lateinit var configureAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: LuckyNumberWidgetConfigurePresenter
|
override lateinit var presenter: LuckyNumberWidgetConfigurePresenter
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -69,9 +70,4 @@ class LuckyNumberWidgetConfigureActivity : BaseActivity(), LuckyNumberWidgetConf
|
|||||||
override fun openLoginView() {
|
override fun openLoginView() {
|
||||||
startActivity(LoginActivity.getStartIntent(this))
|
startActivity(LoginActivity.getStartIntent(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
presenter.onDetachView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ import io.github.wulkanowy.utils.SchedulersProvider
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
private val studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
private val sharedPref: SharedPrefHelper
|
private val sharedPref: SharedPrefHelper
|
||||||
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler) {
|
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
private var appWidgetId: Int? = null
|
private var appWidgetId: Int? = null
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@ -22,7 +21,6 @@ import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
|||||||
import io.github.wulkanowy.ui.modules.exam.ExamFragment
|
import io.github.wulkanowy.ui.modules.exam.ExamFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
|
||||||
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
||||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
@ -34,10 +32,10 @@ import io.github.wulkanowy.utils.setOnViewChangeListener
|
|||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MainActivity : BaseActivity(), MainView {
|
class MainActivity : BaseActivity<MainPresenter>(), MainView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: MainPresenter
|
override lateinit var presenter: MainPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var navController: FragNavController
|
lateinit var navController: FragNavController
|
||||||
@ -154,15 +152,6 @@ class MainActivity : BaseActivity(), MainView {
|
|||||||
navController.showDialogFragment(AccountDialog.newInstance())
|
navController.showDialogFragment(AccountDialog.newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showExpiredDialog() {
|
|
||||||
AlertDialog.Builder(this)
|
|
||||||
.setTitle(R.string.main_session_expired)
|
|
||||||
.setMessage(R.string.main_session_relogin)
|
|
||||||
.setPositiveButton(R.string.main_log_in) { _, _ -> presenter.onLoginSelected() }
|
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun notifyMenuViewReselected() {
|
override fun notifyMenuViewReselected() {
|
||||||
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentReselected()
|
(navController.currentStack?.getOrNull(0) as? MainView.MainChildView)?.onFragmentReselected()
|
||||||
}
|
}
|
||||||
@ -183,19 +172,9 @@ class MainActivity : BaseActivity(), MainView {
|
|||||||
presenter.onBackPressed { super.onBackPressed() }
|
presenter.onBackPressed { super.onBackPressed() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openLoginView() {
|
|
||||||
startActivity(LoginActivity.getStartIntent(this)
|
|
||||||
.apply { addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK) })
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
navController.onSaveInstanceState(outState)
|
navController.onSaveInstanceState(outState)
|
||||||
intent.removeExtra(EXTRA_START_MENU)
|
intent.removeExtra(EXTRA_START_MENU)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
presenter.onDetachView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
|||||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
import io.github.wulkanowy.ui.modules.message.MessageModule
|
import io.github.wulkanowy.ui.modules.message.MessageModule
|
||||||
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
|
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.mobiledevice.token.MobileDeviceTokenDialog
|
||||||
|
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.mobiledevice.MobileDeviceModule
|
||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
import io.github.wulkanowy.ui.modules.settings.SettingsFragment
|
||||||
@ -97,4 +100,12 @@ abstract class MainModule {
|
|||||||
@PerFragment
|
@PerFragment
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindAccountDialog(): AccountDialog
|
abstract fun bindAccountDialog(): AccountDialog
|
||||||
|
|
||||||
|
@PerFragment
|
||||||
|
@ContributesAndroidInjector(modules = [MobileDeviceModule::class])
|
||||||
|
abstract fun bindMobileDevices(): MobileDeviceFragment
|
||||||
|
|
||||||
|
@PerFragment
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindMobileDeviceDialog(): MobileDeviceTokenDialog
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package io.github.wulkanowy.ui.modules.main
|
package io.github.wulkanowy.ui.modules.main
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Event.APP_OPEN
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.DESTINATION
|
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
@ -9,18 +7,17 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
|||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.reactivex.Completable
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MainPresenter @Inject constructor(
|
class MainPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val studentRepository: StudentRepository,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val prefRepository: PreferencesRepository,
|
private val prefRepository: PreferencesRepository,
|
||||||
private val syncManager: SyncManager,
|
private val syncManager: SyncManager,
|
||||||
private val schedulers: SchedulersProvider,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<MainView>(errorHandler) {
|
) : BasePresenter<MainView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
fun onAttachView(view: MainView, initMenu: MainView.MenuView?) {
|
fun onAttachView(view: MainView, initMenu: MainView.MenuView?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -34,7 +31,7 @@ class MainPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
syncManager.startSyncWorker()
|
syncManager.startSyncWorker()
|
||||||
analytics.logEvent(APP_OPEN, DESTINATION to initMenu?.name)
|
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewChange() {
|
fun onViewChange() {
|
||||||
@ -80,28 +77,6 @@ class MainPresenter @Inject constructor(
|
|||||||
} == true
|
} == true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onLoginSelected() {
|
|
||||||
Timber.i("Attempt to switch the student after the session expires")
|
|
||||||
disposable.add(studentRepository.getCurrentStudent(false)
|
|
||||||
.flatMapCompletable { studentRepository.logoutStudent(it) }
|
|
||||||
.andThen(studentRepository.getSavedStudents(false))
|
|
||||||
.flatMapCompletable {
|
|
||||||
if (it.isNotEmpty()) {
|
|
||||||
Timber.i("Switching current student")
|
|
||||||
studentRepository.switchStudent(it[0])
|
|
||||||
} else Completable.complete()
|
|
||||||
}
|
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
|
||||||
.observeOn(schedulers.mainThread)
|
|
||||||
.subscribe({
|
|
||||||
Timber.i("Switch student result: Open login view")
|
|
||||||
view?.openLoginView()
|
|
||||||
}, {
|
|
||||||
Timber.i("Switch student result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getProperViewIndexes(initMenu: MainView.MenuView?): Pair<Int, Int> {
|
private fun getProperViewIndexes(initMenu: MainView.MenuView?): Pair<Int, Int> {
|
||||||
return when {
|
return when {
|
||||||
initMenu?.id in 0..3 -> initMenu!!.id to -1
|
initMenu?.id in 0..3 -> initMenu!!.id to -1
|
||||||
|
@ -28,8 +28,6 @@ interface MainView : BaseView {
|
|||||||
|
|
||||||
fun popView()
|
fun popView()
|
||||||
|
|
||||||
fun openLoginView()
|
|
||||||
|
|
||||||
interface MainChildView {
|
interface MainChildView {
|
||||||
|
|
||||||
fun onFragmentReselected()
|
fun onFragmentReselected()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.message
|
package io.github.wulkanowy.ui.modules.message
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
@ -10,9 +11,10 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MessagePresenter @Inject constructor(
|
class MessagePresenter @Inject constructor(
|
||||||
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
private val schedulers: SchedulersProvider
|
studentRepository: StudentRepository
|
||||||
) : BasePresenter<MessageView>(errorHandler) {
|
) : BasePresenter<MessageView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
override fun onAttachView(view: MessageView) {
|
override fun onAttachView(view: MessageView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
|
@ -12,7 +12,7 @@ import android.view.View.VISIBLE
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
import io.github.wulkanowy.ui.modules.message.MessageFragment
|
||||||
@ -20,8 +20,7 @@ import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
|||||||
import kotlinx.android.synthetic.main.fragment_message_preview.*
|
import kotlinx.android.synthetic.main.fragment_message_preview.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
class MessagePreviewFragment : BaseFragment(), MessagePreviewView, MainView.TitledView {
|
||||||
class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainView.TitledView {
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: MessagePreviewPresenter
|
lateinit var presenter: MessagePreviewPresenter
|
||||||
@ -87,10 +86,12 @@ class MessagePreviewFragment : BaseSessionFragment(), MessagePreviewView, MainVi
|
|||||||
messagePreviewSubject.text = subject
|
messagePreviewSubject.text = subject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun setRecipient(recipient: String) {
|
override fun setRecipient(recipient: String) {
|
||||||
messagePreviewAuthor.text = "${getString(R.string.message_to)} $recipient"
|
messagePreviewAuthor.text = "${getString(R.string.message_to)} $recipient"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun setSender(sender: String) {
|
override fun setSender(sender: String) {
|
||||||
messagePreviewAuthor.text = "${getString(R.string.message_from)} $sender"
|
messagePreviewAuthor.text = "${getString(R.string.message_from)} $sender"
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package io.github.wulkanowy.ui.modules.message.preview
|
package io.github.wulkanowy.ui.modules.message.preview
|
||||||
|
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.START_DATE
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
import io.github.wulkanowy.data.repositories.message.MessageRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionPresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
@ -13,12 +12,12 @@ import timber.log.Timber
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MessagePreviewPresenter @Inject constructor(
|
class MessagePreviewPresenter @Inject constructor(
|
||||||
private val errorHandler: SessionErrorHandler,
|
schedulers: SchedulersProvider,
|
||||||
private val schedulers: SchedulersProvider,
|
errorHandler: ErrorHandler,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
private val messageRepository: MessageRepository,
|
private val messageRepository: MessageRepository,
|
||||||
private val studentRepository: StudentRepository,
|
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BaseSessionPresenter<MessagePreviewView>(errorHandler) {
|
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
var messageId = 0L
|
var messageId = 0L
|
||||||
|
|
||||||
@ -53,7 +52,7 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
else setSender(it.sender)
|
else setSender(it.sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_message_preview", START_DATE to message.date.toFormattedString("yyyy.MM.dd"), "length" to message.content?.length)
|
analytics.logEvent("load_message_preview", "length" to message.content?.length)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading message $id preview result: An exception occurred ")
|
Timber.i("Loading message $id preview result: An exception occurred ")
|
||||||
view?.showMessageError()
|
view?.showMessageError()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.message.preview
|
package io.github.wulkanowy.ui.modules.message.preview
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.ui.base.session.BaseSessionView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface MessagePreviewView : BaseSessionView {
|
interface MessagePreviewView : BaseView {
|
||||||
|
|
||||||
val noSubjectString: String
|
val noSubjectString: String
|
||||||
|
|
||||||
|
@ -19,13 +19,14 @@ import io.github.wulkanowy.utils.showSoftInput
|
|||||||
import kotlinx.android.synthetic.main.activity_send_message.*
|
import kotlinx.android.synthetic.main.activity_send_message.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SendMessageActivity : BaseActivity(), SendMessageView {
|
class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: SendMessagePresenter
|
override lateinit var presenter: SendMessagePresenter
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val EXTRA_MESSAGE = "EXTRA_MESSAGE"
|
private const val EXTRA_MESSAGE = "EXTRA_MESSAGE"
|
||||||
|
|
||||||
private const val EXTRA_REPLY = "EXTRA_REPLY"
|
private const val EXTRA_REPLY = "EXTRA_REPLY"
|
||||||
|
|
||||||
fun getStartIntent(context: Context) = Intent(context, SendMessageActivity::class.java)
|
fun getStartIntent(context: Context) = Intent(context, SendMessageActivity::class.java)
|
||||||
@ -126,9 +127,4 @@ class SendMessageActivity : BaseActivity(), SendMessageView {
|
|||||||
override fun popView() {
|
override fun popView() {
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
presenter.onDetachView()
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user