1
0
Fork 1

Compare commits

..

No commits in common. "2.6.0" and "0.25.1" have entirely different histories.

1002 changed files with 13133 additions and 117194 deletions

View file

@ -162,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 publishPlayRelease --no-daemon --stacktrace --console=plain -PdisablePreDex command: ./gradlew publishPlayRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
workflows: workflows:
version: 2 version: 2

View file

@ -1,12 +0,0 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4
[*.json]
indent_size=2
[*.{kt,kts}]
disabled_rules=import-ordering,no-wildcard-imports

4
.github/FUNDING.yml vendored
View file

@ -1,4 +0,0 @@
# These are supported funding model platforms
github: wulkanowy
custom: https://www.paypal.com/paypalme/wulkanowy

View file

@ -1,12 +1,3 @@
---
name: Bug report
about: Utwórz raport błędu, aby pomóc nam ulepszyć Wulkanowego
title: ''
labels: ''
assignees: ''
---
## Co powinno się dziać ## Co powinno się dziać

View file

@ -1,20 +0,0 @@
---
name: Feature request
about: Zaproponuj nowy pomysł dla Wulkanowego
title: ''
labels: ''
assignees: ''
---
** Czy Twoja prośba o funkcję jest związana z problemem? Proszę opisz.**
Jasny i zwięzły opis problemu. Np. Zawsze jestem sfrustrowany, gdy [...]
** Opisz żądane rozwiązanie **
Jasny i zwięzły opis tego, co chcesz, aby się wydarzyło.
** Opisz alternatywy, które rozważałeś **
Jasny i zwięzły opis wszelkich rozważanych alternatywnych rozwiązań lub funkcji.
** Dodatkowy kontekst **
Dodaj inny kontekst lub zrzuty ekranu dotyczące żądania funkcji tutaj.

View file

@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: gradle
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
target-branch: develop
ignore:
- dependency-name: io.github.wulkanowy:sdk
reviewers:
- Faierbel

View file

@ -1,79 +0,0 @@
name: Deploy release
on:
release:
types: [ created ]
jobs:
deploy-google-play:
name: Google Play
runs-on: ubuntu-latest
timeout-minutes: 10
environment: google-play
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Upload apk to google play
env:
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }}
ADMOB_PROJECT_ID: ${{ secrets.ADMOB_PROJECT_ID }}
SINGLE_SUPPORT_AD_ID: ${{ secrets.SINGLE_SUPPORT_AD_ID }}
DASHBOARD_TILE_AD_ID: ${{ secrets.DASHBOARD_TILE_AD_ID }}
SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
run: ./gradlew publishPlayReleaseApps --stacktrace;
deploy-app-gallery:
name: AppGallery
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-gallery
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: |
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
- name: Prepare credentials
env:
AGC_CREDENTIALS: ${{ secrets.AGC_CREDENTIALS }}
run: echo $AGC_CREDENTIALS > ./app/src/release/agconnect-credentials.json
- name: Build and publish HMS version
env:
PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
run: ./gradlew bundleHmsRelease --stacktrace && ./gradlew publishHuaweiAppGalleryHmsRelease --stacktrace

View file

@ -1,145 +0,0 @@
name: Deploy DEV
on:
push:
# branches: [ develop ]
branches: [ '!*' ]
pull_request_target:
# branches: [ develop ]
branches: [ '!*' ]
workflow_dispatch:
jobs:
deploy-appcenter:
name: App Center
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-center
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- uses: actions/cache@v3
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/google-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@v3
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: App Distribution
runs-on: ubuntu-latest
timeout-minutes: 10
environment: app-distribution
if: github.event_name != 'pull_request_target'
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- uses: actions/cache@v3
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 --stacktrace
- name: Upload apk to github artifacts
uses: actions/upload-artifact@v3
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

View file

@ -1,90 +1,142 @@
name: Tests name: Test and deploy
on: on:
push: push:
branches: branches: [ develop ]
- master
- develop
- 'hotfix/**'
tags: [ '*' ] tags: [ '*' ]
pull_request: pull_request:
branches: [ develop ]
workflow_dispatch:
jobs: jobs:
build:
name: Pre-build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- 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: Build
run: ./gradlew --build-cache compileFdroidDebugUnitTestKotlin preFdroidDebugAndroidTestBuild dexBuilderFdroidDebugAndroidTest packageFdroidDebug packageFdroidDebugAndroidTest
- name: Prepare build cache
run: tar -cf prebuild.tar .build-cache .gradle app/build
- uses: actions/upload-artifact@v2
with:
name: prebuild.tar
path: prebuild.tar
tests-fdroid: unit-tests:
name: F-Droid name: Unit tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10 timeout-minutes: 10
needs: [ build ]
steps: steps:
- uses: fkirc/skip-duplicate-actions@master - uses: actions/checkout@v2
- uses: actions/checkout@v3 - uses: actions/setup-java@v1
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
with: with:
distribution: 'zulu' java-version: 11
java-version: 17 - uses: actions/cache@v2
- uses: actions/cache@v3
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
~/.gradle/wrapper ~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }} key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Unit tests - name: Unit tests
run: | run: |
./gradlew testFdroidDebugUnitTest --stacktrace ./gradlew --build-cache -Pcoverage testFdroidDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace ./gradlew --build-cache -Pcoverage jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v3 - uses: codecov/codecov-action@v1
with: with:
flags: unit flags: unit
tests-play: instrumentation-tests:
name: Play name: Instrumentation tests
runs-on: macOS-latest
timeout-minutes: 15
needs: [ build ]
strategy:
fail-fast: true
matrix:
api-level: [21, 29]
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*') }}
- uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Instrumentation tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86
script: |
./gradlew --build-cache -Pcoverage connectedFdroidDebugAndroidTest --stacktrace
./gradlew --build-cache -Pcoverage jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v1
with:
flags: instrumented,api-${{ matrix.api-level }}
deploy-google-play:
name: Deploy to google play
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 10 timeout-minutes: 10
environment: google-play
needs: [ build, unit-tests, instrumentation-tests ]
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
steps: steps:
- uses: fkirc/skip-duplicate-actions@master - uses: actions/checkout@v2
- uses: actions/checkout@v3 - uses: actions/setup-java@v1
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
with: with:
distribution: 'zulu' java-version: 11
java-version: 17 - uses: actions/cache@v2
- uses: actions/cache@v3
with: with:
path: | path: |
~/.gradle/caches ~/.gradle/caches
~/.gradle/wrapper ~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }} key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Unit tests - uses: actions/download-artifact@v2
with:
name: prebuild.tar
- name: Extract build cache
run: tar -xf prebuild.tar
- name: Decrypt keys
env:
ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
run: | run: |
./gradlew testPlayDebugUnitTest --stacktrace gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
./gradlew jacocoTestReport --stacktrace gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg
- uses: codecov/codecov-action@v3 gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
with: - name: Upload apk to google play
flags: unit env:
PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
tests-hms: PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
name: HMS PLAY_SERVICE_ACCOUNT_EMAIL: ${{ secrets.PLAY_SERVICE_ACCOUNT_EMAIL }}
runs-on: ubuntu-latest PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
timeout-minutes: 10 run: ./gradlew publishPlayRelease -PenableFirebase --stacktrace;
steps:
- uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
- name: Unit tests
run: |
./gradlew testHmsDebugUnitTest --stacktrace
./gradlew jacocoTestReport --stacktrace
- uses: codecov/codecov-action@v3
with:
flags: unit

