forked from github/wulkanowy-mirror
Merge branch 'release/1.1.1'
This commit is contained in:
commit
60a9bcae46
132
.github/workflows/test.yml
vendored
132
.github/workflows/test.yml
vendored
@ -68,3 +68,135 @@ jobs:
|
|||||||
PLAY_SERVICE_ACCOUNT_EMAIL: ${{ secrets.PLAY_SERVICE_ACCOUNT_EMAIL }}
|
PLAY_SERVICE_ACCOUNT_EMAIL: ${{ secrets.PLAY_SERVICE_ACCOUNT_EMAIL }}
|
||||||
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
|
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
|
||||||
run: ./gradlew publishPlayRelease -PenableFirebase --stacktrace;
|
run: ./gradlew publishPlayRelease -PenableFirebase --stacktrace;
|
||||||
|
|
||||||
|
deploy-appcenter:
|
||||||
|
name: Deploy to App Center
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
environment: app-center
|
||||||
|
if: github.ref != 'refs/heads/develop'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||||
|
- name: Set run number with offset
|
||||||
|
env:
|
||||||
|
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
|
||||||
|
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
|
||||||
|
- name: Prepare build configuration
|
||||||
|
run: |
|
||||||
|
sed -i -e "s#applicationIdSuffix \".dev\"#applicationIdSuffix \".${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/build.gradle
|
||||||
|
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/google-services.json
|
||||||
|
sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/src/debug/agconnect-services.json
|
||||||
|
sed -i -e '/versionNameSuffix/d' app/build.gradle
|
||||||
|
- name: Add signing config
|
||||||
|
run: |
|
||||||
|
cat >> app/build.gradle <<EOF
|
||||||
|
android.signingConfigs.debug {
|
||||||
|
storeFile file("bitrise.jks")
|
||||||
|
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
|
||||||
|
keyAlias System.getenv("BITRISE_KEY_ALIAS")
|
||||||
|
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
- name: Decrypt keys
|
||||||
|
env:
|
||||||
|
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
|
||||||
|
run: |
|
||||||
|
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
|
||||||
|
- name: Bump version
|
||||||
|
uses: chkfung/android-version-actions@v1.1
|
||||||
|
with:
|
||||||
|
gradlePath: app/build.gradle
|
||||||
|
versionCode: ${{ env.RUN_NUMBER }}
|
||||||
|
versionName: ${{ env.RUN_NUMBER }}-${{ github.head_ref }}
|
||||||
|
- name: Build apk
|
||||||
|
env:
|
||||||
|
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
|
||||||
|
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
|
||||||
|
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
|
||||||
|
run: ./gradlew assembleFdroidDebug --stacktrace
|
||||||
|
- name: Upload apk to github artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: wulkanowyDEV-${{ env.RUN_NUMBER }}.apk
|
||||||
|
path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
|
||||||
|
- name: Deploy to app center
|
||||||
|
uses: wzieba/AppCenter-Github-Action@v1
|
||||||
|
with:
|
||||||
|
appName: wulkanowy/wulkanowy
|
||||||
|
token: ${{ secrets.APP_CENTER_TOKEN }}
|
||||||
|
group: Testers
|
||||||
|
file: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
|
||||||
|
notifyTesters: true
|
||||||
|
debug: true
|
||||||
|
|
||||||
|
deploy-app-distribution:
|
||||||
|
name: Deploy to AppDistribution
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
|
environment: app-distribution
|
||||||
|
if: github.ref == 'refs/heads/develop'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
|
||||||
|
- name: Set run number with offset
|
||||||
|
env:
|
||||||
|
BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
|
||||||
|
run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
|
||||||
|
- name: Add signing config
|
||||||
|
run: |
|
||||||
|
cat >> app/build.gradle <<EOF
|
||||||
|
android.signingConfigs.debug {
|
||||||
|
storeFile file("bitrise.jks")
|
||||||
|
storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
|
||||||
|
keyAlias System.getenv("BITRISE_KEY_ALIAS")
|
||||||
|
keyPassword System.getenv("BITRISE_KEY_PASSWORD")
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
- name: Decrypt keys
|
||||||
|
env:
|
||||||
|
BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
|
||||||
|
BITRISE_SERVICES_ENCRYPT_KEY: ${{ secrets.BITRISE_SERVICES_ENCRYPT_KEY }}
|
||||||
|
run: |
|
||||||
|
gpg --yes --batch --passphrase=$BITRISE_SERVICES_ENCRYPT_KEY ./app/src/debug/google-services.json.gpg
|
||||||
|
gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
|
||||||
|
- name: Bump version
|
||||||
|
uses: chkfung/android-version-actions@v1.1
|
||||||
|
with:
|
||||||
|
gradlePath: app/build.gradle
|
||||||
|
versionCode: ${{ env.RUN_NUMBER }}
|
||||||
|
versionName: ${{ env.RUN_NUMBER }}
|
||||||
|
- name: Build apk
|
||||||
|
env:
|
||||||
|
BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
|
||||||
|
BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
|
||||||
|
BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
|
||||||
|
run: ./gradlew assemblePlayDebug -PenableFirebase --stacktrace
|
||||||
|
- name: Upload apk to github artifacts
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: wulkanowyDEV-${{ env.RUN_NUMBER }}-dev.apk
|
||||||
|
path: app/build/outputs/apk/play/debug/app-play-debug.apk
|
||||||
|
- name: Deploy to app distribution
|
||||||
|
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||||
|
with:
|
||||||
|
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||||
|
token: ${{ secrets.FIREBASE_TOKEN }}
|
||||||
|
groups: discord
|
||||||
|
file: app/build/outputs/apk/play/debug/app-play-debug.apk
|
||||||
|
BIN
app/bitrise.jks
Normal file
BIN
app/bitrise.jks
Normal file
Binary file not shown.
BIN
app/bitrise.jks.gpg
Normal file
BIN
app/bitrise.jks.gpg
Normal file
Binary file not shown.
@ -5,6 +5,8 @@ apply plugin: 'dagger.hilt.android.plugin'
|
|||||||
apply plugin: 'com.google.firebase.crashlytics'
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||||
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
apply plugin: 'com.huawei.agconnect'
|
||||||
apply from: 'jacoco.gradle'
|
apply from: 'jacoco.gradle'
|
||||||
apply from: 'sonarqube.gradle'
|
apply from: 'sonarqube.gradle'
|
||||||
apply from: 'hooks.gradle'
|
apply from: 'hooks.gradle'
|
||||||
@ -18,8 +20,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 86
|
versionCode 87
|
||||||
versionName "1.1.0"
|
versionName "1.1.1"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
@ -58,7 +60,7 @@ android {
|
|||||||
release {
|
release {
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
@ -115,6 +117,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
|
useIR = true
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "1.8"
|
||||||
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
|
freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
|
||||||
}
|
}
|
||||||
@ -134,31 +137,31 @@ play {
|
|||||||
serviceAccountCredentials = file('key.p12')
|
serviceAccountCredentials = file('key.p12')
|
||||||
defaultToAppBundles = false
|
defaultToAppBundles = false
|
||||||
track = 'production'
|
track = 'production'
|
||||||
updatePriority = 3
|
updatePriority = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
work_manager = "2.5.0"
|
work_manager = "2.5.0"
|
||||||
work_hilt = "1.0.0-alpha03"
|
work_hilt = "1.0.0-beta01"
|
||||||
room = "2.3.0-beta02"
|
room = "2.3.0-beta03"
|
||||||
chucker = "3.4.0"
|
chucker = "3.4.0"
|
||||||
mockk = "1.10.6"
|
mockk = "1.10.6"
|
||||||
moshi = "1.11.0"
|
moshi = "1.11.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:1.1.0"
|
implementation "io.github.wulkanowy:sdk:1.1.1"
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
|
||||||
|
|
||||||
implementation "androidx.core:core-ktx:1.3.2"
|
implementation "androidx.core:core-ktx:1.3.2"
|
||||||
implementation "androidx.activity:activity-ktx:1.2.0"
|
implementation "androidx.activity:activity-ktx:1.2.1"
|
||||||
implementation "androidx.appcompat:appcompat:1.2.0"
|
implementation "androidx.appcompat:appcompat:1.2.0"
|
||||||
implementation "androidx.appcompat:appcompat-resources:1.2.0"
|
implementation "androidx.appcompat:appcompat-resources:1.2.0"
|
||||||
implementation "androidx.fragment:fragment-ktx:1.3.0"
|
implementation "androidx.fragment:fragment-ktx:1.3.1"
|
||||||
implementation "androidx.annotation:annotation:1.1.0"
|
implementation "androidx.annotation:annotation:1.1.0"
|
||||||
implementation "androidx.multidex:multidex:2.0.1"
|
implementation "androidx.multidex:multidex:2.0.1"
|
||||||
|
|
||||||
@ -169,7 +172,7 @@ dependencies {
|
|||||||
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
||||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||||
implementation "com.google.android.material:material:1.3.0"
|
implementation "com.google.android.material:material:1.3.0"
|
||||||
implementation "com.github.wulkanowy:material-chips-input:2.1.1"
|
implementation "com.github.wulkanowy:material-chips-input:2.2.0"
|
||||||
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||||
implementation 'com.mikhaellopez:circularimageview:4.2.0'
|
implementation 'com.mikhaellopez:circularimageview:4.2.0'
|
||||||
|
|
||||||
@ -203,7 +206,7 @@ dependencies {
|
|||||||
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||||
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
|
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
|
||||||
|
|
||||||
playImplementation platform('com.google.firebase:firebase-bom:26.6.0')
|
playImplementation platform('com.google.firebase:firebase-bom:26.7.0')
|
||||||
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
||||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx'
|
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx'
|
||||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx"
|
playImplementation "com.google.firebase:firebase-inappmessaging-ktx"
|
||||||
@ -239,6 +242,3 @@ dependencies {
|
|||||||
androidTestImplementation "io.mockk:mockk-android:$mockk"
|
androidTestImplementation "io.mockk:mockk-android:$mockk"
|
||||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
|
||||||
apply plugin: 'com.huawei.agconnect'
|
|
||||||
|
29
app/proguard-rules.pro
vendored
29
app/proguard-rules.pro
vendored
@ -1,33 +1,21 @@
|
|||||||
# Optimizations
|
# General
|
||||||
-optimizationpasses 5
|
|
||||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
|
||||||
-dontusemixedcaseclassnames
|
|
||||||
-dontskipnonpubliclibraryclasses
|
|
||||||
-dontskipnonpubliclibraryclassmembers
|
|
||||||
-dontpreverify
|
|
||||||
-dontobfuscate
|
-dontobfuscate
|
||||||
-allowaccessmodification
|
|
||||||
-repackageclasses ''
|
|
||||||
-verbose
|
|
||||||
|
|
||||||
|
|
||||||
#Keep all wulkanowy files
|
#Config for wulkanowy
|
||||||
-keep class io.github.wulkanowy.** {*;}
|
-keep class io.github.wulkanowy.** {*;}
|
||||||
|
|
||||||
|
|
||||||
#Config for anallitycs
|
#Config for firebase crashlitycs
|
||||||
-keepattributes *Annotation*
|
|
||||||
-keepattributes SourceFile,LineNumberTable
|
-keepattributes SourceFile,LineNumberTable
|
||||||
-keep class com.crashlytics.** {*;}
|
|
||||||
-keep public class * extends java.lang.Exception
|
-keep public class * extends java.lang.Exception
|
||||||
-dontwarn com.crashlytics.**
|
|
||||||
|
|
||||||
|
|
||||||
#Config for OkHttp
|
#Config for Okio and OkHttp
|
||||||
|
-dontwarn javax.annotation.**
|
||||||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||||
-dontwarn javax.annotation.**
|
|
||||||
|
|
||||||
|
|
||||||
#Config for MPAndroidChart
|
#Config for MPAndroidChart
|
||||||
@ -36,10 +24,3 @@
|
|||||||
|
|
||||||
#Config for Material Components
|
#Config for Material Components
|
||||||
-keep class com.google.android.material.tabs.** { *; }
|
-keep class com.google.android.material.tabs.** { *; }
|
||||||
|
|
||||||
|
|
||||||
#Config for About Libraries
|
|
||||||
-keep class .R
|
|
||||||
-keep class **.R$* {
|
|
||||||
<fields>;
|
|
||||||
}
|
|
||||||
|
@ -192,7 +192,7 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showContent(show: Boolean) {
|
override fun showContent(show: Boolean) {
|
||||||
binding. attendanceRecycler.visibility = if (show) VISIBLE else GONE
|
binding.attendanceRecycler.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showRefresh(show: Boolean) {
|
override fun showRefresh(show: Boolean) {
|
||||||
|
@ -190,35 +190,48 @@ class AttendancePresenter @Inject constructor(
|
|||||||
flowWithResourceIn {
|
flowWithResourceIn {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
attendanceRepository.getAttendance(student, semester, currentDate, currentDate, forceRefresh)
|
attendanceRepository.getAttendance(
|
||||||
|
student,
|
||||||
|
semester,
|
||||||
|
currentDate,
|
||||||
|
currentDate,
|
||||||
|
forceRefresh
|
||||||
|
)
|
||||||
}.onEach {
|
}.onEach {
|
||||||
when (it.status) {
|
when (it.status) {
|
||||||
Status.LOADING -> {
|
Status.LOADING -> {
|
||||||
view?.showExcuseButton(false)
|
view?.showExcuseButton(false)
|
||||||
if (!it.data.isNullOrEmpty()) {
|
if (!it.data.isNullOrEmpty()) {
|
||||||
|
val filteredAttendance = if (prefRepository.isShowPresent) {
|
||||||
|
it.data
|
||||||
|
} else {
|
||||||
|
it.data.filter { item -> !item.presence }
|
||||||
|
}
|
||||||
|
|
||||||
view?.run {
|
view?.run {
|
||||||
enableSwipe(true)
|
enableSwipe(true)
|
||||||
showRefresh(true)
|
showRefresh(true)
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showContent(true)
|
showEmpty(filteredAttendance.isEmpty())
|
||||||
updateData(it.data.let { items ->
|
showContent(filteredAttendance.isNotEmpty())
|
||||||
if (prefRepository.isShowPresent) items
|
updateData(filteredAttendance.sortedBy { item -> item.number })
|
||||||
else items.filter { item -> !item.presence }
|
|
||||||
}.sortedBy { item -> item.number })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
Status.SUCCESS -> {
|
||||||
Timber.i("Loading attendance result: Success")
|
Timber.i("Loading attendance result: Success")
|
||||||
|
val filteredAttendance = if (prefRepository.isShowPresent) {
|
||||||
|
it.data.orEmpty()
|
||||||
|
} else {
|
||||||
|
it.data?.filter { item -> !item.presence }.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
view?.apply {
|
view?.apply {
|
||||||
updateData(it.data!!.let { items ->
|
updateData(filteredAttendance.sortedBy { item -> item.number })
|
||||||
if (prefRepository.isShowPresent) items
|
showEmpty(filteredAttendance.isEmpty())
|
||||||
else items.filter { item -> !item.presence }
|
|
||||||
}.sortedBy { item -> item.number })
|
|
||||||
showEmpty(it.data.isEmpty())
|
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.data.isNotEmpty())
|
showContent(filteredAttendance.isNotEmpty())
|
||||||
showExcuseButton(it.data.any { item -> item.excusable })
|
showExcuseButton(filteredAttendance.any { item -> item.excusable })
|
||||||
}
|
}
|
||||||
analytics.logEvent(
|
analytics.logEvent(
|
||||||
"load_data",
|
"load_data",
|
||||||
|
@ -10,6 +10,7 @@ import android.view.View.VISIBLE
|
|||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.databinding.FragmentGradeBinding
|
import io.github.wulkanowy.databinding.FragmentGradeBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
@ -121,11 +122,9 @@ class GradeFragment : BaseFragment<FragmentGradeBinding>(R.layout.fragment_grade
|
|||||||
semesterSwitchMenu?.isVisible = show
|
semesterSwitchMenu?.isVisible = show
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showSemesterDialog(selectedIndex: Int) {
|
override fun showSemesterDialog(selectedIndex: Int, semesters: List<Semester>) {
|
||||||
val choices = arrayOf(
|
val choices = semesters.map { getString(R.string.grade_semester, it.semesterName) }
|
||||||
getString(R.string.grade_semester, 1),
|
.toTypedArray()
|
||||||
getString(R.string.grade_semester, 2)
|
|
||||||
)
|
|
||||||
|
|
||||||
AlertDialog.Builder(requireContext())
|
AlertDialog.Builder(requireContext())
|
||||||
.setSingleChoiceItems(choices, selectedIndex) { dialog, which ->
|
.setSingleChoiceItems(choices, selectedIndex) { dialog, which ->
|
||||||
|
@ -49,7 +49,9 @@ class GradePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onSemesterSwitch(): Boolean {
|
fun onSemesterSwitch(): Boolean {
|
||||||
if (semesters.isNotEmpty()) view?.showSemesterDialog(selectedIndex - 1)
|
if (semesters.isNotEmpty()) {
|
||||||
|
view?.showSemesterDialog(selectedIndex - 1, semesters.slice(0..1))
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,11 +139,17 @@ class GradePresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
|
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
|
||||||
Timber.d("Load grade tab child. Selected semester: $selectedIndex, semesters: ${semesters.joinToString { it.semesterName.toString() }}")
|
Timber.d("Load grade tab child. Selected semester: $selectedIndex, semesters: ${semesters.joinToString { it.semesterName.toString() }}")
|
||||||
semesters.first { it.semesterName == selectedIndex }.semesterId.also {
|
|
||||||
if (forceRefresh || loadedSemesterId[index] != it) {
|
val newSelectedSemesterId = try {
|
||||||
Timber.i("Load grade child view index: $index")
|
semesters.first { it.semesterName == selectedIndex }.semesterId
|
||||||
view?.notifyChildLoadData(index, it, forceRefresh)
|
} catch (e: NoSuchElementException) {
|
||||||
|
Timber.e(e, "Selected semester no exists")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forceRefresh || loadedSemesterId[index] != newSelectedSemesterId) {
|
||||||
|
Timber.i("Load grade child view index: $index")
|
||||||
|
view?.notifyChildLoadData(index, newSelectedSemesterId, forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeView : BaseView {
|
interface GradeView : BaseView {
|
||||||
@ -18,7 +19,7 @@ interface GradeView : BaseView {
|
|||||||
|
|
||||||
fun showSemesterSwitch(show: Boolean)
|
fun showSemesterSwitch(show: Boolean)
|
||||||
|
|
||||||
fun showSemesterDialog(selectedIndex: Int)
|
fun showSemesterDialog(selectedIndex: Int, semesters: List<Semester>)
|
||||||
|
|
||||||
fun setCurrentSemesterName(semester: Int, schoolYear: Int)
|
fun setCurrentSemesterName(semester: Int, schoolYear: Int)
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
val fragment =
|
val fragment =
|
||||||
supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
|
supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
|
||||||
navController.pushFragment(fragment)
|
pushView(fragment)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +305,8 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun switchMenuView(position: Int) {
|
override fun switchMenuView(position: Int) {
|
||||||
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
||||||
navController.switchTab(position)
|
navController.switchTab(position)
|
||||||
}
|
}
|
||||||
@ -322,6 +324,8 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>) {
|
override fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>) {
|
||||||
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
navController.showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
|
navController.showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,15 +343,21 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun showDialogFragment(dialog: DialogFragment) {
|
fun showDialogFragment(dialog: DialogFragment) {
|
||||||
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
navController.showDialogFragment(dialog)
|
navController.showDialogFragment(dialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pushView(fragment: Fragment) {
|
fun pushView(fragment: Fragment) {
|
||||||
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
||||||
navController.pushFragment(fragment)
|
navController.pushFragment(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popView(depth: Int) {
|
override fun popView(depth: Int) {
|
||||||
|
if (supportFragmentManager.isStateSaved) return
|
||||||
|
|
||||||
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
|
||||||
navController.safelyPopFragments(depth)
|
navController.safelyPopFragments(depth)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ class MainPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun showCurrentStudentAvatar() {
|
private fun showCurrentStudentAvatar() {
|
||||||
val currentStudent =
|
val currentStudent =
|
||||||
studentsWitSemesters!!.single { it.student.isCurrent }.student
|
studentsWitSemesters?.singleOrNull { it.student.isCurrent }?.student ?: return
|
||||||
|
|
||||||
view?.showStudentAvatar(currentStudent)
|
view?.showStudentAvatar(currentStudent)
|
||||||
}
|
}
|
||||||
|
@ -53,13 +53,14 @@ class SchoolFragment : BaseFragment<FragmentSchoolBinding>(R.layout.fragment_sch
|
|||||||
|
|
||||||
override fun updateData(data: School) {
|
override fun updateData(data: School) {
|
||||||
with(binding) {
|
with(binding) {
|
||||||
schoolName.text = data.name
|
val noDataString = getString(R.string.all_no_data)
|
||||||
schoolAddress.text = data.address.ifBlank { "-" }
|
schoolName.text = data.name.ifBlank { noDataString }
|
||||||
|
schoolAddress.text = data.address.ifBlank { noDataString }
|
||||||
schoolAddressButton.visibility = if (data.address.isNotBlank()) VISIBLE else GONE
|
schoolAddressButton.visibility = if (data.address.isNotBlank()) VISIBLE else GONE
|
||||||
schoolTelephone.text = data.contact.ifBlank { "-" }
|
schoolTelephone.text = data.contact.ifBlank { noDataString }
|
||||||
schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) VISIBLE else GONE
|
schoolTelephoneButton.visibility = if (data.contact.isNotBlank()) VISIBLE else GONE
|
||||||
schoolHeadmaster.text = data.headmaster
|
schoolHeadmaster.text = data.headmaster.ifBlank { noDataString }
|
||||||
schoolPedagogue.text = data.pedagogue
|
schoolPedagogue.text = data.pedagogue.ifBlank { noDataString }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
Wersja 1.1.0
|
Wersja 1.1.1
|
||||||
|
|
||||||
- dodaliśmy wyświetlanie inicjałów imienia ucznia jako awatar widoczny w aplikacji
|
- naprawiliśmy wyświetlanie planu lekcji
|
||||||
- dodaliśmy historię szczęśliwego numerka
|
- naprawiliśmy kilka rzadkich problemów ze stabilnością
|
||||||
- dodaliśmy język słowacki
|
|
||||||
- zmieniliśmy kolor górnego i dolnego paska systemowego lepiej dostosowując je do aplikacji
|
|
||||||
- zmieniliśmy wygląd ustawień dzieląc je na sekcje
|
|
||||||
- naprawiliśmy problem dublujących się czasem ocen
|
|
||||||
- naprawiliśmy kilka innych błędów i poprawiliśmy stabilność aplikacji
|
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Důvod nepřítomnosti (volitelný)</string>
|
<string name="attendance_excuse_dialog_reason">Důvod nepřítomnosti (volitelný)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Poslat</string>
|
<string name="attendance_excuse_dialog_submit">Poslat</string>
|
||||||
<string name="attendance_excuse_success">Nepřítomnost úspěšně omluvena!</string>
|
<string name="attendance_excuse_success">Žádost o omluvu nepřítomnosti byla úspěšně odeslána!</string>
|
||||||
<string name="attendance_excuse_no_selection">Musíte vybrat alespoň jednu nepřítomnost!</string>
|
<string name="attendance_excuse_no_selection">Musíte vybrat alespoň jednu nepřítomnost!</string>
|
||||||
<string name="attendance_excuse_title">Ospravedlnit</string>
|
<string name="attendance_excuse_title">Ospravedlnit</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Abwesenheitsgrund (optional)</string>
|
<string name="attendance_excuse_dialog_reason">Abwesenheitsgrund (optional)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Senden</string>
|
<string name="attendance_excuse_dialog_submit">Senden</string>
|
||||||
<string name="attendance_excuse_success">Abwesenheit erfolgreich entschuldigt!</string>
|
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
||||||
<string name="attendance_excuse_no_selection">Sie müssen mindestens eine Abwesenheit auswählen!</string>
|
<string name="attendance_excuse_no_selection">Sie müssen mindestens eine Abwesenheit auswählen!</string>
|
||||||
<string name="attendance_excuse_title">Verzeihung</string>
|
<string name="attendance_excuse_title">Verzeihung</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Absence reason (optional)</string>
|
<string name="attendance_excuse_dialog_reason">Absence reason (optional)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Send</string>
|
<string name="attendance_excuse_dialog_submit">Send</string>
|
||||||
<string name="attendance_excuse_success">Absence excused successfully!</string>
|
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
||||||
<string name="attendance_excuse_no_selection">You must select at least one absence!</string>
|
<string name="attendance_excuse_no_selection">You must select at least one absence!</string>
|
||||||
<string name="attendance_excuse_title">Excuse</string>
|
<string name="attendance_excuse_title">Excuse</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Powód nieobecności (opcjonalny)</string>
|
<string name="attendance_excuse_dialog_reason">Powód nieobecności (opcjonalny)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Wyślij</string>
|
<string name="attendance_excuse_dialog_submit">Wyślij</string>
|
||||||
<string name="attendance_excuse_success">Usprawiedliwiono pomyślnie!</string>
|
<string name="attendance_excuse_success">Prośba o usprawiedliwienie została pomyślnie wysłana!</string>
|
||||||
<string name="attendance_excuse_no_selection">Musisz wybrać co najmniej jedną nieobecność!</string>
|
<string name="attendance_excuse_no_selection">Musisz wybrać co najmniej jedną nieobecność!</string>
|
||||||
<string name="attendance_excuse_title">Usprawiedliw</string>
|
<string name="attendance_excuse_title">Usprawiedliw</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
@ -317,7 +317,7 @@
|
|||||||
<string name="lucky_number_history_button">Pokaż historię</string>
|
<string name="lucky_number_history_button">Pokaż historię</string>
|
||||||
<!--Lucky number history-->
|
<!--Lucky number history-->
|
||||||
<string name="lucky_number_history_title">Historia numerków</string>
|
<string name="lucky_number_history_title">Historia numerków</string>
|
||||||
<string name="lucky_number_history_empty">Brak informacji o szczęśliwych numerach</string>
|
<string name="lucky_number_history_empty">Brak informacji o szczęśliwych numerkach</string>
|
||||||
<!--Mobile devices-->
|
<!--Mobile devices-->
|
||||||
<string name="mobile_devices_title">Dostęp mobilny</string>
|
<string name="mobile_devices_title">Dostęp mobilny</string>
|
||||||
<string name="mobile_devices_no_items">Brak urządzeń</string>
|
<string name="mobile_devices_no_items">Brak urządzeń</string>
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Причина отсутствия (необязательно)</string>
|
<string name="attendance_excuse_dialog_reason">Причина отсутствия (необязательно)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Послать</string>
|
<string name="attendance_excuse_dialog_submit">Послать</string>
|
||||||
<string name="attendance_excuse_success">Статус отсутствия изменён</string>
|
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
||||||
<string name="attendance_excuse_no_selection">Выберите хотя-бы одно отсутствие</string>
|
<string name="attendance_excuse_no_selection">Выберите хотя-бы одно отсутствие</string>
|
||||||
<string name="attendance_excuse_title">Изменить статус</string>
|
<string name="attendance_excuse_title">Изменить статус</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Dôvod neprítomnosti (voliteľný)</string>
|
<string name="attendance_excuse_dialog_reason">Dôvod neprítomnosti (voliteľný)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Poslať</string>
|
<string name="attendance_excuse_dialog_submit">Poslať</string>
|
||||||
<string name="attendance_excuse_success">Neprítomnosť úspešne ospravedlnená!</string>
|
<string name="attendance_excuse_success">Žiadosť o ospravedlnenie neprítomnosti bola úspešne odoslaná!</string>
|
||||||
<string name="attendance_excuse_no_selection">Musíte vybrať aspoň jednu neprítomnosť!</string>
|
<string name="attendance_excuse_no_selection">Musíte vybrať aspoň jednu neprítomnosť!</string>
|
||||||
<string name="attendance_excuse_title">Ospravedlniť</string>
|
<string name="attendance_excuse_title">Ospravedlniť</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -192,7 +192,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Причина відсутності (необов’язково)</string>
|
<string name="attendance_excuse_dialog_reason">Причина відсутності (необов’язково)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Надіслати</string>
|
<string name="attendance_excuse_dialog_submit">Надіслати</string>
|
||||||
<string name="attendance_excuse_success">Змінено статус відсутності</string>
|
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
||||||
<string name="attendance_excuse_no_selection">Оберіть хоча б одну відсутність</string>
|
<string name="attendance_excuse_no_selection">Оберіть хоча б одну відсутність</string>
|
||||||
<string name="attendance_excuse_title">Змінити статус</string>
|
<string name="attendance_excuse_title">Змінити статус</string>
|
||||||
<!--Attendance summary-->
|
<!--Attendance summary-->
|
||||||
|
@ -194,7 +194,7 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="attendance_excuse_dialog_reason">Absence reason (optional)</string>
|
<string name="attendance_excuse_dialog_reason">Absence reason (optional)</string>
|
||||||
<string name="attendance_excuse_dialog_submit">Send</string>
|
<string name="attendance_excuse_dialog_submit">Send</string>
|
||||||
<string name="attendance_excuse_success">Absence excused successfully!</string>
|
<string name="attendance_excuse_success">Absence excuse request sent successfully!</string>
|
||||||
<string name="attendance_excuse_no_selection">You must select at least one absence!</string>
|
<string name="attendance_excuse_no_selection">You must select at least one absence!</string>
|
||||||
<string name="attendance_excuse_title">Excuse</string>
|
<string name="attendance_excuse_title">Excuse</string>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user