From fb35c63781f0d8042a86bb87fa6790cccfe99e27 Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Tue, 9 Jul 2019 22:21:57 +0200 Subject: [PATCH 01/13] Updated Travis CI references (#252) * Updated build dependencies * Updated Travis CI references --- README.md | 4 ++-- build.gradle | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 424abced7..fb53e31b4 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ CI Status |Branch|CI status| |------|---------| -|develop|[![Build Status](https://travis-ci.org/Amab/SWADroid.svg?branch=develop)](https://travis-ci.org/Amab/SWADroid)| -|master|[![Build Status](https://travis-ci.org/Amab/SWADroid.svg?branch=master)](https://travis-ci.org/Amab/SWADroid)| +|develop|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=develop)](https://travis-ci.com/Amab/SWADroid)| +|master|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=master)](https://travis-ci.com/Amab/SWADroid)| Copyright and License --------------------- diff --git a/build.gradle b/build.gradle index 8cf2450fb..2dd9b9872 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,9 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.1' + classpath 'com.android.tools.build:gradle:3.4.2' classpath 'org.ajoberstar:grgit:2.1.1' - classpath 'com.google.gms:google-services:4.2.0' + classpath 'com.google.gms:google-services:4.3.0' } } From d927ee059ddcfc7521fcb4e09587dcaba1b1e6ab Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Sat, 26 Oct 2019 17:16:37 +0200 Subject: [PATCH 02/13] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fb53e31b4..de0aa09bc 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ CI Status |develop|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=develop)](https://travis-ci.com/Amab/SWADroid)| |master|[![Build Status](https://travis-ci.com/Amab/SWADroid.svg?branch=master)](https://travis-ci.com/Amab/SWADroid)| +[![Releases](https://img.shields.io/github/release/Amab/SWADroid.svg)](https://github.com/Amab/SWADroid/releases/latest) +[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=Amab/SWADroid)](https://dependabot.com) +[![libraries.io](https://img.shields.io/librariesio/github/Amab/SWADroid.svg)](https://libraries.io/github/Amab/SWADroid) + Copyright and License --------------------- From 588afa9b11a4f0d49d57e131db5453912acbae13 Mon Sep 17 00:00:00 2001 From: Amab Date: Sat, 26 Oct 2019 17:23:14 +0200 Subject: [PATCH 03/13] Updated dependencies --- .travis.yml | 2 +- SWADroid/build.gradle | 8 ++++---- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36ae65a06..6c16029ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ jdk: oraclejdk8 env: global: - ANDROID_API=29 - - ANDROID_BUILD_TOOLS=29.0.0 + - ANDROID_BUILD_TOOLS=29.0.2 - secure: eY3bGKw4jZ+HHkkMBZHiL2dhcz+RJYHib0WC77SSVHLJcCg63pBvs420i4rjNQHycMs+PhRSlR79jdglDTm8svphhRjSts6VMkHDxObwJIyLF8vAZ0PfjhqfOXO+4+Fx6pRIjwM7cBMOQrDfSimJHRB+z/f2AJfUIsaMSlltGVya7nmrLY/fO4dtl4wPnejslj3mhnBAxr+a2Or978RwI2TMpxBovHZKFT/46wJTcMzKXGdXU64M8nmQmpcKHeIKIBiR4g+A2tahC+Us4tFxxoTDd3R+IAzj7Gvjd5JuMlYmQ3quRv2M08u9OJNiT14LpDXy19fZKdw/QNHg3S8JVis8kJDkv6z4HyZXTIBgISZpCZZti04GP29Lj+1f4ISRFc6uxankDuRgfX8ucsxoEPJVq3PfJlpTdP7wjlQtEGv0HF/3MNNyruNbLHFiCgHOANwEOX44INtw6XylPEftmw4y4ptntFG3VXyV1Zi+732Qe4b2QNTbvLPrsmkCRKzo59vKKAzBBhvYvFVITcWbySqdx9/n1H25SRL2Q96nPGQSQyBF6obzzFcjMKkknPle1PXvAfb171964cdIK6/zo9rh/ZCL3+gAKZibmGWvbeztWYl5ON8B8x8mgLO/qgPIotY+aqwmsY06pKrqi6adYZacMF+UgtbLJlhnird6ugk= - secure: EmcSyXk/5pEJhbRX9DSFzhQGYvGaYdxjDuQwmLuxUGitGpFQZbWexTAK/l0LLcIRsiSmucY7KJgOpL7I6odh2kVUZedarj8/5K1P69ljDDB7bfG8jyOLZvHJ1JTZRuKvUnT846zQwQWTnLXF9N4LaQ86FVqSW2bGHqptIivEjDEVh78V3g4PDsbX5aQ5LjTlSn7bezu9chpVS0fnRlqjAa6U2kUwUt+DDaSHEOs35Z89jT7JoonGFrMsyA7S26CQhOBYE3w76AllIea+MWzPJX3V364ZIzPBnQAkCz02oVI3n+LHZkzUCYHkY8DXWXNy6+/sulFa6L1v6bt8DzF1vwJ+nTNVqmqSDYBe2s1qAUZ+4o8l/THMndxC11LjbbEExG4ekBRFvRsOOf0pBps3Yr4ry27gaj4+9Ap2JCKKOQwm0izh48AJiy0Y8pzIzTO5wB5B7a4czLJmzaNWkPVXw4lKg2ldJ4sd6EBqUZqG2vRmN6VwHb8gHFNaQTH3feBRhYTpkv1wWUuhvclNn5yoZzcSxMT/b8d89e5DahoBYMW48c6jb5wL/EoY3bHp3mjtnTW8oIIjyZK8FjYX+8IqeEoue8bDDqNUN71xmRvp+0CX1iXnfgUeDWnYhXHTewOlJu6i509wGrZPxYjgwAdnpfTyGXPq7Vin9CkNHMw9fbA= before_cache: diff --git a/SWADroid/build.gradle b/SWADroid/build.gradle index da0b9eebd..488e35289 100644 --- a/SWADroid/build.gradle +++ b/SWADroid/build.gradle @@ -45,7 +45,7 @@ if (build_param != "prod") { android { compileSdkVersion "android-29" - buildToolsVersion '29.0.0' + buildToolsVersion '29.0.2' dexOptions { maxProcessCount=2 @@ -80,12 +80,12 @@ android { dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.google.code.ksoap2-android:ksoap2-android:3.6.4' implementation 'commons-io:commons-io:2.6' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' - implementation 'com.google.zxing:core:3.3.3' + implementation 'com.google.zxing:core:3.4.0' implementation 'com.google.code.gson:gson:2.8.5' - implementation 'com.google.firebase:firebase-core:17.0.0' + implementation 'com.google.firebase:firebase-core:17.2.0' } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2dd9b9872..c3659e87e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,9 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:3.5.1' classpath 'org.ajoberstar:grgit:2.1.1' - classpath 'com.google.gms:google-services:4.3.0' + classpath 'com.google.gms:google-services:4.3.2' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 434b58781..865eb2165 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Apr 19 12:17:14 CEST 2019 +#Tue Aug 20 19:44:44 CEST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-all.zip From 43e95486f3b5e0936c43230b7c538258273d8740 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2019 17:38:46 +0200 Subject: [PATCH 04/13] Bump gson from 2.8.5 to 2.8.6 (#258) Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.6. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6) Signed-off-by: dependabot-preview[bot] --- SWADroid/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SWADroid/build.gradle b/SWADroid/build.gradle index 488e35289..69bef42b9 100644 --- a/SWADroid/build.gradle +++ b/SWADroid/build.gradle @@ -86,6 +86,6 @@ dependencies { implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' implementation 'com.google.zxing:core:3.4.0' - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.firebase:firebase-core:17.2.0' } \ No newline at end of file From 37901a00c4550c2b2e46d114cf11e0afb239de88 Mon Sep 17 00:00:00 2001 From: Amab Date: Sat, 26 Oct 2019 17:47:53 +0200 Subject: [PATCH 05/13] Updated minSdkVersion to 24 (Android 7.0) --- SWADroid/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SWADroid/build.gradle b/SWADroid/build.gradle index 488e35289..7087b9cb5 100644 --- a/SWADroid/build.gradle +++ b/SWADroid/build.gradle @@ -61,7 +61,7 @@ android { versionCode gitVersionCode versionName gitVersionName - minSdkVersion 16 + minSdkVersion 24 targetSdkVersion 29 testApplicationId "es.ugr.swad.swadroid.test" From 15587d7717a80a6ab1ed3101fcfa23123c9b650b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2019 17:59:45 +0200 Subject: [PATCH 06/13] Bump zxing-android-embedded from 3.6.0 to 4.0.2 (#259) Bumps zxing-android-embedded from 3.6.0 to 4.0.2. Signed-off-by: dependabot-preview[bot] --- SWADroid/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SWADroid/build.gradle b/SWADroid/build.gradle index b6d6aec88..11459e74f 100644 --- a/SWADroid/build.gradle +++ b/SWADroid/build.gradle @@ -84,7 +84,7 @@ dependencies { implementation 'com.google.code.ksoap2-android:ksoap2-android:3.6.4' implementation 'commons-io:commons-io:2.6' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' - implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' + implementation 'com.journeyapps:zxing-android-embedded:4.0.2@aar' implementation 'com.google.zxing:core:3.4.0' implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.firebase:firebase-core:17.2.0' From c365299c18e2dfbf41becbc58b1d3aa49aab5970 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sat, 26 Oct 2019 18:09:40 +0200 Subject: [PATCH 07/13] Bump firebase-core from 17.2.0 to 17.2.1 (#260) Bumps firebase-core from 17.2.0 to 17.2.1. Signed-off-by: dependabot-preview[bot] --- SWADroid/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SWADroid/build.gradle b/SWADroid/build.gradle index 11459e74f..73656c890 100644 --- a/SWADroid/build.gradle +++ b/SWADroid/build.gradle @@ -87,5 +87,5 @@ dependencies { implementation 'com.journeyapps:zxing-android-embedded:4.0.2@aar' implementation 'com.google.zxing:core:3.4.0' implementation 'com.google.code.gson:gson:2.8.6' - implementation 'com.google.firebase:firebase-core:17.2.0' + implementation 'com.google.firebase:firebase-core:17.2.1' } \ No newline at end of file From f8b0d99011dd08198fc45beb69428e82f9f2bf33 Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Sat, 26 Oct 2019 18:13:48 +0200 Subject: [PATCH 08/13] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de0aa09bc..ae6ccb7c4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Android client for e-learning platform [![SWADroid](https://openswad.org/logo/sw [![SWADroid](http://developer.android.com/images/brand/en_generic_rgb_wo_45.png)](https://play.google.com/store/apps/details?id=es.ugr.swad.swadroid) -[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/c/c8/Farm-Fresh_twitter_1.png)](http://twitter.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/4/4d/Farm-Fresh_facebook.png)](https://www.facebook.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/b/ba/Google_plus_32.png)](https://plus.google.com/115615684349730524355/posts)[![SWADroid](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Telegram_Messenger.png/35px-Telegram_Messenger.png?uselang=es)](https://telegram.me/swadroid)[![SWADroid](https://s.w.org/about/images/logos/wordpress-logo-32-blue.png)](http://swadroid.wordpress.com) +[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/c/c8/Farm-Fresh_twitter_1.png)](http://twitter.com/SWADroid)[![SWADroid](http://upload.wikimedia.org/wikipedia/commons/4/4d/Farm-Fresh_facebook.png)](https://www.facebook.com/SWADroid)[![SWADroid](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Telegram_Messenger.png/35px-Telegram_Messenger.png?uselang=es)](https://telegram.me/swadroid)[![SWADroid](https://s.w.org/about/images/logos/wordpress-logo-32-blue.png)](http://swadroid.wordpress.com) CI Status --------- From a48ce0df57c50abcc24c2454a1ad848d5ebac32f Mon Sep 17 00:00:00 2001 From: Amab Date: Sat, 26 Oct 2019 18:33:16 +0200 Subject: [PATCH 09/13] Added codecov token --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6c16029ab..3f5ce57b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ env: - ANDROID_BUILD_TOOLS=29.0.2 - secure: eY3bGKw4jZ+HHkkMBZHiL2dhcz+RJYHib0WC77SSVHLJcCg63pBvs420i4rjNQHycMs+PhRSlR79jdglDTm8svphhRjSts6VMkHDxObwJIyLF8vAZ0PfjhqfOXO+4+Fx6pRIjwM7cBMOQrDfSimJHRB+z/f2AJfUIsaMSlltGVya7nmrLY/fO4dtl4wPnejslj3mhnBAxr+a2Or978RwI2TMpxBovHZKFT/46wJTcMzKXGdXU64M8nmQmpcKHeIKIBiR4g+A2tahC+Us4tFxxoTDd3R+IAzj7Gvjd5JuMlYmQ3quRv2M08u9OJNiT14LpDXy19fZKdw/QNHg3S8JVis8kJDkv6z4HyZXTIBgISZpCZZti04GP29Lj+1f4ISRFc6uxankDuRgfX8ucsxoEPJVq3PfJlpTdP7wjlQtEGv0HF/3MNNyruNbLHFiCgHOANwEOX44INtw6XylPEftmw4y4ptntFG3VXyV1Zi+732Qe4b2QNTbvLPrsmkCRKzo59vKKAzBBhvYvFVITcWbySqdx9/n1H25SRL2Q96nPGQSQyBF6obzzFcjMKkknPle1PXvAfb171964cdIK6/zo9rh/ZCL3+gAKZibmGWvbeztWYl5ON8B8x8mgLO/qgPIotY+aqwmsY06pKrqi6adYZacMF+UgtbLJlhnird6ugk= - secure: EmcSyXk/5pEJhbRX9DSFzhQGYvGaYdxjDuQwmLuxUGitGpFQZbWexTAK/l0LLcIRsiSmucY7KJgOpL7I6odh2kVUZedarj8/5K1P69ljDDB7bfG8jyOLZvHJ1JTZRuKvUnT846zQwQWTnLXF9N4LaQ86FVqSW2bGHqptIivEjDEVh78V3g4PDsbX5aQ5LjTlSn7bezu9chpVS0fnRlqjAa6U2kUwUt+DDaSHEOs35Z89jT7JoonGFrMsyA7S26CQhOBYE3w76AllIea+MWzPJX3V364ZIzPBnQAkCz02oVI3n+LHZkzUCYHkY8DXWXNy6+/sulFa6L1v6bt8DzF1vwJ+nTNVqmqSDYBe2s1qAUZ+4o8l/THMndxC11LjbbEExG4ekBRFvRsOOf0pBps3Yr4ry27gaj4+9Ap2JCKKOQwm0izh48AJiy0Y8pzIzTO5wB5B7a4czLJmzaNWkPVXw4lKg2ldJ4sd6EBqUZqG2vRmN6VwHb8gHFNaQTH3feBRhYTpkv1wWUuhvclNn5yoZzcSxMT/b8d89e5DahoBYMW48c6jb5wL/EoY3bHp3mjtnTW8oIIjyZK8FjYX+8IqeEoue8bDDqNUN71xmRvp+0CX1iXnfgUeDWnYhXHTewOlJu6i509wGrZPxYjgwAdnpfTyGXPq7Vin9CkNHMw9fbA= + - secure: WS7Jgz0L0aMEZmg4/HxPb9nO7oER9z23n8n508UVQ0DyKL92UPhfVol7+Cob8zuO5SJl5TPOh58gd/C0Prq8t5q3mwlDA9buhnb1uef7pwZOFzQOF0o8RuPSpxLgu8tFlDooWrG9oxZObXwh84TXGX7zgoiWr9Y318qsQSHCiv9Ue9kgJxkjk9wVanJws7zHWAevfFzyoEvqtkDTqNie4RJbMEOdeX+TyUpc77Si2UpAC23Mpl8q+qZr32cgxk3MzSdhJk2C3Vz5MS6LBZ7ynyv+em+/vz2RBlFLetrcknHY8lgE060itWcns6Pj/8tv2SQbJptVFToXbfay/EVleApojHG4w5DFDzQt8a3Az0lBnqOxv3BiAPRcr49/A08qXAKh30p6YBiSvVd8zK+MZoMoj2dDQhdXb72nv0yHZmzkiaQEOGnsBD4Gt3epn/KoJke3W0ffBZOfJNScACW0Gta2XLImZsekb4sjfOF84HrISSMiXunlLpgtcC4C3Pn9VV/6+uciIMqMFDYkJMe2gyRNA2vSyZ61n/ioTLOHYzhYHjZUXB4MOlonYTiFuF4HmVVHO2J9CpOdFFP7hrkWK3HzvcQm9k8dxUkuKDoOlRb+CSlrEZO24V+TaY2DDr1bcitA77VJp90Cz2RpLC3tvSvThgY2VNk+OEbeSrP5DNA= before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -rf $HOME/.gradle/caches/*/plugin-resolution/ @@ -17,8 +18,8 @@ cache: - "$HOME/.android/build-cache" before_install: - openssl aes-256-cbc -K $encrypted_b7f76037f2f7_key -iv $encrypted_b7f76037f2f7_iv - -in $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json.enc - -out $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json -d + -in $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json.enc -out $TRAVIS_BUILD_DIR/SWADroid/src/prod/google-services.json + -d - yes | sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" - yes | sdkmanager "platform-tools" - yes | sdkmanager "tools" From b0e6017169f7066aca7715b185ba8655204432f8 Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Sat, 26 Oct 2019 18:41:27 +0200 Subject: [PATCH 10/13] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ae6ccb7c4..7257e4596 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ CI Status [![Releases](https://img.shields.io/github/release/Amab/SWADroid.svg)](https://github.com/Amab/SWADroid/releases/latest) [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=Amab/SWADroid)](https://dependabot.com) [![libraries.io](https://img.shields.io/librariesio/github/Amab/SWADroid.svg)](https://libraries.io/github/Amab/SWADroid) +[![codecov](https://codecov.io/gh/Amab/SWADroid/branch/develop/graph/badge.svg)](https://codecov.io/gh/Amab/SWADroid) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/41ded03ee87d4ceaaafc976a7529bcf3)](https://www.codacy.com/manual/Amab/SWADroid?utm_source=github.com&utm_medium=referral&utm_content=Amab/SWADroid&utm_campaign=Badge_Grade) Copyright and License --------------------- From 0126888e108726b3c1fc4373cd2abc63c2157cec Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Mon, 4 Nov 2019 19:57:17 +0100 Subject: [PATCH 11/13] Update gradle version (#261) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c3659e87e..920057939 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.android.tools.build:gradle:3.5.2' classpath 'org.ajoberstar:grgit:2.1.1' classpath 'com.google.gms:google-services:4.3.2' } From cfdbecb0aa57d16f5a8225da3c953af95e3405cd Mon Sep 17 00:00:00 2001 From: Juan Miguel Boyero Corral Date: Tue, 5 Nov 2019 20:53:15 +0100 Subject: [PATCH 12/13] Rollcall: Fixed SWADroid allows multiple simultaneous submissions of the attendance list (#263) * Fix #262 * Updated CHANGELOG * Rollcall: Fixed The default image is not displayed if the user does not have a photo --- .../swadroid/modules/rollcall/Rollcall.java | 405 +++++++++--------- .../modules/rollcall/UsersActivity.java | 48 ++- .../modules/rollcall/UsersCursorAdapter.java | 27 +- .../modules/rollcall/UsersDownload.java | 4 +- SWADroid/src/main/res/raw-es/changes.html | 6 + SWADroid/src/main/res/raw/changes.html | 6 + 6 files changed, 269 insertions(+), 227 deletions(-) diff --git a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/Rollcall.java b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/Rollcall.java index ba15feb59..b3e5a0e44 100644 --- a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/Rollcall.java +++ b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/Rollcall.java @@ -50,196 +50,197 @@ * @author Juan Miguel Boyero Corral */ public class Rollcall extends MenuExpandableListActivity implements - SwipeRefreshLayout.OnRefreshListener { - - /** - * Rollcall tag name for Logcat - */ - private static final String TAG = Constants.APP_TAG + " Rollcall"; - /** - * ListView of events - */ - private static ListView lvEvents; - /** - * Adapter for ListView of events - */ - private static EventsCursorAdapter adapter; - private final RefreshAdapterHandler mHandler = new RefreshAdapterHandler(this); - private final Runnable mRunnable = new Runnable() { - @Override - public void run() { + SwipeRefreshLayout.OnRefreshListener { + + /** + * Rollcall tag name for Logcat + */ + private static final String TAG = Constants.APP_TAG + " Rollcall"; + /** + * ListView of events + */ + private ListView lvEvents; + /** + * Adapter for ListView of events + */ + private static EventsCursorAdapter adapter; + private final RefreshAdapterHandler mHandler = new RefreshAdapterHandler(this); + private final Runnable mRunnable = new Runnable() { + @Override + public void run() { /* Database cursor for Adapter of events */ - Cursor dbCursor = dbHelper.getEventsCourseCursor(Courses.getSelectedCourseCode()); - startManagingCursor(dbCursor); + Cursor dbCursor = dbHelper.getEventsCourseCursor(Courses.getSelectedCourseCode()); + startManagingCursor(dbCursor); - /* - * If there aren't events to show, hide the events lvEvents - * and show the empty events message - */ - if ((dbCursor == null) || (dbCursor.getCount() == 0)) { - Log.d(TAG, "Events list is empty"); + /* + * If there aren't events to show, hide the events lvEvents + * and show the empty events message + */ + if ((dbCursor == null) || (dbCursor.getCount() == 0)) { + Log.d(TAG, "Events list is empty"); - emptyEventsTextView.setText(R.string.eventsEmptyListMsg); - emptyEventsTextView.setVisibility(View.VISIBLE); + emptyEventsTextView.setText(R.string.eventsEmptyListMsg); + emptyEventsTextView.setVisibility(View.VISIBLE); - lvEvents.setVisibility(View.GONE); - } else { - Log.d(TAG, "Events list is not empty"); + lvEvents.setVisibility(View.GONE); + } else { + Log.d(TAG, "Events list is not empty"); - emptyEventsTextView.setVisibility(View.GONE); - lvEvents.setVisibility(View.VISIBLE); - } + emptyEventsTextView.setVisibility(View.GONE); + lvEvents.setVisibility(View.VISIBLE); + } - adapter = new EventsCursorAdapter(getBaseContext(), dbCursor, dbHelper); - lvEvents.setAdapter(adapter); + adapter = new EventsCursorAdapter(getBaseContext(), dbCursor, dbHelper); + lvEvents.setAdapter(adapter); - mProgressScreen.hide(); - } - }; - /** - * TextView for the empty events message - */ - private TextView emptyEventsTextView; - /** - * Layout with "Pull to refresh" function - */ - private SwipeRefreshLayout refreshLayout; - /** - * Progress screen - */ - private ProgressScreen mProgressScreen; - /** - * ListView click listener - */ - private ListView.OnItemClickListener clickListener = new ListView.OnItemClickListener() { + mProgressScreen.hide(); + } + }; + /** + * TextView for the empty events message + */ + private TextView emptyEventsTextView; + /** + * Layout with "Pull to refresh" function + */ + private SwipeRefreshLayout refreshLayout; + /** + * Progress screen + */ + private ProgressScreen mProgressScreen; + /** + * ListView click listener + */ + private ListView.OnItemClickListener clickListener = new ListView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Intent activity = new Intent(getApplicationContext(), + UsersActivity.class); + activity.putExtra("attendanceEventCode", + (int) adapter.getItemId(position)); + startActivity(activity); + } + }; + + /* (non-Javadoc) + * @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle) + */ @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - Intent activity = new Intent(getApplicationContext(), - UsersActivity.class); - activity.putExtra("attendanceEventCode", - (int) adapter.getItemId(position)); - startActivity(activity); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.list_items_pulltorefresh); + + refreshLayout = findViewById(R.id.swipe_container_list); + emptyEventsTextView = findViewById(R.id.list_item_title); + + View mProgressScreenView = findViewById(R.id.progress_screen); + mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout, + getString(R.string.loadingMsg), this); + + lvEvents = findViewById(R.id.list_pulltorefresh); + + lvEvents.setOnItemClickListener(clickListener); + lvEvents.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView absListView, int scrollState) { + } + + @Override + public void onScroll(AbsListView absListView, int firstVisibleItem, + int visibleItemCount, int totalItemCount) { + + boolean enable = true; + if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) { + // check if the first item of the list is visible + boolean firstItemVisible = lvEvents.getFirstVisiblePosition() == 0; + // check if the top of the first item is visible + boolean topOfFirstItemVisible = lvEvents.getChildAt(0).getTop() == 0; + // enabling or disabling the refresh layout + enable = firstItemVisible && topOfFirstItemVisible; + } + refreshLayout.setEnabled(enable); + } + }); + + refreshLayout.setOnRefreshListener(this); + setAppearance(); + + getSupportActionBar().setSubtitle(Courses.getSelectedCourseShortName()); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); } - }; - - /* (non-Javadoc) - * @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle) - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.list_items_pulltorefresh); - - refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container_list); - emptyEventsTextView = (TextView) findViewById(R.id.list_item_title); - - View mProgressScreenView = findViewById(R.id.progress_screen); - mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout, - getString(R.string.loadingMsg), this); - lvEvents = (ListView) findViewById(R.id.list_pulltorefresh); - - lvEvents.setOnItemClickListener(clickListener); - lvEvents.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView absListView, int scrollState) { - } + /* (non-Javadoc) + * @see es.ugr.swad.swadroid.MenuExpandableListActivity#Override(android.os.Bundle) + */ + @Override + protected void onStart() { + super.onStart(); - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { + //Refresh ListView of events + refreshAdapter(); + } - boolean enable = true; - if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) { - // check if the first item of the list is visible - boolean firstItemVisible = lvEvents.getFirstVisiblePosition() == 0; - // check if the top of the first item is visible - boolean topOfFirstItemVisible = lvEvents.getChildAt(0).getTop() == 0; - // enabling or disabling the refresh layout - enable = firstItemVisible && topOfFirstItemVisible; + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + switch (requestCode) { + case Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE: + refreshAdapter(); + break; } - refreshLayout.setEnabled(enable); - } - }); - - refreshLayout.setOnRefreshListener(this); - setAppearance(); + super.onActivityResult(requestCode, resultCode, intent); + } - getSupportActionBar().setSubtitle(Courses.getSelectedCourseShortName()); + private void refreshAdapter() { + mHandler.post(mRunnable); + } - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } + private void refreshEvents() { + mProgressScreen.show(); + Intent activity = new Intent(this, EventsDownload.class); + startActivityForResult(activity, Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE); + } - /* (non-Javadoc) - * @see es.ugr.swad.swadroid.MenuExpandableListActivity#Override(android.os.Bundle) - */ - @Override - protected void onStart() { - super.onStart(); - - //Refresh ListView of events - refreshAdapter(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent intent) { - switch (requestCode) { - case Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE: - refreshAdapter(); - break; + /** + * It shows the SwipeRefreshLayout progress + */ + private void showSwipeProgress() { + refreshLayout.setRefreshing(true); } - } - private void refreshAdapter() { - mHandler.post(mRunnable); - } + /** + * It shows the SwipeRefreshLayout progress + */ + private void hideSwipeProgress() { + refreshLayout.setRefreshing(false); + } - private void refreshEvents() { - mProgressScreen.show(); - Intent activity = new Intent(this, EventsDownload.class); - startActivityForResult(activity, Constants.ROLLCALL_EVENTS_DOWNLOAD_REQUEST_CODE); - } + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + private void setAppearance() { + refreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright, + android.R.color.holo_green_light, + android.R.color.holo_orange_light, + android.R.color.holo_red_light); + } - /** - * It shows the SwipeRefreshLayout progress - */ - private void showSwipeProgress() { - refreshLayout.setRefreshing(true); - } + private boolean hasPendingEvents() { + boolean hasPendingEvents = false; + TextView sendingStateTextView; + int i = 0; - /** - * It shows the SwipeRefreshLayout progress - */ - private void hideSwipeProgress() { - refreshLayout.setRefreshing(false); - } - - @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) - private void setAppearance() { - refreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright, - android.R.color.holo_green_light, - android.R.color.holo_orange_light, - android.R.color.holo_red_light); - } - - private boolean hasPendingEvents() { - boolean hasPendingEvents = false; - TextView sendingStateTextView; - int i = 0; - - if ((lvEvents != null) && (lvEvents.getChildCount() > 0)) { - while(!hasPendingEvents && (i 0)) { + while(!hasPendingEvents && (i mActivity; - private final WeakReference mActivity; + public RefreshAdapterHandler(Rollcall activity) { + mActivity = new WeakReference<>(activity); + } - public RefreshAdapterHandler(Rollcall activity) { - mActivity = new WeakReference<>(activity); } - - } } diff --git a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersActivity.java b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersActivity.java index 276f43dd5..a39078dc8 100644 --- a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersActivity.java +++ b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersActivity.java @@ -74,7 +74,7 @@ public class UsersActivity extends MenuExpandableListActivity implements /** * ListView of users */ - private static ListView lvUsers; + private ListView lvUsers; /** * Adapter for ListView of users */ @@ -105,6 +105,16 @@ public class UsersActivity extends MenuExpandableListActivity implements */ private IntentIntegrator integrator; + /** + * Button for send attendances to SWAD + */ + private MenuItem mSendUsersMenuItem; + + /** + * Button for clear all users for an event + */ + private MenuItem mCleanUsersMenuItem; + /* (non-Javadoc) * @see es.ugr.swad.swadroid.MenuExpandableListActivity#onCreate(android.os.Bundle) */ @@ -113,14 +123,14 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_items_pulltorefresh); - refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container_list); - emptyUsersTextView = (TextView) findViewById(R.id.list_item_title); + refreshLayout = findViewById(R.id.swipe_container_list); + emptyUsersTextView = findViewById(R.id.list_item_title); View mProgressScreenView = findViewById(R.id.progress_screen); mProgressScreen = new ProgressScreen(mProgressScreenView, refreshLayout, getString(R.string.loadingMsg), this); - lvUsers = (ListView) findViewById(R.id.list_pulltorefresh); + lvUsers = findViewById(R.id.list_pulltorefresh); lvUsers.setOnScrollListener(new AbsListView.OnScrollListener() { @Override @@ -165,6 +175,9 @@ protected void onStart() { @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { refreshAdapter(); + setActionMenuItemsEnabled(true); + + super.onActivityResult(requestCode, resultCode, intent); } private void refreshAdapter() { @@ -243,39 +256,50 @@ private void setAppearance() { */ @Override public void onRefresh() { + setActionMenuItemsEnabled(false); showSwipeProgress(); refreshUsers(); hideSwipeProgress(); + setActionMenuItemsEnabled(true); } private String getUsersCodes() { - String usersCodes = ""; + StringBuilder usersCodes = new StringBuilder(); List usersList = dbHelper.getUsersEvent(eventCode); //Concatenate the user code of all users checked as present and separate them with commas for(UserAttendance user : usersList) { if(user.isUserPresent()) { - usersCodes += user.getId() + ","; + usersCodes.append(user.getId()).append(","); } } //Remove final comma - if(!usersCodes.isEmpty()) { - usersCodes = usersCodes.substring(0, usersCodes.length()-1); + if(usersCodes.length() > 0) { + usersCodes = new StringBuilder(usersCodes.substring(0, usersCodes.length() - 1)); } - return usersCodes; + return usersCodes.toString(); } private void scanQRCode() { integrator.initiateScan(); } + private void setActionMenuItemsEnabled(boolean enabled) { + mSendUsersMenuItem.setEnabled(enabled); + mCleanUsersMenuItem.setEnabled(enabled); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.rollcall_activity_actions, menu); + + mSendUsersMenuItem = menu.findItem(R.id.action_sendMsg); + mCleanUsersMenuItem = menu.findItem(R.id.action_cleanUsers); + return super.onCreateOptionsMenu(menu); } @@ -302,6 +326,8 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.action_sendMsg: + setActionMenuItemsEnabled(false); + String usersCodes = getUsersCodes(); Intent activity = new Intent(getApplicationContext(), @@ -318,6 +344,8 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.action_cleanUsers: + setActionMenuItemsEnabled(false); + AlertDialog cleanDBDialog = DialogFactory.createWarningDialog(this, -1, R.string.areYouSure, @@ -358,7 +386,7 @@ public static int getEventCode() { } @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case Constants.PERMISSIONS_REQUEST_CAMERA: { diff --git a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersCursorAdapter.java b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersCursorAdapter.java index f824afbfe..b95580773 100644 --- a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersCursorAdapter.java +++ b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersCursorAdapter.java @@ -108,7 +108,7 @@ public void bindView(View view, Context context, Cursor cursor) { String userFirstname = crypto.decrypt(cursor.getString(cursor.getColumnIndex("userFirstname"))); String userID = crypto.decrypt(cursor.getString(cursor.getColumnIndex("userID"))); final long userCode = cursor.getLong(cursor.getColumnIndex("userCode")); - String userPhoto = cursor.getString(cursor.getColumnIndex("photoPath")); + String userPhoto = crypto.decrypt(cursor.getString(cursor.getColumnIndex("photoPath"))); boolean present = Utils.parseIntBool(cursor.getInt(cursor.getColumnIndex("present"))); // Replace NULL value for strings returned by the webservice with the empty string @@ -127,10 +127,10 @@ public void bindView(View view, Context context, Cursor cursor) { final ViewHolder holder = (ViewHolder) view.getTag(); view.setTag(holder); - holder.image = (ImageView) view.findViewById(R.id.imageView1); - holder.text1 = (TextView) view.findViewById(R.id.TextView1); - holder.text2 = (TextView) view.findViewById(R.id.TextView2); - holder.checkbox = (CheckBox) view.findViewById(R.id.check); + holder.image = view.findViewById(R.id.imageView1); + holder.text1 = view.findViewById(R.id.TextView1); + holder.text2 = view.findViewById(R.id.TextView2); + holder.checkbox = view.findViewById(R.id.check); holder.checkbox.setChecked(present); holder.checkbox.setOnClickListener(new View.OnClickListener() { @@ -152,12 +152,13 @@ public void onClick(View v) { } }); - holder.image.setImageResource(R.drawable.usr_bl); - if(userPhoto != null) { - ImageFactory.displayImage(loader, crypto.decrypt(userPhoto), holder.image); + if((userPhoto != null) && !userPhoto.isEmpty()) { + ImageFactory.displayImage(loader, userPhoto, holder.image); + } else { + holder.image.setImageResource(R.drawable.usr_bl); } - holder.text1.setText(userSurname1 + " " + userSurname2 + ", " + userFirstname); + holder.text1.setText(String.format("%s %s, %s", userSurname1, userSurname2, userFirstname)); holder.text2.setText(userID); } @@ -166,10 +167,10 @@ public View newView(Context context, Cursor cursor, ViewGroup parent) { View view = inflater.inflate(R.layout.users_list_item, parent, false); ViewHolder holder = new ViewHolder(); - holder.image = (ImageView) view.findViewById(R.id.imageView1); - holder.text1 = (TextView) view.findViewById(R.id.TextView1); - holder.text2 = (TextView) view.findViewById(R.id.TextView2); - holder.checkbox = (CheckBox) view.findViewById(R.id.check); + holder.image = view.findViewById(R.id.imageView1); + holder.text1 = view.findViewById(R.id.TextView1); + holder.text2 = view.findViewById(R.id.TextView2); + holder.checkbox = view.findViewById(R.id.check); view.setTag(holder); return view; diff --git a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersDownload.java b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersDownload.java index 5cafc4c5a..e06ddb3c0 100644 --- a/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersDownload.java +++ b/SWADroid/src/main/java/es/ugr/swad/swadroid/modules/rollcall/UsersDownload.java @@ -122,7 +122,7 @@ protected void requestService() throws Exception { if (userSurname1.equalsIgnoreCase(Constants.NULL_VALUE)) userSurname1 = ""; if (userSurname2.equalsIgnoreCase(Constants.NULL_VALUE)) userSurname2 = ""; if (userFirstname.equalsIgnoreCase(Constants.NULL_VALUE)) userFirstname = ""; - if (userPhoto.equalsIgnoreCase(Constants.NULL_VALUE)) userPhoto = null; + if (userPhoto.equalsIgnoreCase(Constants.NULL_VALUE)) userPhoto = ""; //Inserts user data into database dbHelper.insertUser(new User(userCode, null, userID, userNickname, userSurname1, userSurname2, @@ -153,7 +153,7 @@ protected void postConnect() { if (numUsers == 0) { Toast.makeText(this, R.string.noUsersAvailableMsg, Toast.LENGTH_LONG).show(); } else { - String msg = String.valueOf(numUsers) + " " + getResources().getString(R.string.usersUpdated); + String msg = numUsers + " " + getResources().getString(R.string.usersUpdated); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } diff --git a/SWADroid/src/main/res/raw-es/changes.html b/SWADroid/src/main/res/raw-es/changes.html index 1814b9a6e..33dc4d152 100644 --- a/SWADroid/src/main/res/raw-es/changes.html +++ b/SWADroid/src/main/res/raw-es/changes.html @@ -14,6 +14,12 @@ + +

1.5.6 (futura)

+
    +
  • Pasar lista: Corregida ejecución simultánea de varios envíos de la lista de asistencia
  • +
+

1.5.5 (2019-07-08)

    diff --git a/SWADroid/src/main/res/raw/changes.html b/SWADroid/src/main/res/raw/changes.html index 47ea3ef9a..003007ab8 100644 --- a/SWADroid/src/main/res/raw/changes.html +++ b/SWADroid/src/main/res/raw/changes.html @@ -14,6 +14,12 @@ + +

    1.5.6 (upcoming)

    +
      +
    • Rollcall: Fixed SWADroid allows multiple simultaneous submissions of the attendance list
    • +
    +

    1.5.5 (2019-07-08)

      From a53efc52bca9e4d744cb24a20f6d63aa1ea4331c Mon Sep 17 00:00:00 2001 From: Amab Date: Tue, 5 Nov 2019 21:02:16 +0100 Subject: [PATCH 13/13] Updated CHANGELOG --- SWADroid/src/main/res/raw-es/changes.html | 2 +- SWADroid/src/main/res/raw/changes.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SWADroid/src/main/res/raw-es/changes.html b/SWADroid/src/main/res/raw-es/changes.html index 33dc4d152..f08b5b434 100644 --- a/SWADroid/src/main/res/raw-es/changes.html +++ b/SWADroid/src/main/res/raw-es/changes.html @@ -15,7 +15,7 @@ -

      1.5.6 (futura)

      +

      1.5.6 (2019-11-05)

      • Pasar lista: Corregida ejecución simultánea de varios envíos de la lista de asistencia
      diff --git a/SWADroid/src/main/res/raw/changes.html b/SWADroid/src/main/res/raw/changes.html index 003007ab8..60b0589aa 100644 --- a/SWADroid/src/main/res/raw/changes.html +++ b/SWADroid/src/main/res/raw/changes.html @@ -15,7 +15,7 @@ -

      1.5.6 (upcoming)

      +

      1.5.6 (2019-11-05)

      • Rollcall: Fixed SWADroid allows multiple simultaneous submissions of the attendance list