14
.gitignore vendored
View file

@ -65,12 +65,6 @@ captures/
.idea/uiDesigner.xml .idea/uiDesigner.xml
.idea/runConfigurations.xml .idea/runConfigurations.xml
.idea/discord.xml .idea/discord.xml
.idea/migrations.xml
.idea/androidTestResultsUserPreferences.xml
.idea/copilot
.idea/deploymentTargetDropDown.xml
.idea/deploymentTargetSelector.xml
.idea/kotlinc.xml
# Keystore files # Keystore files
*.jks *.jks
@ -117,13 +111,9 @@ Thumbs.db
*.ear *.ear
### AndroidStudio Patch ### ### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar !/gradle/wrapper/gradle-wrapper.jar
.idea/jarRepositories.xml .idea/jarRepositories.xml
### Services config files
agconnect-services.json
agconnect-credentials.json
google-services.json
!app/google-services.json
app/src/release/agconnect-services.json

View file

@ -2,6 +2,23 @@
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" /> <option name="LINE_SEPARATOR" value="&#10;" />
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<codeStyleSettings language="XML"> <codeStyleSettings language="XML">
@ -118,6 +135,13 @@
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="kotlin"> <codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View file

@ -61,7 +61,7 @@ script:
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg; gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg; gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/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 publishPlayRelease --stacktrace; ./gradlew publishPlayRelease -PenableFirebase --stacktrace;
fi fi
after_success: after_success:

View file

@ -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 2023 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.

View file

@ -1,73 +0,0 @@
Česká verze / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/wulkanowy/wulkanowy/test.yml?branch=develop&style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Neoficiální klient deníku VULCAN UONET+ pro žáka a rodiče
## Funkce
* přihlášení pomocí emailu a hesla
* funkce z webové stránky deníku:
* známky
* statistiky známek
* frekvence
* procento frekvence
* zkoušky
* plán lekce
* dokončené lekce
* zprávy
* domácí úkoly
* poznámky
* šťastné číslo
* další lekce
* školní setkání
* informace o žáku a škole
* výpočet průměru nezávisle na preferencích školy
* upozornění, např. o nových známkách
* podpora více účtů s možností přejmenování žáků
* tmavý a černý (AMOLED) motiv
* offline režim
* volitelné reklamy na podporu projektu
## Stáhnout
Aktuální verzi si můžete stáhnout z Google Play, F-Droid nebo Huawei AppGallery
[<img src="https://play.google.com/intl/cs-CZ/badges/images/generic/cs_badge_web_generic.png"
alt="Nyní na 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="Stáhnout s F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="https://i.imgur.com/baTGiDP.png"
alt="Objevuj v AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Můžete si také stáhnout [vývojovou verzi](https://wulkanowy.github.io/#download), která zahrnuje nové funkce připravované pro příští vydání
## Postaveno s pomocí
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
* [Hilt](https://dagger.dev/hilt/)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Spolupráce
Přispějte do projektu vytvořením PR nebo odesláním issue na GitHub.
Pro zájemce o překlad aplikace do různých jazyků poskytujeme Crowdin:
https://crowdin.com/project/wulkanowy2
## Licence
Tento projekt je licencován pod licencí Apache License 2.0 - podrobnosti v souboru [LICENSE](LICENSE)

View file

@ -1,73 +0,0 @@
[Česká verze](README.cs.md) / Deutsche Version / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/wulkanowy/wulkanowy/test.yml?branch=develop&style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Inoffizieller Android VULCAN UONET+ Registrierungsclient für Schüler und ihre Eltern
## Merkmale
* Einloggen mit E-Mail und Passwort
* Funktionen von der Registerwebsite:
* Noten
* Notenstatistik
* Anwesenheit
* Prozentsatz der Anwesenheit
* Prüfungen
* Stundenplan
* abgeschlossene Unterrichtsstunden
* Nachrichten
* Hausaufgaben
* Anmerkungen
* Glückszahl
* Zusätzliche Lektionen
* Schulkonferenzen
* Schüler- und Schulinformationen
* Berechnung des Durchschnitts unabhängig von den Präferenzen der Schule
* Benachrichtigungen, z. B. über eine neue Note
* Unterstützung für mehrere Konten mit der Möglichkeit, den Namen des Schülers zu ändern
* dunkles und schwarzes (AMOLED) Thema
* Offline-Modus
* optionale Werbungen, die es uns ermöglichen das Projekt zu unterstützen
## Herunterladen
Die aktuelle Version können Sie von der Google Play, F-Droid oder Huawei AppGallery store herunterladen
[<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 F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="appgallery_badge.png"
alt="Explore it on AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Sie können auch eine [Entwicklungsversion herunterladen](https://wulkanowy.github.io/#download) die beinhaltet neue Funktionen, die für die nächste Version vorbereitet werden
## Gebaut mit
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
* [Hilt](https://dagger.dev/hilt/)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Beitragen
Bitte tragen Sie zum Projekt bei, indem Sie entweder eine PR erstellen oder ein Issue auf GitHub einreichen.
Für Personen, die daran interessiert sind, die Anwendung in verschiedene Sprachen zu übersetzen, bieten wir Crowdin
https://crowdin.com/project/wulkanowy2
## Lizenz
Dieses Projekt ist unter der Apache License 2.0 lizenziert - siehe die [LIZENZ](LICENSE) Datei für Details

View file

@ -1,19 +1,18 @@
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / English version / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md) [Polska wersja README](README.md)
# Wulkanowy # Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/wulkanowy/wulkanowy/test.yml?branch=develop&style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Test%20and%20deploy/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy) [![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr) [![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/) [![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases) [![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Unofficial android VULCAN UONET+ register client for both students and their parents Unofficial android VULCAN UONET+ register client for both students and their parents
## Features ## Features
* logging in using the email and password * logging in using the email and password OR using token and pin
* functions from the register website: * functions from the register website:
* grades * grades
* grade statistics * grade statistics
@ -26,19 +25,15 @@ Unofficial android VULCAN UONET+ register client for both students and their par
* homework * homework
* notes * notes
* lucky number * lucky number
* additional lessons
* school conferences
* student and school information
* calculation of the average independently of school's preferences * calculation of the average independently of school's preferences
* notifications, e.g. about a new grade * notifications, e.g. about a new grade
* support for multiple accounts with the ability to rename students
* dark and black (AMOLED) theme * dark and black (AMOLED) theme
* offline mode * offline mode
* optional ads which allow to support the project * no ads
## Download ## Download
You can download the current version from the Google Play, F-Droid or Huawei AppGallery store You can download the current beta version from the Google Play, F-Droid or Huawei AppGallery store
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play" alt="Get it on Google Play"
@ -65,9 +60,6 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
Please contribute to the project either by creating a PR or submitting an issue on GitHub. Please contribute to the project either by creating a PR or submitting an issue on GitHub.
For people interested in translating the application into different languages, we provide Crowdin
https://crowdin.com/project/wulkanowy2
## License ## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details

View file

@ -1,19 +1,18 @@
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / Polska wersja / [Slovenská verzia](README.sk.md) [English version of README](README.en.md)
# Wulkanowy # Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/wulkanowy/wulkanowy/test.yml?branch=develop&style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/wulkanowy/wulkanowy/Test%20and%20deploy/develop?style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy) [![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr) [![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/) [![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases) [![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
## Funkcje ## Funkcje
* logowanie za pomocą e-maila i hasła * logowanie za pomocą e-maila i hasła LUB tokena i pinu
* funkcje ze strony internetowej dziennika: * funkcje ze strony internetowej dziennika:
* oceny * oceny
* statystyki ocen * statystyki ocen
@ -26,19 +25,15 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
* zadania domowe * zadania domowe
* uwagi * uwagi
* szczęśliwy numerek * szczęśliwy numerek
* dodatkowe lekcje
* zebrania w szkole
* informacje o uczniu i szkole
* obliczanie średniej niezależnie od preferencji szkoły * obliczanie średniej niezależnie od preferencji szkoły
* powiadomienia np. o nowej ocenie * powiadomienia np. o nowej ocenie
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
* ciemny i czarny (AMOLED) motyw * ciemny i czarny (AMOLED) motyw
* tryb offline * tryb offilne
* opcjonalne reklamy umożliwiające wsparcie projektu * brak reklam
## Pobierz ## Pobierz
Aktualną wersję możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery Aktualną wersję beta możesz pobrać ze sklepu Google Play, F-Droid lub Huawei AppGallery
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" [<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Pobierz z Google Play" alt="Pobierz z Google Play"
@ -66,9 +61,6 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub. Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub.
Dla osób zainteresowanych tłumaczeniem aplikacji na różne języki udostępniamy Crowdina
https://crowdin.com/project/wulkanowy2
## Licencja ## Licencja
Ten projekt udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE) Ten projekt udostępniany jest na licencji Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)

View file

@ -1,73 +0,0 @@
[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / Slovenská verzia
# Wulkanowy
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/wulkanowy/wulkanowy/test.yml?branch=develop&style=flat-square)](https://github.com/wulkanowy/wulkanowy/actions)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg?style=flat-square)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github&style=flat-square)](https://github.com/wulkanowy/wulkanowy/releases)
[![Crowdin](https://badges.crowdin.net/wulkanowy2/localized.svg)](https://translate.wulkanowy.net.pl)
Neoficiálny klient denníka VULCAN UONET+ pre žiaka a rodičov
## Funkcie
* prihlásenie pomocou emailu a hesla
* funkcie z webovej stránky denníka:
* známky
* štatistiky známok
* frekvencia
* percento frekvencie
* skúšky
* plán lekcie
* dokončené lekcie
* správy
* domáce úlohy
* poznámky
* šťastné číslo
* ďalšie lekcie
* školské stretnutie
* informácie o žiakovi a škole
* výpočet priemeru nezávisle od preferencií školy
* upozornenia, napr. o nových známkach
* podpora viacerých účtov s možnosťou premenovania žiakov
* tmavý a čierny (AMOLED) motív
* offline režim
* voliteľné reklamy na podporu projektu
## Stiahnuť
Aktuálnu verziu si môžete stiahnuť z Google Play, F-Droid alebo Huawei AppGallery
[<img src="https://play.google.com/intl/sk/badges/images/generic/sk_badge_web_generic.png"
alt="Nyní na 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="Stiahnuť s F-Droid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
[<img src="https://i.imgur.com/sX8UyAw.png"
alt="Objavíte v AppGallery"
height="80">](https://appgallery.cloud.huawei.com/ag/n/app/C101440411?channelId=Badge&id=1b3f7fbb700849a9be0dba6b520b2282&s=EB1D3BF9ED9D1564D869B7B94B18016D3CABFCA5AEFB8E29F675FA04E0DC131D&detailType=0&v=)
Môžete si tiež stiahnuť [vývojovú verziu](https://wulkanowy.github.io/#download), ktorá zahrňuje nové funkcie pripravované pre budúce vydanie
## Postavené s pomocou
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [Kotlin Coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html)
* [Hilt](https://dagger.dev/hilt/)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Spolupráca
Prispejte do projektu vytvorením PR alebo odoslaním issue na GitHub.
Pre záujemcov o preklad aplikácie do rôznych jazykov poskytujeme Crowdin:
https://crowdin.com/project/wulkanowy2
## Licencia
Tento projekt je licencovaný pod licenciou Apache License 2.0 - podrobnosti v súbore [LICENSE](LICENSE)

Binary file not shown.

View file

@ -1,52 +1,47 @@
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
import ru.cian.huawei.publish.ReleaseNote
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization' apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize'
apply plugin: 'com.google.devtools.ksp'
apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.gms.google-services'
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: 'ru.cian.huawei-publish'
apply plugin: 'com.mikepenz.aboutlibraries.plugin' apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'com.huawei.agconnect'
apply plugin: 'kotlin-kapt'
apply from: 'jacoco.gradle' apply from: 'jacoco.gradle'
apply from: 'sonarqube.gradle' apply from: 'sonarqube.gradle'
apply from: 'hooks.gradle' apply from: 'hooks.gradle'
android { android {
namespace 'io.github.wulkanowy' compileSdkVersion 30
compileSdk 34 buildToolsVersion '30.0.3'
defaultConfig { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21 minSdkVersion 17
targetSdkVersion 34 targetSdkVersion 30
versionCode 160 versionCode 83
versionName "2.6.0" versionName "0.25.1"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
resValue "string", "app_name", "Wulkanowy" resValue "string", "app_name", "Wulkanowy"
manifestPlaceholders = [admob_project_id: ""] buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis())
buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "null" manifestPlaceholders = [
buildConfigField "String", "DASHBOARD_TILE_AD_ID", "null" firebase_enabled: project.hasProperty("enableFirebase")
]
if (System.env.SET_BUILD_TIMESTAMP) { javaCompileOptions {
buildConfigField "long", "BUILD_TIMESTAMP", String.valueOf(System.currentTimeMillis()) annotationProcessorOptions {
} else { arguments += [
buildConfigField "long", "BUILD_TIMESTAMP", "1486235849000" "room.schemaLocation": "$projectDir/schemas".toString(),
"room.incremental" : "true"
]
}
} }
} }
sourceSets { sourceSets {
// https://github.com/robolectric/robolectric/issues/3928#issuecomment-395309991 androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
debug.assets.srcDirs += files("$projectDir/schemas".toString())
} }
signingConfigs { signingConfigs {
@ -64,84 +59,64 @@ android {
shrinkResources true shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release signingConfig signingConfigs.release
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"'
} }
debug { debug {
minifyEnabled false resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode
shrinkResources false
resValue "string", "app_name", "Wulkanowy DEV"
applicationIdSuffix ".dev" applicationIdSuffix ".dev"
versionNameSuffix "-dev" versionNameSuffix "-dev"
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\"" testCoverageEnabled = project.hasProperty('coverage')
buildConfigField "String", "SCHOOLS_BASE_URL", '"https://schools.wulkanowy.net.pl"' ext.enableCrashlytics = project.hasProperty("enableFirebase")
} }
} }
flavorDimensions += "platform" flavorDimensions "platform"
productFlavors { productFlavors {
hms { hms {
dimension "platform" dimension "platform"
manifestPlaceholders = [install_channel: "AppGallery"] minSdkVersion 19
manifestPlaceholders = [
install_channel: "AppGallery"
]
} }
play { play {
dimension "platform" dimension "platform"
manifestPlaceholders = [ manifestPlaceholders = [
install_channel : "Google Play", install_channel: "Google Play"
admob_project_id: System.getenv("ADMOB_PROJECT_ID") ?: "ca-app-pub-3940256099942544~3347511713"
] ]
buildConfigField "String", "SINGLE_SUPPORT_AD_ID", "\"${System.getenv("SINGLE_SUPPORT_AD_ID") ?: "ca-app-pub-3940256099942544/5354046379"}\""
buildConfigField "String", "DASHBOARD_TILE_AD_ID", "\"${System.getenv("DASHBOARD_TILE_AD_ID") ?: "ca-app-pub-3940256099942544/6300978111"}\""
} }
fdroid { fdroid {
dimension "platform" dimension "platform"
manifestPlaceholders = [install_channel: "F-Droid"] manifestPlaceholders = [
install_channel: "F-Droid"
]
} }
} }
playConfigs {
play { enabled.set(true) }
}
buildFeatures { buildFeatures {
viewBinding true viewBinding = true
buildConfig true
} }
bundle { lintOptions {
language { disable 'HardwareIds'
enableSplit = false
}
}
testOptions {
unitTests.includeAndroidResources = true
// workaround HMS test errors https://github.com/robolectric/robolectric/issues/2750
unitTests.all { jvmArgs '-noverify' }
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_1_8
} }
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "1.8"
freeCompilerArgs += ["-opt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"] freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn", "-Xjvm-default=all"]
} }
packagingOptions { packagingOptions {
resources { exclude 'META-INF/library_release.kotlin_module'
excludes += ['META-INF/library_release.kotlin_module', exclude 'META-INF/library-core_release.kotlin_module'
'META-INF/library-core_release.kotlin_module',
'META-INF/LICENSE.md',
'META-INF/LICENSE-notice.md']
}
} }
aboutLibraries { aboutLibraries {
@ -149,142 +124,108 @@ android {
} }
} }
kapt {
correctErrorTypes true
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas".toString())
}
play { play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = false defaultToAppBundles = false
track = 'production' track = 'alpha'
releaseStatus = ReleaseStatus.IN_PROGRESS updatePriority = 3
userFraction = 0.25d
updatePriority = 1
enabled.set(false)
}
huaweiPublish {
instances {
hmsRelease {
credentialsPath = "$rootDir/app/src/release/agconnect-credentials.json"
buildFormat = "aab"
deployType = "publish"
releaseNotes = [
new ReleaseNote(
"pl-PL",
"$projectDir/src/main/play/release-notes/pl-PL/default.txt"
)
]
}
}
} }
ext { ext {
work_manager = "2.9.0" work_manager = "2.5.0"
android_hilt = "1.2.0" work_hilt = "1.0.0-alpha03"
room = "2.6.1" room = "2.3.0-beta01"
chucker = "4.0.0" chucker = "3.4.0"
mockk = "1.13.10" mockk = "1.10.5"
coroutines = "1.8.0" moshi = "1.11.0"
} }
dependencies { dependencies {
implementation 'io.github.wulkanowy:sdk:2.6.0' implementation "io.github.wulkanowy:sdk:0.25.1"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'
implementation 'androidx.core:core-ktx:1.13.0' implementation "androidx.core:core-ktx:1.3.2"
implementation 'androidx.core:core-splashscreen:1.0.1' implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.activity:activity-ktx:1.9.0" implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.appcompat:appcompat:1.6.1" implementation "androidx.appcompat:appcompat-resources:1.2.0"
implementation "androidx.fragment:fragment-ktx:1.6.2" implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "androidx.annotation:annotation:1.7.1" implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.preference:preference-ktx:1.2.1" implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.recyclerview:recyclerview:1.3.2" implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager2:viewpager2:1.1.0-beta02" implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4" implementation "androidx.constraintlayout:constraintlayout:2.0.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0" implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.10.0" implementation "com.google.android.material:material:1.3.0-rc01"
implementation "com.github.wulkanowy:material-chips-input:2.3.1" implementation "com.github.wulkanowy:material-chips-input:2.1.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation 'com.github.lopspower:CircularImageView:4.3.0'
implementation "androidx.work:work-runtime:$work_manager" implementation "androidx.work:work-runtime-ktx:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager" playImplementation "androidx.work:work-gcm:$work_manager"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.7.0" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.room:room-runtime:$room" implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room" implementation "androidx.room:room-ktx:$room"
ksp "androidx.room:room-compiler:$room" kapt "androidx.room:room-compiler:$room"
implementation "com.google.dagger:hilt-android:$hilt_version" implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version" kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
kapt "androidx.hilt:hilt-compiler:$android_hilt" implementation "androidx.hilt:hilt-work:$work_hilt"
implementation "androidx.hilt:hilt-work:$android_hilt" kapt "androidx.hilt:hilt-compiler:$work_hilt"
implementation 'com.github.ncapdevi:FragNav:3.3.0' implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.3.0" implementation "com.github.YarikSOffice:lingver:1.3.0"
implementation 'com.squareup.retrofit2:retrofit:2.11.0' implementation "com.squareup.moshi:moshi:$moshi"
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0" implementation "com.squareup.moshi:moshi-adapters:$moshi"
implementation "com.squareup.okhttp3:logging-interceptor:4.12.0" kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi"
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.12.0" implementation "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "com.jakewharton.timber:timber:5.0.1" implementation "fr.bipi.treessence:treessence:0.3.2"
implementation 'com.github.Faierbel:slf4j-timber:2.0'
implementation 'com.github.bastienpaulfr:Treessence:1.1.2'
implementation "com.mikepenz:aboutlibraries-core:$about_libraries" implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'io.coil-kt:coil:2.6.0' implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.github.wulkanowy:AppKillerManager:3.0.1" implementation "io.coil-kt:coil:1.1.1"
implementation 'me.xdrop:fuzzywuzzy:1.4.0' implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'com.fredporciuncula:flow-preferences:1.9.1' implementation 'me.xdrop:fuzzywuzzy:1.3.1'
implementation 'org.apache.commons:commons-text:1.12.0'
playImplementation platform('com.google.firebase:firebase-bom:32.8.1') playImplementation platform('com.google.firebase:firebase-bom:26.4.0')
playImplementation 'com.google.firebase:firebase-analytics' playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging' playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx"
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:' playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.firebase:firebase-config' playImplementation 'com.google.android.play:core-ktx:1.8.1'
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
playImplementation 'com.google.android.gms:play-services-ads:23.0.0' hmsImplementation 'com.huawei.hms:hianalytics:5.1.0.301'
playImplementation "com.google.android.play:integrity:1.3.0" hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.5.0.200'
playImplementation 'com.google.android.play:app-update-ktx:2.1.0'
playImplementation 'com.google.android.play:review-ktx:2.0.1'
playImplementation "com.google.android.ump:user-messaging-platform:2.1.0"
hmsImplementation 'com.huawei.hms:hianalytics:6.12.0.301' releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.9.1.303'
releaseImplementation "com.github.chuckerteam.chucker:library-no-op:$chucker" debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
debugImplementation "com.github.chuckerteam.chucker:library:$chucker" testImplementation "junit:junit:4.13.1"
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
testImplementation "junit:junit:4.13.2"
testImplementation "io.mockk:mockk:$mockk" testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines" testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testImplementation 'org.robolectric:robolectric:4.12.1' androidTestImplementation "androidx.test:core:1.3.0"
testImplementation "androidx.test:runner:1.5.2" androidTestImplementation "androidx.test:runner:1.3.0"
testImplementation "androidx.test.ext:junit:1.1.5" androidTestImplementation "androidx.test.ext:junit:1.1.2"
testImplementation "androidx.test:core:1.5.0"
testImplementation "androidx.room:room-testing:$room"
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
androidTestImplementation "androidx.test:core:1.5.0"
androidTestImplementation "androidx.test:runner:1.5.2"
androidTestImplementation "androidx.test.ext:junit:1.1.5"
androidTestImplementation "io.mockk:mockk-android:$mockk" androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
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'

View file

@ -1,23 +1,23 @@
apply plugin: "jacoco" apply plugin: "jacoco"
jacoco { jacoco {
toolVersion "0.8.11" toolVersion "0.8.5"
reportsDirectory.set(file("$buildDir/reports")) reportsDir = file("$buildDir/reports")
} }
tasks.withType(Test).configureEach { tasks.withType(Test) {
jacoco.includeNoLocationClasses = true jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*'] jacoco.excludes = ['jdk.internal.*']
} }
tasks.register('jacocoTestReport', JacocoReport) { task jacocoTestReport(type: JacocoReport) {
group = "Reporting" group = "Reporting"
description = "Generate Jacoco coverage reports" description = "Generate Jacoco coverage reports"
reports { reports {
xml.required.set(true) xml.enabled = true
html.required.set(true) html.enabled = true
} }
def excludes = ['**/R.class', def excludes = ['**/R.class',
@ -33,19 +33,19 @@ tasks.register('jacocoTestReport', JacocoReport) {
'**/*_Factory.*'] '**/*_Factory.*']
classDirectories.setFrom(fileTree( classDirectories.setFrom(fileTree(
dir: "$buildDir/intermediates/classes/debug", dir: "$buildDir/intermediates/classes/debug",
excludes: excludes excludes: excludes
) + fileTree( ) + fileTree(
dir: "$buildDir/tmp/kotlin-classes/fdroidDebug", dir: "$buildDir/tmp/kotlin-classes/fdroidDebug",
excludes: excludes excludes: excludes
)) ))
sourceDirectories.setFrom(files([ sourceDirectories.setFrom(files([
"src/main/java", "src/main/java",
"src/fdroid/java" "src/fdroid/java"
])) ]))
executionData.setFrom(fileTree( executionData.setFrom(fileTree(
dir: project.projectDir, dir: project.projectDir,
includes: ["**/*.exec", "**/*.ec"] includes: ["**/*.exec", "**/*.ec"]
)) ))
} }

BIN
app/key.p12.gpg Normal file

Binary file not shown.

View file

@ -1,8 +1,7 @@
#!/bin/bash - #!/bin/bash -
content=$(cat < "app/src/main/play/release-notes/pl-PL/default.txt") || exit content=$(cat < "app/src/main/play/release-notes/pl-PL/default.txt") || exit
content2=echo "$content" | dos2unix if [[ "${#content}" -gt 500 ]]; then
if [[ "${#content2}" -gt 500 ]]; then
echo >&2 "Release notes content has reached the limit of 500 characters" echo >&2 "Release notes content has reached the limit of 500 characters"
exit 1 exit 1
fi fi

View file

@ -1,22 +1,33 @@
# General # Optimizations
-optimizationpasses 5
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-dontobfuscate -dontobfuscate
-ignorewarnings -allowaccessmodification
-repackageclasses ''
-verbose
#Config for wulkanowy #Keep all wulkanowy files
-keep class io.github.wulkanowy.** {*;} -keep class io.github.wulkanowy.** {*;}
#Config for firebase crashlitycs #Config for anallitycs
-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 Okio and OkHttp #Config for 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
@ -27,16 +38,8 @@
-keep class com.google.android.material.tabs.** { *; } -keep class com.google.android.material.tabs.** { *; }
#Config for HMS SDK #Config for About Libraries
-keepattributes *Annotation* -keep class .R
-keepattributes Exceptions -keep class **.R$* {
-keepattributes InnerClasses <fields>;
-keepattributes Signature }
-keep class com.huawei.agconnect.**{*;}
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
#Config for Wulkanowy SDK
-keep,allowobfuscation,allowshrinking class retrofit2.Response

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,37 @@
package io.github.wulkanowy.data.db.migrations
import android.content.Context
import androidx.preference.PreferenceManager
import androidx.room.Room
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import org.junit.Rule
abstract class AbstractMigrationTest {
val dbName = "migration-test"
@get:Rule
val helper: MigrationTestHelper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
AppDatabase::class.java.canonicalName,
FrameworkSQLiteOpenHelperFactory()
)
fun getMigratedRoomDatabase(): AppDatabase {
val context = ApplicationProvider.getApplicationContext<Context>()
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase::class.java, dbName)
.addMigrations(*AppDatabase.getMigrations(SharedPrefProvider(PreferenceManager
.getDefaultSharedPreferences(context)))
)
.build()
// close the database and release any stream resources when the test finishes
helper.closeWhenFinished(database)
return database
}
}

View file

@ -2,38 +2,32 @@ package io.github.wulkanowy.data.db.migrations
import android.content.ContentValues import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL
import android.os.Build
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import dagger.hilt.android.testing.HiltAndroidTest import androidx.test.ext.junit.runners.AndroidJUnit4
import dagger.hilt.android.testing.HiltTestApplication
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import kotlin.test.assertEquals import kotlin.test.assertEquals
@HiltAndroidTest @RunWith(AndroidJUnit4::class)
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class)
class Migration12Test : AbstractMigrationTest() { class Migration12Test : AbstractMigrationTest() {
@Test @Test
fun twoNotRelatedStudents() { fun twoNotRelatedStudents() {
helper.createDatabase(dbName, 11).apply { helper.createDatabase(dbName, 11).apply {
// user 1 // user 1
createStudent(this, 1) createStudent(this, 1, true)
createSemester(this, 1, false, 5, 1) createSemester(this, 1, false, 5, 1)
createSemester(this, 1, true, 5, 2) createSemester(this, 1, true, 5, 2)
// user 2 // user 2
createStudent(this, 2) createStudent(this, 2, true)
createSemester(this, 2, false, 6, 1) createSemester(this, 2, false, 6, 1)
createSemester(this, 2, true, 6, 2) createSemester(this, 2, true, 6, 2)
close() close()
} }
runMigrationsAndValidate(Migration12()) helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -49,21 +43,20 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(2, studentId) assertEquals(2, studentId)
assertEquals(6, classId) assertEquals(6, classId)
} }
db.close()
} }
@Test @Test
fun removeStudentsWithoutClassId() { fun removeStudentsWithoutClassId() {
helper.createDatabase(dbName, 11).apply { helper.createDatabase(dbName, 11).apply {
// user 1 // user 1
createStudent(this, 1) createStudent(this, 1, true)
createSemester(this, 1, false, 0, 2) createSemester(this, 1, false, 0, 2)
createStudent(this, 2) createStudent(this, 2, true)
createSemester(this, 2, true, 1, 2) createSemester(this, 2, true, 1, 2)
close() close()
} }
runMigrationsAndValidate(Migration12()) helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -74,23 +67,22 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(2, studentId) assertEquals(2, studentId)
assertEquals(1, classId) assertEquals(1, classId)
} }
db.close()
} }
@Test @Test
fun ensureThereIsOnlyOneCurrentStudent() { fun ensureThereIsOnlyOneCurrentStudent() {
helper.createDatabase(dbName, 11).apply { helper.createDatabase(dbName, 11).apply {
// user 1 // user 1
createStudent(this, 1) createStudent(this, 1, true)
createSemester(this, 1, true, 5, 2) createSemester(this, 1, true, 5, 2)
createStudent(this, 2) createStudent(this, 2, true)
createSemester(this, 2, true, 6, 2) createSemester(this, 2, true, 6, 2)
createStudent(this, 3) createStudent(this, 3, true)
createSemester(this, 3, false, 7, 2) createSemester(this, 3, false, 7, 2)
close() close()
} }
runMigrationsAndValidate(Migration12()) helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -109,10 +101,9 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(studentId, 3) assertEquals(studentId, 3)
assertEquals(true, isCurrent) assertEquals(true, isCurrent)
} }
db.close()
} }
private fun createStudent(db: SupportSQLiteDatabase, studentId: Int) { private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, isCurrent: Boolean) {
db.insert("Students", CONFLICT_FAIL, ContentValues().apply { db.insert("Students", CONFLICT_FAIL, ContentValues().apply {
put("endpoint", "https://fakelog.cf") put("endpoint", "https://fakelog.cf")
put("loginType", "STANDARD") put("loginType", "STANDARD")
@ -123,7 +114,7 @@ class Migration12Test : AbstractMigrationTest() {
put("student_name", "Jan Kowalski") put("student_name", "Jan Kowalski")
put("school_id", "000123") put("school_id", "000123")
put("school_name", "") put("school_name", "")
put("is_current", true) put("is_current", isCurrent)
put("registration_date", "0") put("registration_date", "0")
}) })
} }

View file

@ -2,26 +2,17 @@ package io.github.wulkanowy.data.db.migrations
import android.content.ContentValues import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
import android.os.Build
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.HiltTestApplication
import io.github.wulkanowy.data.db.Converters import io.github.wulkanowy.data.db.Converters
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.time.LocalDate.of import java.time.LocalDate.of
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
@HiltAndroidTest
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class)
class Migration13Test : AbstractMigrationTest() { class Migration13Test : AbstractMigrationTest() {
@Test @Test
@ -57,8 +48,6 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals("C", className) assertEquals("C", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName) assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName)
} }
db.close()
} }
@Test @Test
@ -87,30 +76,28 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals("", className) assertEquals("", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName) assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName)
} }
db.close()
} }
@Test @Test
fun markAtLeastAndOnlyOneSemesterAtCurrent() { fun markAtLeastAndOnlyOneSemesterAtCurrent() {
helper.createDatabase(dbName, 12).apply { helper.createDatabase(dbName, 12).apply {
createStudent(this, 1, "", 5) createStudent(this, 1, "", 5)
createSemester(this, 1, 1, 1, false) createSemester(this, 1, 5, 1, 1, false)
createSemester(this, 1, 2, 1, false) createSemester(this, 1, 5, 2, 1, false)
createSemester(this, 1, 3, 2, false) createSemester(this, 1, 5, 3, 2, false)
createSemester(this, 1, 4, 2, false) createSemester(this, 1, 5, 4, 2, false)
createStudent(this, 2, "", 5) createStudent(this, 2, "", 5)
createSemester(this, 2, 5, 5, true) createSemester(this, 2, 5, 5, 5, true)
createSemester(this, 2, 6, 5, true) createSemester(this, 2, 5, 6, 5, true)
createSemester(this, 2, 7, 55, true) createSemester(this, 2, 5, 7, 55, true)
createSemester(this, 2, 8, 55, true) createSemester(this, 2, 5, 8, 55, true)
createStudent(this, 3, "", 5) createStudent(this, 3, "", 5)
createSemester(this, 3, 11, 99, false) createSemester(this, 3, 5, 11, 99, false)
createSemester(this, 3, 12, 99, false) createSemester(this, 3, 5, 12, 99, false)
createSemester(this, 3, 13, 100, false) createSemester(this, 3, 5, 13, 100, false)
createSemester(this, 3, 14, 100, true) createSemester(this, 3, 5, 14, 100, true)
close() close()
} }
@ -152,32 +139,28 @@ class Migration13Test : AbstractMigrationTest() {
assertFalse(semesters[2].second) assertFalse(semesters[2].second)
assertTrue(semesters[3].second) assertTrue(semesters[3].second)
} }
db.close()
} }
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Pair<Semester, Boolean>> { private fun getSemesters(db: SupportSQLiteDatabase, query: String): List<Pair<Semester, Boolean>> {
val semesters = mutableListOf<Pair<Semester, Boolean>>() val semesters = mutableListOf<Pair<Semester, Boolean>>()
db.query(query).use { val cursor = db.query(query)
if (it.moveToFirst()) { if (cursor.moveToFirst()) {
do { do {
semesters.add(Semester( semesters.add(Semester(
studentId = it.getInt(1), studentId = cursor.getInt(1),
diaryId = it.getInt(2), diaryId = cursor.getInt(2),
kindergartenDiaryId = 0, diaryName = cursor.getString(3),
diaryName = it.getString(3), semesterId = cursor.getInt(4),
semesterId = it.getInt(4), semesterName = cursor.getInt(5),
semesterName = it.getInt(5), classId = cursor.getInt(7),
classId = it.getInt(7), unitId = cursor.getInt(8),
unitId = it.getInt(8), schoolYear = cursor.getInt(9),
schoolYear = it.getInt(9), start = Converters().timestampToDate(cursor.getLong(10))!!,
start = Converters().timestampToLocalDate(it.getLong(10))!!, end = Converters().timestampToDate(cursor.getLong(11))!!
end = Converters().timestampToLocalDate(it.getLong(11))!! ) to (cursor.getInt(6) == 1))
) to (it.getInt(6) == 1)) } while (cursor.moveToNext())
} while (it.moveToNext())
}
} }
return semesters.toList() return semesters.toList()
} }
@ -198,13 +181,7 @@ class Migration13Test : AbstractMigrationTest() {
}) })
} }
private fun createSemester( private fun createSemester(db: SupportSQLiteDatabase, studentId: Int, classId: Int, semesterId: Int, diaryId: Int, isCurrent: Boolean = false) {
db: SupportSQLiteDatabase,
studentId: Int,
semesterId: Int,
diaryId: Int,
isCurrent: Boolean = false
) {
db.insert("Semesters", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply { db.insert("Semesters", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
put("student_id", studentId) put("student_id", studentId)
put("diary_id", diaryId) put("diary_id", diaryId)
@ -212,7 +189,7 @@ class Migration13Test : AbstractMigrationTest() {
put("semester_id", semesterId) put("semester_id", semesterId)
put("semester_name", "1") put("semester_name", "1")
put("is_current", isCurrent) put("is_current", isCurrent)
put("class_id", 5) put("class_id", classId)
put("unit_id", "99") put("unit_id", "99")
}) })
} }

View file

@ -2,21 +2,12 @@ package io.github.wulkanowy.data.db.migrations
import android.content.ContentValues import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
import android.os.Build
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.HiltTestApplication
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import kotlin.random.Random import kotlin.random.Random
@HiltAndroidTest
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class)
class Migration27Test : AbstractMigrationTest() { class Migration27Test : AbstractMigrationTest() {
@Test @Test
@ -27,7 +18,7 @@ class Migration27Test : AbstractMigrationTest() {
close() close()
} }
runMigrationsAndValidate(Migration27()) helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -39,8 +30,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(123, userLoginId) assertEquals(123, userLoginId)
assertEquals("Student Jan", userName) assertEquals("Student Jan", userName)
} }
db.close()
} }
@Test @Test
@ -51,7 +40,7 @@ class Migration27Test : AbstractMigrationTest() {
close() close()
} }
runMigrationsAndValidate(Migration27()) helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -63,8 +52,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(2, userLoginId) assertEquals(2, userLoginId)
assertEquals("Unit Jan", userName) assertEquals("Unit Jan", userName)
} }
db.close()
} }
@Test @Test
@ -77,7 +64,7 @@ class Migration27Test : AbstractMigrationTest() {
close() close()
} }
runMigrationsAndValidate(Migration27()) helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase() val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() } val students = runBlocking { db.studentDao.loadAll() }
@ -94,8 +81,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(333, userLoginId) assertEquals(333, userLoginId)
assertEquals("Unit Tomasz", userName) assertEquals("Unit Tomasz", userName)
} }
db.close()
} }
private fun createStudent(db: SupportSQLiteDatabase, id: Long, userLoginId: Int, studentName: String) { private fun createStudent(db: SupportSQLiteDatabase, id: Long, userLoginId: Int, studentName: String) {

View file

@ -14,37 +14,34 @@ import kotlin.test.assertFailsWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class ScramblerTest { class ScramblerTest {
private val scrambler = Scrambler(ApplicationProvider.getApplicationContext())
@Test @Test
fun encryptDecryptTest() { fun encryptDecryptTest() {
assertEquals( assertEquals("TEST", decrypt(encrypt("TEST",
"TEST", scrambler.decrypt(scrambler.encrypt("TEST")) ApplicationProvider.getApplicationContext())))
)
} }
@Test @Test
fun emptyTextEncryptTest() { fun emptyTextEncryptTest() {
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.decrypt("") decrypt("")
} }
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.encrypt("") encrypt("", ApplicationProvider.getApplicationContext())
} }
} }
@Test @Test
@SdkSuppress(minSdkVersion = 18) @SdkSuppress(minSdkVersion = 18)
fun emptyKeyStoreTest() { fun emptyKeyStoreTest() {
val text = scrambler.encrypt("test") val text = encrypt("test", ApplicationProvider.getApplicationContext())
val keyStore = KeyStore.getInstance("AndroidKeyStore") val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null) keyStore.load(null)
keyStore.deleteEntry("wulkanowy_password") keyStore.deleteEntry("wulkanowy_password")
assertFailsWith<ScramblerException> { assertFailsWith<ScramblerException> {
scrambler.decrypt(text) decrypt(text)
} }
} }
} }

View file

@ -0,0 +1,33 @@
{
"agcgw":{
"backurl":"connect-dre.dbankcloud.cn",
"url":"connect-dre.hispace.hicloud.com"
},
"client":{
"cp_id":"890048000024105546",
"product_id":"",
"client_id":"",
"client_secret":"",
"app_id":"101440411",
"package_name":"io.github.wulkanowy.dev",
"api_key":""
},
"service":{
"analytics":{
"collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
"resource_id":"p1",
"channel_id":""
},
"search":{
"url":"https://search-dre.cloud.huawei.com"
},
"cloudstorage":{
"storage_url":"https://ops-dre.agcstorage.link"
},
"ml":{
"mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
}
},
"region":"DE",
"configuration_version":"1.0"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/colorIcon" /> <background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" /> <foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
<monochrome android:drawable="@drawable/ic_launcher_foreground_dev_mono" /> </adaptive-icon>
</adaptive-icon>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/colorPrimary" />
<foreground android:drawable="@drawable/ic_launcher_foreground_dev" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1,31 +0,0 @@
package io.github.wulkanowy.utils
import android.content.Context
import android.view.View
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import kotlinx.coroutines.flow.MutableStateFlow
import javax.inject.Inject
@Suppress("unused")
class AdsHelper @Inject constructor(
@ApplicationContext private val context: Context,
private val preferencesRepository: PreferencesRepository
) {
val isMobileAdsSdkInitialized = MutableStateFlow(false)
val canShowAd = false
fun initialize() {
preferencesRepository.isAdsEnabled = false
preferencesRepository.selectedDashboardTiles -= DashboardItem.Tile.ADS
}
@Suppress("RedundantSuspendModifier", "UNUSED_PARAMETER")
suspend fun getDashboardTileAdBanner(width: Int): AdBanner {
throw IllegalStateException("Can't get ad banner (F-droid)")
}
}
data class AdBanner(val view: View)

View file

@ -8,7 +8,15 @@ import javax.inject.Singleton
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
class AnalyticsHelper @Inject constructor() { class AnalyticsHelper @Inject constructor() {
fun logEvent(name: String, vararg params: Pair<String, Any?>) = Unit fun logEvent(name: String, vararg params: Pair<String, Any?>) {
fun setCurrentScreen(activity: Activity, name: String?) = Unit // do nothing
fun popCurrentScreen(name: String?) = Unit }
fun setCurrentScreen(activity: Activity, name: String?) {
// do nothing
}
fun popCurrentScreen(name: String?) {
// do nothing
}
} }

View file

@ -1,18 +0,0 @@
package io.github.wulkanowy.utils
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.ui.modules.main.MainActivity
import javax.inject.Singleton
import javax.inject.Inject
@Suppress("UNUSED_PARAMETER", "unused")
@Singleton
class InAppReviewHelper @Inject constructor(
@ApplicationContext private val context: Context
) {
fun showInAppReview(activity: MainActivity) {
// do nothing
}
}

View file

@ -1,13 +0,0 @@
package io.github.wulkanowy.utils
import android.view.View
import javax.inject.Inject
class InAppUpdateHelper @Inject constructor() {
lateinit var messageContainer: View
fun checkAndInstallUpdates() {}
fun onResume() {}
}

View file

@ -1,11 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class IntegrityHelper @Inject constructor() {
@Suppress("UNUSED_PARAMETER")
fun getIntegrityToken(requestId: String): String? = null
}

View file

@ -1,7 +0,0 @@
package io.github.wulkanowy.utils
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RemoteConfigHelper @Inject constructor() : BaseRemoteConfigHelper()

Some files were not shown because too many files have changed in this diff Show more