Compare commits
93 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2d6d823a87 | ||
![]() |
02a9724587 | ||
![]() |
c17237015e | ||
![]() |
2681794676 | ||
![]() |
42e59ac0db | ||
![]() |
cac98ee3d4 | ||
![]() |
aeecc48639 | ||
![]() |
db444d89f0 | ||
![]() |
29971777a7 | ||
![]() |
88cd18b8c6 | ||
![]() |
30a77f1a99 | ||
![]() |
6de7ee9cee | ||
![]() |
d44b85073a | ||
![]() |
514fbafd00 | ||
![]() |
c35222cdfd | ||
![]() |
37a94595c0 | ||
![]() |
58d9dec33c | ||
![]() |
095403cc76 | ||
![]() |
7f3a607246 | ||
![]() |
ffee78d4f7 | ||
![]() |
f2a20c3aae | ||
![]() |
1e7dbba995 | ||
![]() |
0b8f3fe94b | ||
![]() |
0e8b0673ca | ||
![]() |
8450f6953e | ||
![]() |
ddefda08f1 | ||
![]() |
c5b173b40a | ||
![]() |
f10bc42c7b | ||
![]() |
6371d71b7a | ||
![]() |
09f0c986e0 | ||
![]() |
10043cc62c | ||
![]() |
f795412551 | ||
![]() |
6a7020a516 | ||
![]() |
137ea65e0f | ||
![]() |
50ef7f8617 | ||
![]() |
e1dbc2f050 | ||
![]() |
77e1acbb1e | ||
![]() |
6e19f37d79 | ||
0823e72328 | |||
![]() |
fadf1d7754 | ||
![]() |
1071a0848a | ||
![]() |
cefb0deba8 | ||
![]() |
53c813f014 | ||
![]() |
90a151c129 | ||
![]() |
9fd9721ae7 | ||
![]() |
ceca75ef4b | ||
![]() |
21c00bbe53 | ||
![]() |
db00566ebf | ||
![]() |
07ab1b984f | ||
![]() |
8177d4aa2d | ||
![]() |
beff1b6460 | ||
![]() |
31b569b02e | ||
![]() |
8bf77817d2 | ||
![]() |
87b7bd9b30 | ||
![]() |
27b61adf1d | ||
![]() |
8d7dc511ea | ||
![]() |
a0244841ad | ||
![]() |
12c0c6f2ec | ||
![]() |
aaa3b8626e | ||
![]() |
48c9e2dfe3 | ||
![]() |
81d4801d27 | ||
![]() |
5f8016061d | ||
![]() |
5007587192 | ||
![]() |
dfd1083e41 | ||
![]() |
a322986df5 | ||
![]() |
726c22b70a | ||
![]() |
ef0996c80e | ||
![]() |
14952307b3 | ||
![]() |
86c41d9191 | ||
![]() |
c1ef0e9d11 | ||
![]() |
2e97467c57 | ||
![]() |
46de915965 | ||
![]() |
9a6d56ec77 | ||
![]() |
41217190bb | ||
![]() |
d60e622626 | ||
![]() |
c011f550bb | ||
![]() |
61b7410bd0 | ||
![]() |
d5c10fbd2b | ||
![]() |
fd31cafd8f | ||
![]() |
df7044cc64 | ||
![]() |
0a127ac6ee | ||
![]() |
6b75715e87 | ||
![]() |
b9e0d91220 | ||
![]() |
0d5bb331f3 | ||
![]() |
0e52fb7386 | ||
![]() |
339bb9c8f6 | ||
![]() |
b44fa6b2e4 | ||
![]() |
9cc98fcf08 | ||
![]() |
67b794ce2b | ||
![]() |
31b502bb6c | ||
![]() |
7686c451e6 | ||
![]() |
04f3ce4d64 | ||
![]() |
3a6087e421 |
2
.github/utils/_get_password.py
vendored
@ -23,8 +23,6 @@ def get_password(
|
||||
auth_plugin="mysql_native_password",
|
||||
)
|
||||
|
||||
print(f"Generating passwords for version {version_name} ({version_code})")
|
||||
|
||||
password = base64.b64encode(secrets.token_bytes(16)).decode()
|
||||
iv = secrets.token_bytes(16)
|
||||
|
||||
|
4
.github/utils/_utils.py
vendored
@ -102,7 +102,9 @@ def get_commit_log(project_dir: str, format: str, max_lines: int = None) -> str:
|
||||
)
|
||||
|
||||
log = subprocess.run(
|
||||
args=f"git log {last_tag}..HEAD --format=%an%x00%at%x00%h%x00%s%x00%D".split(" "),
|
||||
args=f"git log {last_tag}..HEAD --format=%an%x00%at%x00%h%x00%s%x00%D".split(
|
||||
" "
|
||||
),
|
||||
cwd=project_dir,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
29
.github/utils/bump_nightly.py
vendored
@ -1,10 +1,7 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import requests
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from _utils import (
|
||||
get_commit_log,
|
||||
@ -18,38 +15,20 @@ if __name__ == "__main__":
|
||||
print("usage: bump_nightly.py <project dir>")
|
||||
exit(-1)
|
||||
|
||||
repo = os.getenv("GITHUB_REPOSITORY")
|
||||
sha = os.getenv("GITHUB_SHA")
|
||||
|
||||
if not repo or not sha:
|
||||
print("Missing GitHub environment variables.")
|
||||
exit(-1)
|
||||
|
||||
with requests.get(
|
||||
f"https://api.github.com/repos/{repo}/actions/runs?per_page=5&status=success"
|
||||
) as r:
|
||||
data = json.loads(r.text)
|
||||
runs = [run for run in data["workflow_runs"] if run["head_sha"] == sha]
|
||||
if runs:
|
||||
print("::set-output name=hasNewChanges::false")
|
||||
exit(0)
|
||||
|
||||
print("::set-output name=hasNewChanges::true")
|
||||
|
||||
project_dir = get_project_dir()
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
version_name = version_name.split("+")[0]
|
||||
|
||||
date = datetime.now()
|
||||
date = datetime.now(tz=ZoneInfo("Europe/Warsaw"))
|
||||
if date.hour > 6:
|
||||
version_name += "+daily." + date.strftime("%Y%m%d-%H%M")
|
||||
else:
|
||||
date -= timedelta(days=1)
|
||||
version_name += "+nightly." + date.strftime("%Y%m%d")
|
||||
|
||||
print("::set-output name=appVersionName::" + version_name)
|
||||
print("::set-output name=appVersionCode::" + str(version_code))
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
write_gradle_version(project_dir, version_code, version_name)
|
||||
|
||||
|
23
.github/utils/check_nightly.py
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
if __name__ == "__main__":
|
||||
repo = os.getenv("GITHUB_REPOSITORY")
|
||||
sha = os.getenv("GITHUB_SHA")
|
||||
|
||||
if not repo or not sha:
|
||||
print("Missing GitHub environment variables.")
|
||||
exit(-1)
|
||||
|
||||
with requests.get(
|
||||
f"https://api.github.com/repos/{repo}/actions/runs?per_page=5&status=success"
|
||||
) as r:
|
||||
data = json.loads(r.text)
|
||||
runs = [run for run in data["workflow_runs"] if run["head_sha"] == sha]
|
||||
if runs:
|
||||
print("hasNewChanges=false")
|
||||
exit(0)
|
||||
|
||||
print("hasNewChanges=true")
|
25
.github/utils/extract_changelogs.py
vendored
@ -12,24 +12,24 @@ if __name__ == "__main__":
|
||||
|
||||
(version_code, version_name) = read_gradle_version(project_dir)
|
||||
|
||||
print("::set-output name=appVersionName::" + version_name)
|
||||
print("::set-output name=appVersionCode::" + str(version_code))
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
dir = f"{project_dir}/app/release/whatsnew-{version_name}/"
|
||||
os.makedirs(dir, exist_ok=True)
|
||||
|
||||
print("::set-output name=changelogDir::" + dir)
|
||||
print("changelogDir=" + dir)
|
||||
|
||||
(title, changelog) = get_changelog(project_dir, format="plain")
|
||||
|
||||
# plain text changelog - Firebase App Distribution
|
||||
with open(dir + "whatsnew-titled.txt", "w", encoding="utf-8") as f:
|
||||
with open(dir + "whatsnew_titled.txt", "w", encoding="utf-8") as f:
|
||||
f.write(title)
|
||||
f.write("\n")
|
||||
f.write(changelog)
|
||||
print("::set-output name=changelogPlainTitledFile::" + dir + "whatsnew-titled.txt")
|
||||
print("changelogPlainTitledFile=" + dir + "whatsnew_titled.txt")
|
||||
|
||||
print("::set-output name=changelogTitle::" + title)
|
||||
print("changelogTitle=" + title)
|
||||
|
||||
# plain text changelog, max 500 chars - Google Play
|
||||
with open(dir + "whatsnew-pl-PL", "w", encoding="utf-8") as f:
|
||||
@ -41,32 +41,31 @@ if __name__ == "__main__":
|
||||
changelog = changelog.strip()
|
||||
f.write(changelog)
|
||||
|
||||
print("::set-output name=changelogPlainFile::" + dir + "whatsnew-pl-PL")
|
||||
print("changelogPlainFile=" + dir + "whatsnew-pl-PL")
|
||||
|
||||
# markdown changelog - Discord webhook
|
||||
(_, changelog) = get_changelog(project_dir, format="markdown")
|
||||
with open(dir + "whatsnew.md", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("::set-output name=changelogMarkdownFile::" + dir + "whatsnew.md")
|
||||
print("changelogMarkdownFile=" + dir + "whatsnew.md")
|
||||
|
||||
# html changelog - version info in DB
|
||||
(_, changelog) = get_changelog(project_dir, format="html")
|
||||
with open(dir + "whatsnew.html", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("::set-output name=changelogHtmlFile::" + dir + "whatsnew.html")
|
||||
|
||||
print("changelogHtmlFile=" + dir + "whatsnew.html")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="plain", max_lines=10)
|
||||
with open(dir + "commit_log.txt", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("::set-output name=commitLogPlainFile::" + dir + "commit_log.txt")
|
||||
print("commitLogPlainFile=" + dir + "commit_log.txt")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="markdown", max_lines=10)
|
||||
with open(dir + "commit_log.md", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("::set-output name=commitLogMarkdownFile::" + dir + "commit_log.md")
|
||||
print("commitLogMarkdownFile=" + dir + "commit_log.md")
|
||||
|
||||
changelog = get_commit_log(project_dir, format="html", max_lines=10)
|
||||
with open(dir + "commit_log.html", "w", encoding="utf-8") as f:
|
||||
f.write(changelog)
|
||||
print("::set-output name=commitLogHtmlFile::" + dir + "commit_log.html")
|
||||
print("commitLogHtmlFile=" + dir + "commit_log.html")
|
||||
|
@ -13,7 +13,7 @@ if __name__ == "__main__":
|
||||
|
||||
files = glob.glob(f"{project_dir}/app/release/*.*")
|
||||
for file in files:
|
||||
file_relative = file.replace(os.getenv("GITHUB_WORKSPACE") + "/", "")
|
||||
file_relative = file.replace(project_dir + "/", "")
|
||||
if "-aligned.apk" in file:
|
||||
os.unlink(file)
|
||||
elif "-signed.apk" in file:
|
||||
@ -22,5 +22,5 @@ if __name__ == "__main__":
|
||||
os.unlink(new_file)
|
||||
os.rename(file, new_file)
|
||||
elif ".apk" in file or ".aab" in file:
|
||||
print("::set-output name=signedReleaseFile::" + file)
|
||||
print("::set-output name=signedReleaseFileRelative::" + file_relative)
|
||||
print("signedReleaseFile=" + file)
|
||||
print("signedReleaseFileRelative=" + file_relative)
|
25
.github/utils/save_version.py
vendored
@ -3,6 +3,7 @@ import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import mysql.connector as mysql
|
||||
from dotenv import load_dotenv
|
||||
@ -59,12 +60,22 @@ def save_version(
|
||||
build_date = int(os.stat(file).st_mtime)
|
||||
bundle_name_play = output_aab_play
|
||||
|
||||
build_date = datetime.fromtimestamp(build_date).strftime("%Y-%m-%d %H:%M:%S")
|
||||
build_date = datetime.fromtimestamp(
|
||||
build_date,
|
||||
tz=ZoneInfo("Europe/Warsaw"),
|
||||
).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
if build_type in ["nightly", "daily"]:
|
||||
download_url = apk_server_nightly + apk_name if apk_name else None
|
||||
else:
|
||||
download_url = apk_server_release + apk_name if apk_name else None
|
||||
# download_url = apk_server_release + apk_name if apk_name else None
|
||||
download_url = (
|
||||
f"https://github.com/szkolny-eu/szkolny-android/releases/download/v{version_name}/{apk_name}"
|
||||
if apk_name
|
||||
else None
|
||||
)
|
||||
if download_url:
|
||||
print("downloadUrl=" + download_url)
|
||||
|
||||
cols = [
|
||||
"versionCode",
|
||||
@ -119,4 +130,12 @@ if __name__ == "__main__":
|
||||
APK_SERVER_RELEASE = os.getenv("APK_SERVER_RELEASE")
|
||||
APK_SERVER_NIGHTLY = os.getenv("APK_SERVER_NIGHTLY")
|
||||
|
||||
save_version(project_dir, DB_HOST, DB_USER, DB_PASS, DB_NAME, APK_SERVER_RELEASE, APK_SERVER_NIGHTLY)
|
||||
save_version(
|
||||
project_dir,
|
||||
DB_HOST,
|
||||
DB_USER,
|
||||
DB_PASS,
|
||||
DB_NAME,
|
||||
APK_SERVER_RELEASE,
|
||||
APK_SERVER_NIGHTLY,
|
||||
)
|
||||
|
6
.github/utils/sign.py
vendored
@ -31,8 +31,6 @@ def sign(
|
||||
SIGNING_FORMAT = "$param1.{}.$param2"
|
||||
CPP_FORMAT = "/*{}*/\nstatic toys AES_IV[16] = {{\n\t{} }};"
|
||||
|
||||
print(f"Writing passwords for version {version_name} ({version_code})")
|
||||
|
||||
iv_hex = " ".join(["{:02x}".format(x) for x in iv])
|
||||
iv_cpp = ", ".join(["0x{:02x}".format(x) for x in iv])
|
||||
|
||||
@ -71,8 +69,8 @@ if __name__ == "__main__":
|
||||
version_name, version_code, DB_HOST, DB_USER, DB_PASS, DB_NAME
|
||||
)
|
||||
|
||||
print("::set-output name=appVersionName::" + version_name)
|
||||
print("::set-output name=appVersionCode::" + str(version_code))
|
||||
print("appVersionName=" + version_name)
|
||||
print("appVersionCode=" + str(version_code))
|
||||
|
||||
sign(
|
||||
project_dir,
|
||||
|
39
.github/utils/webhook_discord.py
vendored
@ -1,6 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
@ -11,8 +12,7 @@ from _utils import get_changelog, get_commit_log, get_project_dir, read_gradle_v
|
||||
def post_webhook(
|
||||
project_dir: str,
|
||||
apk_file: str,
|
||||
apk_server_release: str,
|
||||
apk_server_nightly: str,
|
||||
download_url: str,
|
||||
webhook_release: str,
|
||||
webhook_testing: str,
|
||||
):
|
||||
@ -25,16 +25,13 @@ def post_webhook(
|
||||
testing = ["dev", "beta", "nightly", "daily"]
|
||||
testing = build_type in testing
|
||||
|
||||
apk_name = os.path.basename(apk_file)
|
||||
if build_type in ["nightly", "daily"]:
|
||||
download_url = apk_server_nightly + apk_name
|
||||
else:
|
||||
download_url = apk_server_release + apk_name
|
||||
|
||||
if testing:
|
||||
build_date = int(os.stat(apk_file).st_mtime)
|
||||
if build_date:
|
||||
build_date = datetime.fromtimestamp(build_date).strftime("%Y-%m-%d %H:%M")
|
||||
build_date = datetime.fromtimestamp(
|
||||
build_date,
|
||||
tz=ZoneInfo("Europe/Warsaw"),
|
||||
).strftime("%Y-%m-%d %H:%M")
|
||||
|
||||
# untagged release, get commit log
|
||||
if build_type in ["nightly", "daily"]:
|
||||
@ -48,13 +45,17 @@ def post_webhook(
|
||||
requests.post(url=webhook_testing, json=webhook)
|
||||
else:
|
||||
changelog = get_changelog(project_dir, format="markdown")
|
||||
webhook = get_webhook_release(changelog, download_url)
|
||||
webhook = get_webhook_release(version_name, changelog, download_url)
|
||||
requests.post(url=webhook_release, json=webhook)
|
||||
|
||||
|
||||
def get_webhook_release(changelog: str, download_url: str):
|
||||
def get_webhook_release(version_name: str, changelog: str, download_url: str):
|
||||
(title, content) = changelog
|
||||
return {"content": f"__**{title}**__\n{content}\n{download_url}"}
|
||||
return {
|
||||
"content": (
|
||||
f"__**{title}**__\n{content}\n[Szkolny.eu {version_name}]({download_url})"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def get_webhook_testing(
|
||||
@ -73,9 +74,11 @@ def get_webhook_testing(
|
||||
"fields": [
|
||||
{
|
||||
"name": f"Wersja `{version_name}`",
|
||||
"value": f"[Pobierz .APK]({download_url})"
|
||||
if download_url
|
||||
else "*Pobieranie niedostępne*",
|
||||
"value": (
|
||||
f"[Pobierz .APK]({download_url})"
|
||||
if download_url
|
||||
else "*Pobieranie niedostępne*"
|
||||
),
|
||||
"inline": False,
|
||||
},
|
||||
{
|
||||
@ -103,16 +106,14 @@ if __name__ == "__main__":
|
||||
|
||||
load_dotenv()
|
||||
APK_FILE = os.getenv("APK_FILE")
|
||||
APK_SERVER_RELEASE = os.getenv("APK_SERVER_RELEASE")
|
||||
APK_SERVER_NIGHTLY = os.getenv("APK_SERVER_NIGHTLY")
|
||||
DOWNLOAD_URL = os.getenv("DOWNLOAD_URL")
|
||||
WEBHOOK_RELEASE = os.getenv("WEBHOOK_RELEASE")
|
||||
WEBHOOK_TESTING = os.getenv("WEBHOOK_TESTING")
|
||||
|
||||
post_webhook(
|
||||
project_dir,
|
||||
APK_FILE,
|
||||
APK_SERVER_RELEASE,
|
||||
APK_SERVER_NIGHTLY,
|
||||
DOWNLOAD_URL,
|
||||
WEBHOOK_RELEASE,
|
||||
WEBHOOK_TESTING,
|
||||
)
|
||||
|
195
.github/workflows/_build.yml
vendored
Normal file
@ -0,0 +1,195 @@
|
||||
name: "[reusable] Szkolny.eu Build"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
nightly:
|
||||
type: boolean
|
||||
default: false
|
||||
build-apk:
|
||||
type: boolean
|
||||
default: false
|
||||
build-aab:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
release-ssh:
|
||||
type: boolean
|
||||
default: false
|
||||
release-github:
|
||||
type: boolean
|
||||
default: false
|
||||
release-firebase:
|
||||
type: boolean
|
||||
default: false
|
||||
release-google-play:
|
||||
type: boolean
|
||||
default: false
|
||||
release-discord:
|
||||
type: boolean
|
||||
default: false
|
||||
secrets:
|
||||
APK_SERVER_NIGHTLY:
|
||||
APK_SERVER_RELEASE:
|
||||
DB_HOST:
|
||||
DB_NAME:
|
||||
DB_PASS:
|
||||
DB_USER:
|
||||
FIREBASE_APP_ID:
|
||||
FIREBASE_GROUPS_NIGHTLY:
|
||||
FIREBASE_GROUPS_RELEASE:
|
||||
FIREBASE_SERVICE_ACCOUNT_JSON:
|
||||
KEY_ALIAS_PASSWORD:
|
||||
KEY_ALIAS:
|
||||
KEY_STORE_PASSWORD:
|
||||
KEY_STORE:
|
||||
PLAY_RELEASE_TRACK:
|
||||
PLAY_SERVICE_ACCOUNT_JSON:
|
||||
SSH_IP:
|
||||
SSH_KEY:
|
||||
SSH_PATH_NIGHTLY:
|
||||
SSH_PATH_RELEASE:
|
||||
SSH_USERNAME:
|
||||
WEBHOOK_RELEASE:
|
||||
WEBHOOK_TESTING:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Setup JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install Python packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
python-dotenv
|
||||
pycryptodome
|
||||
mysql-connector-python
|
||||
requests
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
|
||||
- name: Bump nightly version
|
||||
if: ${{ inputs.nightly }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/bump_nightly.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Write signing passwords and keystore
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
KEY_STORE: ${{ secrets.KEY_STORE }}
|
||||
run: |
|
||||
python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit >> $GITHUB_OUTPUT
|
||||
echo $KEY_STORE | base64 --decode > keystore.jks
|
||||
- name: Clean build artifacts
|
||||
run: |
|
||||
rm -rf app/release/*
|
||||
rm -rf app/build/outputs/apk/*
|
||||
rm -rf app/build/outputs/bundle/*
|
||||
|
||||
- name: Build app with Gradle
|
||||
if: ${{ inputs.build-apk || inputs.build-aab }}
|
||||
run: |
|
||||
chmod +x ./gradlew
|
||||
./gradlew \
|
||||
${{ inputs.build-apk && 'assembleOfficialRelease' || '' }} \
|
||||
${{ inputs.build-aab && 'bundlePlayRelease' || '' }} \
|
||||
-P android.injected.signing.store.file=${{ github.workspace }}/keystore.jks \
|
||||
-P android.injected.signing.store.password=${{ secrets.KEY_STORE_PASSWORD }} \
|
||||
-P android.injected.signing.key.alias=${{ secrets.KEY_ALIAS }} \
|
||||
-P android.injected.signing.key.password=${{ secrets.KEY_ALIAS_PASSWORD }}
|
||||
|
||||
- name: Upload release to server
|
||||
if: ${{ inputs.release-ssh }}
|
||||
uses: easingthemes/ssh-deploy@v2.1.6
|
||||
env:
|
||||
REMOTE_HOST: ${{ secrets.SSH_IP }}
|
||||
REMOTE_USER: ${{ secrets.SSH_USERNAME }}
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
|
||||
SOURCE: app/release/
|
||||
TARGET: ${{ inputs.nightly && secrets.SSH_PATH_NIGHTLY || secrets.SSH_PATH_RELEASE }}
|
||||
|
||||
- name: Find signed artifacts
|
||||
id: artifacts
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/find_artifacts.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Extract release changelogs
|
||||
id: changelog
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
- name: Save version to database
|
||||
id: save
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/save_version.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Release on GitHub
|
||||
if: ${{ inputs.release-github }}
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.changelogTitle }}
|
||||
body_path: ${{ steps.changelog.outputs.changelogMarkdownFile }}
|
||||
files: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Distribute to App Distribution
|
||||
if: ${{ inputs.release-firebase }}
|
||||
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||
with:
|
||||
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}
|
||||
file: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
groups: ${{ inputs.nightly && secrets.FIREBASE_GROUPS_NIGHTLY || secrets.FIREBASE_GROUPS_RELEASE }}
|
||||
releaseNotesFile: ${{ inputs.nightly && steps.changelog.outputs.commitLogPlainFile || steps.changelog.outputs.changelogPlainTitledFile }}
|
||||
|
||||
- name: Publish AAB to Google Play
|
||||
if: ${{ inputs.release-google-play }}
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
|
||||
packageName: pl.szczodrzynski.edziennik
|
||||
releaseFiles: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
releaseName: ${{ steps.changelog.outputs.appVersionName }}
|
||||
track: ${{ secrets.PLAY_RELEASE_TRACK }}
|
||||
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
|
||||
status: completed
|
||||
|
||||
- name: Post Discord webhook
|
||||
if: ${{ inputs.release-discord }}
|
||||
env:
|
||||
APK_FILE: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
DOWNLOAD_URL: ${{ steps.save.outputs.downloadUrl }}
|
||||
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
|
||||
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||
path: |
|
||||
app/release/whatsnew*/
|
||||
app/release/*.apk
|
||||
app/release/*.aab
|
||||
app/release/*.json
|
||||
app/release/*.txt
|
154
.github/workflows/build-nightly-apk.yml
vendored
@ -1,154 +0,0 @@
|
||||
name: Nightly build
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# 23:30 UTC, 0:30 or 1:30 CET/CEST
|
||||
- cron: "30 23 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare build environment
|
||||
runs-on: self-hosted
|
||||
outputs:
|
||||
hasNewChanges: ${{ steps.nightly.outputs.hasNewChanges }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Set executable permissions to gradlew
|
||||
run: chmod +x ./gradlew
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
python-dotenv
|
||||
pycryptodome
|
||||
mysql-connector-python
|
||||
requests
|
||||
- name: Bump nightly version
|
||||
id: nightly
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/bump_nightly.py $GITHUB_WORKSPACE
|
||||
- name: Write signing passwords
|
||||
if: steps.nightly.outputs.hasNewChanges
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
|
||||
build:
|
||||
name: Build APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- prepare
|
||||
if: ${{ needs.prepare.outputs.hasNewChanges == 'true' }}
|
||||
outputs:
|
||||
androidHome: ${{ env.ANDROID_HOME }}
|
||||
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
|
||||
steps:
|
||||
- name: Setup JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
- name: Clean build artifacts
|
||||
run: |
|
||||
rm -rf app/release/*
|
||||
rm -rf app/build/outputs/apk/*
|
||||
rm -rf app/build/outputs/bundle/*
|
||||
- name: Assemble official release with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: assembleOfficialRelease
|
||||
sign:
|
||||
name: Sign APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- build
|
||||
outputs:
|
||||
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
|
||||
steps:
|
||||
- name: Sign build artifacts
|
||||
id: sign_app
|
||||
uses: r0adkll/sign-android-release@v1
|
||||
with:
|
||||
releaseDirectory: app/release
|
||||
signingKeyBase64: ${{ secrets.KEY_STORE }}
|
||||
alias: ${{ secrets.KEY_ALIAS }}
|
||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
|
||||
env:
|
||||
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
|
||||
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
|
||||
BUILD_TOOLS_VERSION: "30.0.2"
|
||||
- name: Rename signed artifacts
|
||||
id: artifacts
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
|
||||
publish:
|
||||
name: Publish APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- sign
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
|
||||
- name: Extract changelogs
|
||||
id: changelog
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Upload APK to SFTP
|
||||
uses: easingthemes/ssh-deploy@v2.1.6
|
||||
env:
|
||||
REMOTE_HOST: ${{ secrets.SSH_IP }}
|
||||
REMOTE_USER: ${{ secrets.SSH_USERNAME }}
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
|
||||
SOURCE: ${{ needs.sign.outputs.signedReleaseFileRelative }}
|
||||
TARGET: ${{ secrets.SSH_PATH_NIGHTLY }}
|
||||
- name: Save version metadata
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/save_version.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Distribute to App Distribution
|
||||
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||
with:
|
||||
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||
token: ${{ secrets.FIREBASE_TOKEN }}
|
||||
groups: ${{ secrets.FIREBASE_GROUPS_NIGHTLY }}
|
||||
file: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
releaseNotesFile: ${{ steps.changelog.outputs.commitLogPlainFile }}
|
||||
|
||||
- name: Post Discord webhook
|
||||
env:
|
||||
APK_FILE: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
|
||||
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: true
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||
path: |
|
||||
app/release/whatsnew*/
|
||||
app/release/*.apk
|
||||
app/release/*.aab
|
||||
app/release/*.json
|
||||
app/release/*.txt
|
131
.github/workflows/build-release-aab-play.yml
vendored
@ -1,131 +0,0 @@
|
||||
name: Release build - Google Play [AAB]
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare build environment
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Set executable permissions to gradlew
|
||||
run: chmod +x ./gradlew
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
python-dotenv
|
||||
pycryptodome
|
||||
mysql-connector-python
|
||||
requests
|
||||
- name: Write signing passwords
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
|
||||
build:
|
||||
name: Build App Bundle
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- prepare
|
||||
outputs:
|
||||
androidHome: ${{ env.ANDROID_HOME }}
|
||||
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
|
||||
steps:
|
||||
- name: Setup JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
- name: Clean build artifacts
|
||||
run: |
|
||||
rm -rf app/release/*
|
||||
rm -rf app/build/outputs/apk/*
|
||||
rm -rf app/build/outputs/bundle/*
|
||||
- name: Bundle play release with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: bundlePlayRelease
|
||||
sign:
|
||||
name: Sign App Bundle
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- build
|
||||
outputs:
|
||||
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
|
||||
steps:
|
||||
- name: Sign build artifacts
|
||||
id: sign_app
|
||||
uses: r0adkll/sign-android-release@v1
|
||||
with:
|
||||
releaseDirectory: app/release
|
||||
signingKeyBase64: ${{ secrets.KEY_STORE }}
|
||||
alias: ${{ secrets.KEY_ALIAS }}
|
||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
|
||||
env:
|
||||
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
|
||||
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
|
||||
BUILD_TOOLS_VERSION: "30.0.2"
|
||||
- name: Rename signed artifacts
|
||||
id: artifacts
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
|
||||
publish:
|
||||
name: Publish App Bundle
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- sign
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
|
||||
- name: Extract changelogs
|
||||
id: changelog
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Save version metadata
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/save_version.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Publish AAB to Google Play
|
||||
uses: r0adkll/upload-google-play@v1
|
||||
if: ${{ endsWith(needs.sign.outputs.signedReleaseFile, '.aab') }}
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
|
||||
packageName: pl.szczodrzynski.edziennik
|
||||
releaseFile: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
releaseName: ${{ steps.changelog.outputs.appVersionName }}
|
||||
track: ${{ secrets.PLAY_RELEASE_TRACK }}
|
||||
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||
path: |
|
||||
app/release/whatsnew*/
|
||||
app/release/*.apk
|
||||
app/release/*.aab
|
||||
app/release/*.json
|
||||
app/release/*.txt
|
154
.github/workflows/build-release-apk.yml
vendored
@ -1,154 +0,0 @@
|
||||
name: Release build - official
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare build environment
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Set executable permissions to gradlew
|
||||
run: chmod +x ./gradlew
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
python-dotenv
|
||||
pycryptodome
|
||||
mysql-connector-python
|
||||
requests
|
||||
- name: Write signing passwords
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/sign.py $GITHUB_WORKSPACE commit
|
||||
build:
|
||||
name: Build APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- prepare
|
||||
outputs:
|
||||
androidHome: ${{ env.ANDROID_HOME }}
|
||||
androidSdkRoot: ${{ env.ANDROID_SDK_ROOT }}
|
||||
steps:
|
||||
- name: Setup JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
- name: Clean build artifacts
|
||||
run: |
|
||||
rm -rf app/release/*
|
||||
rm -rf app/build/outputs/apk/*
|
||||
rm -rf app/build/outputs/bundle/*
|
||||
- name: Assemble official release with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: assembleOfficialRelease
|
||||
sign:
|
||||
name: Sign APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- build
|
||||
outputs:
|
||||
signedReleaseFile: ${{ steps.artifacts.outputs.signedReleaseFile }}
|
||||
signedReleaseFileRelative: ${{ steps.artifacts.outputs.signedReleaseFileRelative }}
|
||||
steps:
|
||||
- name: Sign build artifacts
|
||||
id: sign_app
|
||||
uses: r0adkll/sign-android-release@v1
|
||||
with:
|
||||
releaseDirectory: app/release
|
||||
signingKeyBase64: ${{ secrets.KEY_STORE }}
|
||||
alias: ${{ secrets.KEY_ALIAS }}
|
||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyPassword: ${{ secrets.KEY_ALIAS_PASSWORD }}
|
||||
env:
|
||||
ANDROID_HOME: ${{ needs.build.outputs.androidHome }}
|
||||
ANDROID_SDK_ROOT: ${{ needs.build.outputs.androidSdkRoot }}
|
||||
BUILD_TOOLS_VERSION: "30.0.2"
|
||||
- name: Rename signed artifacts
|
||||
id: artifacts
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/rename_artifacts.py $GITHUB_WORKSPACE
|
||||
publish:
|
||||
name: Publish APK
|
||||
runs-on: self-hosted
|
||||
needs:
|
||||
- sign
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v2
|
||||
|
||||
- name: Extract changelogs
|
||||
id: changelog
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/extract_changelogs.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Upload APK to SFTP
|
||||
uses: easingthemes/ssh-deploy@v2.1.6
|
||||
env:
|
||||
REMOTE_HOST: ${{ secrets.SSH_IP }}
|
||||
REMOTE_USER: ${{ secrets.SSH_USERNAME }}
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
|
||||
SOURCE: ${{ needs.sign.outputs.signedReleaseFileRelative }}
|
||||
TARGET: ${{ secrets.SSH_PATH_RELEASE }}
|
||||
- name: Save version metadata
|
||||
env:
|
||||
DB_HOST: ${{ secrets.DB_HOST }}
|
||||
DB_USER: ${{ secrets.DB_USER }}
|
||||
DB_PASS: ${{ secrets.DB_PASS }}
|
||||
DB_NAME: ${{ secrets.DB_NAME }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/save_version.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Distribute to App Distribution
|
||||
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
||||
with:
|
||||
appId: ${{ secrets.FIREBASE_APP_ID }}
|
||||
token: ${{ secrets.FIREBASE_TOKEN }}
|
||||
groups: ${{ secrets.FIREBASE_GROUPS_RELEASE }}
|
||||
file: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
releaseNotesFile: ${{ steps.changelog.outputs.changelogPlainTitledFile }}
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.changelogTitle }}
|
||||
body_path: ${{ steps.changelog.outputs.changelogMarkdownFile }}
|
||||
files: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Post Discord webhook
|
||||
env:
|
||||
APK_FILE: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||
APK_SERVER_RELEASE: ${{ secrets.APK_SERVER_RELEASE }}
|
||||
APK_SERVER_NIGHTLY: ${{ secrets.APK_SERVER_NIGHTLY }}
|
||||
WEBHOOK_RELEASE: ${{ secrets.WEBHOOK_RELEASE }}
|
||||
WEBHOOK_TESTING: ${{ secrets.WEBHOOK_TESTING }}
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/webhook_discord.py $GITHUB_WORKSPACE
|
||||
|
||||
- name: Upload workflow artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: true
|
||||
with:
|
||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||
path: |
|
||||
app/release/whatsnew*/
|
||||
app/release/*.apk
|
||||
app/release/*.aab
|
||||
app/release/*.json
|
||||
app/release/*.txt
|
13
.github/workflows/push-master.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name: Push (master)
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
jobs:
|
||||
build:
|
||||
name: Build for Google Play (AAB)
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
build-aab: true
|
||||
release-ssh: true
|
||||
release-google-play: true
|
||||
secrets: inherit
|
15
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v*.*.*"]
|
||||
jobs:
|
||||
build:
|
||||
name: Build release (APK)
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
build-apk: true
|
||||
release-ssh: true
|
||||
release-github: true
|
||||
release-firebase: true
|
||||
release-discord: true
|
||||
secrets: inherit
|
42
.github/workflows/schedule-dispatch.yml
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
name: Schedule/dispatch
|
||||
on:
|
||||
schedule:
|
||||
# 23:30 UTC, 0:30 or 1:30 CET/CEST
|
||||
- cron: "30 23 * * *"
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
check:
|
||||
name: Check new changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
hasNewChanges: ${{ steps.nightly.outputs.hasNewChanges }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
clean: false
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install packages
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
requests
|
||||
- name: Check new changes
|
||||
id: nightly
|
||||
run: python $GITHUB_WORKSPACE/.github/utils/check_nightly.py $GITHUB_WORKSPACE >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
name: Build nightly release (APK)
|
||||
needs:
|
||||
- check
|
||||
if: ${{ needs.check.outputs.hasNewChanges == 'true' }}
|
||||
uses: szkolny-eu/szkolny-android/.github/workflows/_build.yml@develop
|
||||
with:
|
||||
nightly: true
|
||||
build-apk: true
|
||||
release-ssh: true
|
||||
release-firebase: true
|
||||
release-discord: true
|
||||
secrets: inherit
|
21
.idea/codeStyles/Project.xml
generated
@ -1,7 +1,23 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="LAYOUT_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="MANIFEST_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="OTHER_SETTINGS">
|
||||
<value>
|
||||
<option name="INSERT_LINE_BREAK_BEFORE_NAMESPACE_DECLARATION" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="ALLOW_TRAILING_COMMA" value="true" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
@ -127,6 +143,9 @@
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="2" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
1
.idea/dictionaries/Kuba.xml
generated
@ -4,6 +4,7 @@
|
||||
<w>autoryzacji</w>
|
||||
<w>ciasteczko</w>
|
||||
<w>csrf</w>
|
||||
<w>daynight</w>
|
||||
<w>edziennik</w>
|
||||
<w>eggfall</w>
|
||||
<w>elearning</w>
|
||||
|
@ -6,13 +6,13 @@
|
||||
[](https://szkolny.eu/)
|
||||
[](https://szkolny.eu/facebook)
|
||||
|
||||

|
||||

|
||||
[](https://github.com/szkolny-eu/szkolny-android/releases/latest)
|
||||

|
||||
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-release-apk.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-release-aab-play.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/build-nightly-apk.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/release.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/push-master.yml)
|
||||
[](https://github.com/szkolny-eu/szkolny-android/actions/workflows/schedule-dispatch.yml)
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -10,8 +10,10 @@ apply from: 'git-info.gradle'
|
||||
android {
|
||||
compileSdkVersion setup.compileSdk
|
||||
|
||||
namespace "pl.szczodrzynski.edziennik"
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'pl.szczodrzynski.edziennik'
|
||||
applicationId "pl.szczodrzynski.edziennik"
|
||||
minSdkVersion setup.minSdk
|
||||
targetSdkVersion setup.targetSdk
|
||||
|
||||
@ -20,8 +22,9 @@ android {
|
||||
|
||||
buildConfigField "java.util.Map<String, String>", "GIT_INFO", gitInfoMap
|
||||
buildConfigField "String", "VERSION_BASE", "\"${release.versionName}\""
|
||||
|
||||
manifestPlaceholders = [
|
||||
buildTimestamp: String.valueOf(System.currentTimeMillis())
|
||||
buildTimestamp: String.valueOf(System.currentTimeMillis())
|
||||
]
|
||||
|
||||
multiDexEnabled = true
|
||||
@ -36,6 +39,8 @@ android {
|
||||
arguments {
|
||||
arg("room.schemaLocation", "$projectDir/schemas")
|
||||
}
|
||||
|
||||
correctErrorTypes = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,10 +48,12 @@ android {
|
||||
debug {
|
||||
getIsDefault().set(true)
|
||||
minifyEnabled = false
|
||||
applicationIdSuffix = ".debug"
|
||||
manifestPlaceholders = [
|
||||
buildTimestamp: 0
|
||||
buildTimestamp: "0"
|
||||
]
|
||||
}
|
||||
|
||||
release {
|
||||
minifyEnabled = true
|
||||
shrinkResources = true
|
||||
@ -54,28 +61,35 @@ android {
|
||||
proguardFiles fileTree('proguard').asList().toArray()
|
||||
}
|
||||
}
|
||||
flavorDimensions "platform"
|
||||
|
||||
flavorDimensions += "platform"
|
||||
|
||||
productFlavors {
|
||||
unofficial {
|
||||
getIsDefault().set(true)
|
||||
versionName "${release.versionName}-${gitInfo.versionSuffix}"
|
||||
}
|
||||
|
||||
official {}
|
||||
play {}
|
||||
}
|
||||
|
||||
variantFilter { variant ->
|
||||
def flavors = variant.flavors*.name
|
||||
setIgnore(variant.buildType.name == "debug" && !flavors.contains("unofficial") || flavors.contains("main"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
unofficial {
|
||||
java.srcDirs = ["src/main/java", "src/play-not/java"]
|
||||
manifest.srcFile("src/play-not/AndroidManifest.xml")
|
||||
}
|
||||
|
||||
official {
|
||||
java.srcDirs = ["src/main/java", "src/play-not/java"]
|
||||
manifest.srcFile("src/play-not/AndroidManifest.xml")
|
||||
}
|
||||
|
||||
play {
|
||||
java.srcDirs = ["src/main/java", "src/play/java"]
|
||||
}
|
||||
@ -84,37 +98,45 @@ android {
|
||||
defaultConfig {
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
freeCompilerArgs += "-Xcontext-receivers"
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += ['META-INF/library-core_release.kotlin_module']
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "src/main/cpp/CMakeLists.txt"
|
||||
version "3.10.2"
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
}
|
||||
|
||||
tasks.whenTaskAdded { task ->
|
||||
if (!task.name.endsWith("Release") && !task.name.endsWith("ReleaseWithR8"))
|
||||
if (!(task.name == "assembleUnofficialRelease" || task.name == "assembleOfficialRelease" || task.name == "signPlayReleaseBundle"))
|
||||
return
|
||||
|
||||
def renameTaskName = "rename${task.name.capitalize()}"
|
||||
|
||||
def flavor = ""
|
||||
@ -124,17 +146,22 @@ tasks.whenTaskAdded { task ->
|
||||
flavor = task.name.substring("assemble".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
if (task.name.startsWith("minify"))
|
||||
flavor = task.name.substring("minify".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
if (task.name.startsWith("sign"))
|
||||
flavor = task.name.substring("sign".length(), task.name.indexOf("Release")).uncapitalize()
|
||||
|
||||
if (flavor != "") {
|
||||
tasks.create(renameTaskName, Copy) {
|
||||
tasks.register(renameTaskName, Copy) {
|
||||
dependsOn(task.name)
|
||||
duplicatesStrategy DuplicatesStrategy.FAIL
|
||||
from file("${projectDir}/${flavor}/release/"),
|
||||
file("${buildDir}/outputs/mapping/${flavor}Release/"),
|
||||
file("${buildDir}/outputs/apk/${flavor}/release/"),
|
||||
file("${buildDir}/outputs/bundle/${flavor}Release/")
|
||||
include "*.aab", "*.apk", "mapping.txt", "output-metadata.json"
|
||||
file("${projectDir}/build/outputs/apk/${flavor}/release/"),
|
||||
file("${projectDir}/build/outputs/mapping/${flavor}Release/"),
|
||||
file("${projectDir}/build/outputs/bundle/${flavor}Release/")
|
||||
include "*-release.aab", "*-release.apk", "mapping.txt", "output-metadata.json"
|
||||
destinationDir file("${projectDir}/release/")
|
||||
rename ".+?\\.(.+)", "Edziennik_${android.defaultConfig.versionName}_${flavor}." + '$1'
|
||||
}
|
||||
|
||||
task.finalizedBy(renameTaskName)
|
||||
}
|
||||
}
|
||||
@ -145,28 +172,29 @@ dependencies {
|
||||
// Language cores
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "androidx.multidex:multidex:2.0.1"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
|
||||
|
||||
// Android Jetpack
|
||||
implementation "androidx.appcompat:appcompat:1.5.1"
|
||||
implementation "androidx.appcompat:appcompat:1.7.0"
|
||||
implementation "androidx.cardview:cardview:1.0.0"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
||||
implementation "androidx.core:core-ktx:1.9.0"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.5.2"
|
||||
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
||||
implementation "androidx.room:room-runtime:2.4.3"
|
||||
implementation "androidx.work:work-runtime-ktx:2.7.1"
|
||||
kapt "androidx.room:room-compiler:2.4.3"
|
||||
implementation "androidx.core:core-ktx:1.13.1"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.2"
|
||||
implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
|
||||
implementation "androidx.recyclerview:recyclerview:1.3.2"
|
||||
implementation "androidx.room:room-runtime:2.6.1"
|
||||
implementation "androidx.room:room-ktx:2.6.1"
|
||||
implementation "androidx.work:work-runtime-ktx:2.9.0"
|
||||
kapt "androidx.room:room-compiler:2.6.1"
|
||||
|
||||
// Google design libs
|
||||
implementation "com.google.android.material:material:1.6.1"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "com.google.android.flexbox:flexbox:3.0.0"
|
||||
|
||||
// Play Services/Firebase
|
||||
implementation "com.google.android.gms:play-services-wearable:17.1.0"
|
||||
implementation "com.google.android.gms:play-services-wearable:18.2.0"
|
||||
implementation("com.google.firebase:firebase-core") { version { strictly "19.0.2" } }
|
||||
implementation "com.google.firebase:firebase-crashlytics:18.2.13"
|
||||
implementation "com.google.firebase:firebase-crashlytics:19.0.1"
|
||||
implementation("com.google.firebase:firebase-messaging") { version { strictly "20.1.3" } }
|
||||
|
||||
// OkHttp, Retrofit, Gson, Jsoup
|
||||
@ -174,12 +202,13 @@ dependencies {
|
||||
implementation "com.squareup.retrofit2:retrofit:2.9.0"
|
||||
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
|
||||
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
|
||||
implementation 'com.google.code.gson:gson:2.8.8'
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation 'org.jsoup:jsoup:1.14.3'
|
||||
implementation "pl.droidsonroids:jspoon:1.3.2"
|
||||
implementation "pl.droidsonroids.retrofit2:converter-jspoon:1.3.2"
|
||||
|
||||
// Szkolny.eu libraries/forks
|
||||
implementation project(":navlib")
|
||||
implementation "eu.szkolny:android-snowfall:1ca9ea2da3"
|
||||
implementation "eu.szkolny:agendacalendarview:1.0.4"
|
||||
implementation "eu.szkolny:cafebar:5bf0c618de"
|
||||
@ -187,20 +216,22 @@ dependencies {
|
||||
implementation "eu.szkolny:material-about-library:1d5ebaf47c"
|
||||
implementation "eu.szkolny:mhttp:af4b62e6e9"
|
||||
implementation "eu.szkolny:nachos:0e5dfcaceb"
|
||||
implementation "eu.szkolny.selective-dao:annotation:27f8f3f194"
|
||||
implementation "eu.szkolny.selective-dao:annotation:6a337f9"
|
||||
officialImplementation "eu.szkolny:ssl-provider:1.0.0"
|
||||
unofficialImplementation "eu.szkolny:ssl-provider:1.0.0"
|
||||
implementation "pl.szczodrzynski:navlib:0.8.0"
|
||||
|
||||
implementation "pl.szczodrzynski:numberslidingpicker:2921225f76"
|
||||
implementation "pl.szczodrzynski:recyclertablayout:700f980584"
|
||||
implementation "pl.szczodrzynski:tachyon:551943a6b5"
|
||||
kapt "eu.szkolny.selective-dao:codegen:27f8f3f194"
|
||||
kapt "eu.szkolny.selective-dao:codegen:6a337f9"
|
||||
|
||||
// Iconics & related
|
||||
implementation "com.mikepenz:iconics-core:5.3.2"
|
||||
implementation "com.mikepenz:iconics-views:5.3.2"
|
||||
implementation "com.mikepenz:materialdrawer:9.0.1"
|
||||
implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar"
|
||||
implementation "eu.szkolny:szkolny-font:77e33acc2a"
|
||||
implementation 'com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar'
|
||||
implementation "eu.szkolny:szkolny-font:95eabe7"
|
||||
|
||||
// Other dependencies
|
||||
implementation "cat.ereza:customactivityoncrash:2.3.0"
|
||||
@ -211,11 +242,11 @@ dependencies {
|
||||
implementation "com.github.ChuckerTeam.Chucker:library:3.5.2" // https://github.com/ChuckerTeam/chucker
|
||||
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2" // https://github.com/antonKozyriatskyi/CircularProgressIndicator
|
||||
implementation "com.github.bassaer:chatmessageview:2.0.1" // https://github.com/bassaer/ChatMessageView
|
||||
implementation "com.github.hypertrack:hyperlog-android:0.0.10" // https://github.com/hypertrack/hyperlog-android
|
||||
implementation "com.github.smuyyh:JsonViewer:V1.0.6" // https://github.com/smuyyh/JsonViewer
|
||||
implementation "com.github.underwindfall.PowerPermission:powerpermission-coroutines:1.4.0" // https://github.com/underwindfall/PowerPermission
|
||||
implementation "com.github.underwindfall.PowerPermission:powerpermission:1.4.0" // https://github.com/underwindfall/PowerPermission
|
||||
implementation "com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31" // https://github.com/wulkanowy/uonet-request-signer
|
||||
implementation 'com.jakewharton.timber:timber:5.0.1'
|
||||
implementation "com.jaredrummler:colorpicker:1.1.0"
|
||||
implementation "io.coil-kt:coil:1.1.1"
|
||||
implementation "me.dm7.barcodescanner:zxing:1.9.8"
|
||||
|
@ -5,7 +5,7 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.eclipse.jgit:org.eclipse.jgit:5.5.+"
|
||||
|
@ -36,6 +36,37 @@
|
||||
"status": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:640759989760:android:4aa71407b25cdc8d",
|
||||
"android_client_info": {
|
||||
"package_name": "pl.szczodrzynski.edziennik.debug"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "640759989760-6f8q00u864lnuh3gh36e8g4cer9lv8pv.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAvq9HMPxulz9ntdAHZ0eZuPf2YQs4nDSU"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
},
|
||||
"ads_service": {
|
||||
"status": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
|
39
app/proguard-rules.pro
vendored
@ -19,10 +19,13 @@
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-keepattributes Signature
|
||||
-keep class android.support.v7.widget.** { *; }
|
||||
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||
-keep class * extends com.google.gson.reflect.TypeToken
|
||||
|
||||
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.db.enums.* { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.enums.* { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage { *; }
|
||||
@ -32,9 +35,9 @@
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||
-keep class pl.szczodrzynski.edziennik.config.AppData { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.config.AppData$** { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.utils.managers.TextStylingManager$HtmlMode { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.config.AppData { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.data.config.AppData$** { *; }
|
||||
-keep class pl.szczodrzynski.edziennik.core.manager.TextStylingManager$HtmlMode { *; }
|
||||
|
||||
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
|
||||
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }
|
||||
@ -42,6 +45,20 @@
|
||||
-keepclassmembernames class androidx.appcompat.view.menu.MenuItemImpl { private *; }
|
||||
|
||||
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
||||
-keepclassmembernames class com.mikepenz.iconics.internal.IconicsViewsAttrsApplier {
|
||||
<fields>;
|
||||
readIconicsTextView(android.content.Context, android.util.AttributeSet, com.mikepenz.iconics.internal.CompoundIconsBundle);
|
||||
getIconicsImageViewDrawable(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclassmembernames class com.mikepenz.iconics.internal.CompoundIconsBundle {
|
||||
setIcons(android.widget.TextView);
|
||||
}
|
||||
|
||||
# for RecyclerTabView
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabLayout { *; }
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabLayout$TabView { *; }
|
||||
-keepclassmembernames class com.google.android.material.tabs.TabIndicatorInterpolator { *; }
|
||||
|
||||
-keep class .R
|
||||
-keep class **.R$* {
|
||||
@ -55,8 +72,19 @@
|
||||
|
||||
-keep class com.google.android.material.tabs.** {*;}
|
||||
|
||||
# Exclude AgendaCalendarView
|
||||
# Preserve generic type information for EventRenderer and its subclasses
|
||||
-keepclassmembers class * extends com.github.tibolte.agendacalendarview.render.EventRenderer {
|
||||
<fields>;
|
||||
<methods>;
|
||||
}
|
||||
|
||||
# Keep the EventRenderer class itself and all its subclasses
|
||||
-keep class com.github.tibolte.agendacalendarview.render.EventRenderer
|
||||
-keep class * extends com.github.tibolte.agendacalendarview.render.EventRenderer
|
||||
|
||||
# ServiceLoader support
|
||||
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||
-keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}
|
||||
-keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}
|
||||
|
||||
# Most of volatile fields are updated with AFU and should not be mangled
|
||||
@ -70,6 +98,7 @@
|
||||
|
||||
-keep class pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing { public final byte[] pleaseStopRightNow(java.lang.String, long); }
|
||||
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.ui.login.qr.* { *; }
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
||||
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.login.LoginInfo$Platform { *; }
|
||||
|
2348
app/schemas/pl.szczodrzynski.edziennik.data.db.AppDb/101.json
Normal file
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
app/src/debug/res/mipmap-hdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 874 B |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/debug/res/mipmap-mdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/debug/res/mipmap-xxhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v1.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v1_foreground.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v3.webp
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v3_foreground.webp
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v4.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v4_foreground.webp
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5.webp
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5_foreground.webp
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_launcher_v5_monochrome.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v1.webp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v3.webp
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v4.webp
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
app/src/debug/res/mipmap-xxxhdpi/ic_splash_v5.webp
Normal file
After Width: | Height: | Size: 24 KiB |
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="pl.szczodrzynski.edziennik">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
@ -12,19 +11,21 @@
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<!-- PowerPermission uses minSdk 21, it's safe to override as it is used only in >= 23 -->
|
||||
<uses-sdk tools:overrideLibrary="com.qifan.powerpermission.coroutines, com.qifan.powerpermission.core" />
|
||||
<uses-sdk
|
||||
tools:overrideLibrary="com.qifan.powerpermission.coroutines, com.qifan.powerpermission.core, com.mikepenz:materialdrawer, com.mikepenz.iconics.typeface.library.navlibfont, androidx.appcompat.resources, androidx.appcompat, com.google.android.gms.wearable, com.google.android.gms.base, com.google.firebase.crashlytics, com.google.firebase.sessions, com.google.firebase.ktx, com.google.firebase, com.google.android.gms.tasks, com.google.android.gms.common, com.google.firebase.components" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_descriptor"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:icon="@mipmap/ic_launcher_v5"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.Dark"
|
||||
android:theme="@style/AppTheme.M3.Blue"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
@ -40,7 +41,6 @@
|
||||
|___/ -->
|
||||
<activity android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:exported="true"
|
||||
android:theme="@style/SplashTheme">
|
||||
@ -67,7 +67,7 @@
|
||||
android:excludeFromRecents="true"
|
||||
android:noHistory="true"
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.Dark.NoDisplay">
|
||||
android:theme="@style/AppTheme.M3.NoDisplay">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
@ -84,14 +84,14 @@
|
||||
android:resource="@xml/widget_timetable_info" />
|
||||
</receiver>
|
||||
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" android:foregroundServiceType="dataSync"/>
|
||||
<activity android:name=".ui.widgets.LessonDialogActivity"
|
||||
android:label=""
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:excludeFromRecents="true"
|
||||
android:noHistory="true"
|
||||
android:exported="true"
|
||||
android:theme="@style/AppTheme.Dark.NoDisplay" />
|
||||
android:theme="@style/AppTheme.M3.NoDisplay" />
|
||||
<!-- NOTIFICATIONS -->
|
||||
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
||||
android:label="@string/widget_notifications_title"
|
||||
@ -105,7 +105,7 @@
|
||||
android:resource="@xml/widget_notifications_info" />
|
||||
</receiver>
|
||||
<service android:name=".ui.widgets.notifications.WidgetNotificationsService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" android:foregroundServiceType="dataSync"/>
|
||||
<!-- LUCKY NUMBER -->
|
||||
<receiver android:name=".ui.widgets.luckynumber.WidgetLuckyNumberProvider"
|
||||
android:label="@string/widget_lucky_number_title"
|
||||
@ -126,33 +126,31 @@
|
||||
/ ____ \ (__| |_| |\ V /| | |_| | __/\__ \
|
||||
/_/ \_\___|\__|_| \_/ |_|\__|_|\___||___/
|
||||
-->
|
||||
<activity android:name=".ui.base.CrashActivity"
|
||||
<activity android:name=".ui.main.CrashActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:process=":error_activity"
|
||||
android:exported="false"
|
||||
android:theme="@style/DeadTheme" />
|
||||
<activity android:name=".ui.intro.ChangelogIntroActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.Intro" />
|
||||
<activity android:name=".ui.login.LoginActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:launchMode="singleTop"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.Light" />
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.home.CounterActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.Black" />
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.feedback.FeedbackActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme" />
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name=".ui.settings.SettingsLicenseActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme" />
|
||||
android:theme="@style/AppTheme.M3" />
|
||||
<activity android:name="com.canhub.cropper.CropImageActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
@ -160,9 +158,12 @@
|
||||
<activity android:name=".ui.login.oauth.OAuthLoginActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.Light" />
|
||||
<activity android:name=".ui.base.BuildInvalidActivity" android:exported="false" />
|
||||
<activity android:name=".ui.settings.contributors.ContributorsActivity" android:exported="false" />
|
||||
android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar" />
|
||||
<activity android:name=".ui.login.recaptcha.RecaptchaActivity"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar" />
|
||||
<activity android:name=".ui.main.BuildInvalidActivity" android:exported="false" />
|
||||
|
||||
<!-- _____ _
|
||||
| __ \ (_)
|
||||
@ -171,7 +172,7 @@
|
||||
| | \ \ __/ (_| __/ |\ V / __/ | \__ \
|
||||
|_| \_\___|\___\___|_| \_/ \___|_| |___/
|
||||
-->
|
||||
<receiver android:name=".receivers.UserPresentReceiver"
|
||||
<receiver android:name=".core.receiver.UserPresentReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
@ -184,7 +185,7 @@
|
||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.SzkolnyReceiver"
|
||||
<receiver android:name=".core.receiver.SzkolnyReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" />
|
||||
@ -198,15 +199,15 @@
|
||||
____) | __/ | \ V /| | (_| __/\__ \
|
||||
|_____/ \___|_| \_/ |_|\___\___||___/
|
||||
-->
|
||||
<service android:name=".data.api.ApiService" />
|
||||
<service android:name=".data.firebase.MyFirebaseService"
|
||||
android:exported="false">
|
||||
<service android:name=".data.api.ApiService" android:foregroundServiceType="dataSync"/>
|
||||
<service android:name=".core.firebase.MyFirebaseService"
|
||||
android:exported="false" android:foregroundServiceType="dataSync">
|
||||
<intent-filter android:priority="10000000">
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name=".sync.UpdateDownloaderService" />
|
||||
<service android:name=".sync.UpdateDownloaderService" android:foregroundServiceType="dataSync"/>
|
||||
|
||||
<!--
|
||||
_____ _ _
|
||||
|
@ -1,9 +1,11 @@
|
||||
<h3>Wersja 4.13.2, 2022-11-28</h3>
|
||||
<h3>Wersja 4.14, 2025-02-02</h3>
|
||||
<ul>
|
||||
<li>Poprawiono synchronizację w Mobidzienniku bez ustawionego adresu e-mail.</li>
|
||||
<li>Poprawiono błąd synchronizacji w Vulcanie.</li>
|
||||
<li>USOS: <b>dodano obsługę ocen</b>.</li>
|
||||
<li>USOS: obliczanie średniej za studia oraz punktów ECTS.</li>
|
||||
<li>USOS: poprawiono brak planu zajęć po rozpoczęciu roku.</li>
|
||||
<li>Wyłączono archiwizator profili.</li>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
Dzięki za korzystanie ze Szkolnego!<br>
|
||||
<i>© [Kuba Szczodrzyński](@kuba2k2) 2022</i>
|
||||
<i>© [Kuba Szczodrzyński](@kuba2k2) 2025</i>
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
project(szkolny-signing)
|
||||
|
||||
# Creates and names a library, sets it as either STATIC
|
||||
# or SHARED, and provides the relative paths to its source code.
|
||||
# You can define multiple libraries, and CMake builds them for you.
|
||||
@ -41,4 +43,4 @@ target_link_libraries( # Specifies the target library.
|
||||
|
||||
# Links the target library to the log library
|
||||
# included in the NDK.
|
||||
${log-lib} )
|
||||
${log-lib} )
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
/*secret password - removed for source code publication*/
|
||||
static toys AES_IV[16] = {
|
||||
0x8c, 0xad, 0x9c, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
0xee, 0x23, 0xf1, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||
|
||||
|
@ -4,12 +4,6 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
@ -20,12 +14,7 @@ import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||
import com.chuckerteam.chucker.api.RetentionManager
|
||||
import com.google.firebase.FirebaseApp
|
||||
import com.google.firebase.FirebaseOptions
|
||||
import com.google.firebase.iid.FirebaseInstanceId
|
||||
import com.google.firebase.messaging.FirebaseMessaging
|
||||
import com.google.gson.Gson
|
||||
import com.hypertrack.hyperlog.HyperLog
|
||||
import com.mikepenz.iconics.Iconics
|
||||
import im.wangchao.mhttp.MHttp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -36,42 +25,39 @@ import kotlinx.coroutines.withContext
|
||||
import me.leolin.shortcutbadger.ShortcutBadger
|
||||
import okhttp3.OkHttpClient
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import pl.szczodrzynski.edziennik.config.AppData
|
||||
import pl.szczodrzynski.edziennik.config.Config
|
||||
import pl.szczodrzynski.edziennik.core.manager.AttendanceManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.AvailabilityManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.BuildManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.EventManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.FirebaseManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.LoggingManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.MessageManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.NoteManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.NotificationManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.PermissionManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.ShortcutManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.TimetableManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.UiManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.UpdateManager
|
||||
import pl.szczodrzynski.edziennik.core.manager.UserActionManager
|
||||
import pl.szczodrzynski.edziennik.core.network.DumbCookieJar
|
||||
import pl.szczodrzynski.edziennik.core.work.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||
import pl.szczodrzynski.edziennik.data.config.AppData
|
||||
import pl.szczodrzynski.edziennik.data.config.Config
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.ext.DAY
|
||||
import pl.szczodrzynski.edziennik.ext.MS
|
||||
import pl.szczodrzynski.edziennik.ext.putExtras
|
||||
import pl.szczodrzynski.edziennik.ext.setLanguage
|
||||
import pl.szczodrzynski.edziennik.data.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.network.SSLProviderInstaller
|
||||
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
|
||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.ui.base.CrashActivity
|
||||
import pl.szczodrzynski.edziennik.ui.base.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.utils.DebugLogFormat
|
||||
import pl.szczodrzynski.edziennik.ui.main.CrashActivity
|
||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
import pl.szczodrzynski.edziennik.utils.managers.AttendanceManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.BuildManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.EventManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.MessageManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.NoteManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.PermissionManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.TimetableManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.UpdateManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.system.exitProcess
|
||||
@ -82,7 +68,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
lateinit var db: AppDb
|
||||
private set
|
||||
lateinit var config: Config
|
||||
// private set // for LabFragment
|
||||
|
||||
// private set // for LabFragment
|
||||
lateinit var profile: Profile
|
||||
private set
|
||||
lateinit var data: AppData
|
||||
@ -91,7 +78,6 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
get() = profile.id
|
||||
|
||||
var enableChucker = false
|
||||
var debugMode = false
|
||||
var devMode = false
|
||||
}
|
||||
|
||||
@ -100,13 +86,17 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
val availabilityManager by lazy { AvailabilityManager(this) }
|
||||
val buildManager by lazy { BuildManager(this) }
|
||||
val eventManager by lazy { EventManager(this) }
|
||||
val firebaseManager by lazy { FirebaseManager(this) }
|
||||
val gradesManager by lazy { GradesManager(this) }
|
||||
val loggingManager by lazy { LoggingManager(this) }
|
||||
val messageManager by lazy { MessageManager(this) }
|
||||
val noteManager by lazy { NoteManager(this) }
|
||||
val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
|
||||
val notificationManager by lazy { NotificationManager(this) }
|
||||
val permissionManager by lazy { PermissionManager(this) }
|
||||
val shortcutManager by lazy { ShortcutManager(this) }
|
||||
val textStylingManager by lazy { TextStylingManager(this) }
|
||||
val timetableManager by lazy { TimetableManager(this) }
|
||||
val uiManager by lazy { UiManager(this) }
|
||||
val updateManager by lazy { UpdateManager(this) }
|
||||
val userActionManager by lazy { UserActionManager(this) }
|
||||
|
||||
@ -124,9 +114,10 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
private val job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
override fun getWorkManagerConfiguration() = Configuration.Builder()
|
||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
||||
.build()
|
||||
|
||||
override val workManagerConfiguration: Configuration = Configuration.Builder()
|
||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
||||
.build()
|
||||
|
||||
val permissionChecker by lazy { PermissionChecker(this) }
|
||||
val gson by lazy { Gson() }
|
||||
@ -155,7 +146,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
|
||||
if (devMode) {
|
||||
if (enableChucker) {
|
||||
val chuckerCollector = ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
|
||||
val chuckerCollector =
|
||||
ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
|
||||
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
||||
builder.addInterceptor(chuckerInterceptor)
|
||||
}
|
||||
@ -170,6 +162,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
|
||||
MHttp.instance().customOkHttpClient(http)
|
||||
}
|
||||
|
||||
val cookieJar by lazy { DumbCookieJar(this) }
|
||||
|
||||
/* _____ _ _
|
||||
@ -180,7 +173,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
||||
__/ |
|
||||
|__*/
|
||||
val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
||||
val deviceId: String by lazy {
|
||||
Settings.Secure.getString(
|
||||
contentResolver,
|
||||
Settings.Secure.ANDROID_ID
|
||||
) ?: ""
|
||||
}
|
||||
private var unreadBadgesAvailable = true
|
||||
|
||||
/* _____ _
|
||||
@ -191,35 +189,46 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
\___/|_| |_|\_____|_| \___|\__,_|\__\__*/
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
CaocConfig.Builder.create()
|
||||
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM)
|
||||
.enabled(true)
|
||||
.showErrorDetails(true)
|
||||
.showRestartButton(true)
|
||||
.logErrorOnRestart(true)
|
||||
.trackActivities(true)
|
||||
.minTimeBetweenCrashesMs(60*1000)
|
||||
.errorDrawable(R.drawable.ic_rip)
|
||||
.restartActivity(MainActivity::class.java)
|
||||
.errorActivity(CrashActivity::class.java)
|
||||
.apply()
|
||||
Iconics.init(applicationContext)
|
||||
Iconics.respectFontBoundsDefault = true
|
||||
|
||||
// initialize companion object values
|
||||
// initialize Timber to enable basic logging
|
||||
Timber.plant(loggingManager.logcatTree)
|
||||
Timber.i("Initializing Szkolny.eu app v${BuildConfig.VERSION_NAME}")
|
||||
// initialize core objects
|
||||
AppData.read(this)
|
||||
App.db = AppDb(this)
|
||||
App.config = Config(App.db)
|
||||
debugMode = BuildConfig.DEBUG
|
||||
devMode = config.devMode ?: debugMode
|
||||
// read and migrate global config
|
||||
App.config = Config(this)
|
||||
App.config.migrate()
|
||||
// add database logging to Timber
|
||||
Timber.plant(loggingManager.databaseTree)
|
||||
Timber.i("Initialized Szkolny.eu app v${BuildConfig.VERSION_NAME}")
|
||||
|
||||
devMode = config.devMode ?: BuildConfig.DEBUG
|
||||
if (config.devModePassword != null)
|
||||
checkDevModePassword()
|
||||
enableChucker = config.enableChucker ?: devMode
|
||||
|
||||
if (devMode) {
|
||||
HyperLog.initialize(this)
|
||||
HyperLog.setLogLevel(Log.VERBOSE)
|
||||
HyperLog.setLogFormat(DebugLogFormat(this))
|
||||
}
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
CaocConfig.Builder.create()
|
||||
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM)
|
||||
.enabled(true)
|
||||
.showErrorDetails(true)
|
||||
.showRestartButton(true)
|
||||
.logErrorOnRestart(true)
|
||||
.trackActivities(true)
|
||||
.minTimeBetweenCrashesMs(60 * 1000)
|
||||
.errorDrawable(R.drawable.ic_rip)
|
||||
.restartActivity(MainActivity::class.java)
|
||||
.errorActivity(CrashActivity::class.java)
|
||||
.apply()
|
||||
Iconics.init(applicationContext)
|
||||
Iconics.respectFontBoundsDefault = true
|
||||
Signing.getCert(this)
|
||||
Utils.initializeStorageDir(this)
|
||||
buildHttp()
|
||||
|
||||
uiManager.applyNightMode()
|
||||
uiManager.applyLanguage(this)
|
||||
|
||||
if (!profileLoadById(config.lastProfileId)) {
|
||||
val success = db.profileDao().firstId?.let { profileLoadById(it) }
|
||||
@ -227,192 +236,38 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
profileLoad(Profile(0, 0, LoginType.TEMPLATE, ""))
|
||||
}
|
||||
|
||||
buildHttp()
|
||||
launch(Dispatchers.Default) {
|
||||
buildManager.fetchInstalledTime()
|
||||
firebaseManager.initializeApps()
|
||||
loggingManager.cleanupIfNeeded()
|
||||
loggingManager.cleanupHyperLogDatabase()
|
||||
notificationManager.registerAllChannels()
|
||||
shortcutManager.createShortcuts()
|
||||
|
||||
if (config.appVersionCore < BuildConfig.VERSION_CODE) {
|
||||
// force syncing all endpoints on update
|
||||
db.endpointTimerDao().clear()
|
||||
config.sync.lastAppSync = 0L
|
||||
config.hash = "invalid"
|
||||
config.appVersionCore = BuildConfig.VERSION_CODE
|
||||
}
|
||||
|
||||
Themes.themeInt = config.ui.theme
|
||||
config.ui.language?.let {
|
||||
setLanguage(it)
|
||||
SSLProviderInstaller.install(applicationContext, this@App::buildHttp)
|
||||
|
||||
if (config.sync.enabled)
|
||||
SyncWorker.scheduleNext(this@App, false)
|
||||
else
|
||||
SyncWorker.cancelNext(this@App)
|
||||
|
||||
if (config.sync.notifyAboutUpdates)
|
||||
UpdateWorker.scheduleNext(this@App, false)
|
||||
else
|
||||
UpdateWorker.cancelNext(this@App)
|
||||
}
|
||||
|
||||
Signing.getCert(this)
|
||||
|
||||
launch {
|
||||
withContext(Dispatchers.Default) {
|
||||
config.migrate(this@App)
|
||||
|
||||
SSLProviderInstaller.install(applicationContext, this@App::buildHttp)
|
||||
|
||||
if (config.devModePassword != null)
|
||||
checkDevModePassword()
|
||||
|
||||
if (config.sync.enabled)
|
||||
SyncWorker.scheduleNext(this@App, false)
|
||||
else
|
||||
SyncWorker.cancelNext(this@App)
|
||||
|
||||
if (config.sync.notifyAboutUpdates)
|
||||
UpdateWorker.scheduleNext(this@App, false)
|
||||
else
|
||||
UpdateWorker.cancelNext(this@App)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
||||
|
||||
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
|
||||
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
|
||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||
.putExtras("fragmentId" to NavTarget.TIMETABLE))
|
||||
.build()
|
||||
|
||||
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
|
||||
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
|
||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||
.putExtras("fragmentId" to NavTarget.AGENDA))
|
||||
.build()
|
||||
|
||||
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
|
||||
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
|
||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||
.putExtras("fragmentId" to NavTarget.GRADES))
|
||||
.build()
|
||||
|
||||
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
|
||||
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
|
||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||
.putExtras("fragmentId" to NavTarget.HOMEWORK))
|
||||
.build()
|
||||
|
||||
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
|
||||
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
|
||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||
.putExtras("fragmentId" to NavTarget.MESSAGES))
|
||||
.build()
|
||||
|
||||
shortcutManager.dynamicShortcuts = listOf(
|
||||
shortcutTimetable,
|
||||
shortcutAgenda,
|
||||
shortcutGrades,
|
||||
shortcutHomework,
|
||||
shortcutMessages
|
||||
)
|
||||
} // shortcuts - end
|
||||
|
||||
notificationChannelsManager.registerAllChannels()
|
||||
|
||||
|
||||
if (config.appInstalledTime == 0L)
|
||||
try {
|
||||
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
||||
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
val pushMobidziennikApp = FirebaseApp.initializeApp(
|
||||
this@App,
|
||||
FirebaseOptions.Builder()
|
||||
.setProjectId("mobidziennik")
|
||||
.setStorageBucket("mobidziennik.appspot.com")
|
||||
.setDatabaseUrl("https://mobidziennik.firebaseio.com")
|
||||
.setGcmSenderId("747285019373")
|
||||
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
||||
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
||||
.build(),
|
||||
"Mobidziennik2"
|
||||
)
|
||||
|
||||
val pushLibrusApp = FirebaseApp.initializeApp(
|
||||
this@App,
|
||||
FirebaseOptions.Builder()
|
||||
.setProjectId("synergiadru")
|
||||
.setStorageBucket("synergiadru.appspot.com")
|
||||
.setDatabaseUrl("https://synergiadru.firebaseio.com")
|
||||
.setGcmSenderId("513056078587")
|
||||
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
||||
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
||||
.build(),
|
||||
"Librus"
|
||||
)
|
||||
|
||||
val pushVulcanApp = FirebaseApp.initializeApp(
|
||||
this@App,
|
||||
FirebaseOptions.Builder()
|
||||
.setProjectId("dzienniczekplus")
|
||||
.setStorageBucket("dzienniczekplus.appspot.com")
|
||||
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
|
||||
.setGcmSenderId("987828170337")
|
||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
||||
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
||||
.build(),
|
||||
"Vulcan"
|
||||
)
|
||||
|
||||
val pushVulcanHebeApp = FirebaseApp.initializeApp(
|
||||
this@App,
|
||||
FirebaseOptions.Builder()
|
||||
.setProjectId("dzienniczekplus")
|
||||
.setStorageBucket("dzienniczekplus.appspot.com")
|
||||
.setDatabaseUrl("https://dzienniczekplus.firebaseio.com")
|
||||
.setGcmSenderId("987828170337")
|
||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
||||
.setApplicationId("1:987828170337:android:7e16404b9e5deaaa")
|
||||
.build(),
|
||||
"VulcanHebe"
|
||||
)
|
||||
|
||||
try {
|
||||
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
|
||||
val token = instanceIdResult.token
|
||||
d("Firebase", "Got App token: $token")
|
||||
config.sync.tokenApp = token
|
||||
}
|
||||
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||
val token = instanceIdResult.token
|
||||
d("Firebase", "Got Mobidziennik2 token: $token")
|
||||
if (token != config.sync.tokenMobidziennik) {
|
||||
config.sync.tokenMobidziennik = token
|
||||
config.sync.tokenMobidziennikList = listOf()
|
||||
}
|
||||
}
|
||||
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||
val token = instanceIdResult.token
|
||||
d("Firebase", "Got Librus token: $token")
|
||||
if (token != config.sync.tokenLibrus) {
|
||||
config.sync.tokenLibrus = token
|
||||
config.sync.tokenLibrusList = listOf()
|
||||
}
|
||||
}
|
||||
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||
val token = instanceIdResult.token
|
||||
d("Firebase", "Got Vulcan token: $token")
|
||||
if (token != config.sync.tokenVulcan) {
|
||||
config.sync.tokenVulcan = token
|
||||
config.sync.tokenVulcanList = listOf()
|
||||
}
|
||||
}
|
||||
FirebaseInstanceId.getInstance(pushVulcanHebeApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||
val token = instanceIdResult.token
|
||||
d("Firebase", "Got VulcanHebe token: $token")
|
||||
if (token != config.sync.tokenVulcanHebe) {
|
||||
config.sync.tokenVulcanHebe = token
|
||||
config.sync.tokenVulcanHebeList = listOf()
|
||||
}
|
||||
}
|
||||
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
|
||||
} catch (e: IllegalStateException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
db.metadataDao().countUnseen().observeForever { count: Int ->
|
||||
if (unreadBadgesAvailable)
|
||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
||||
}
|
||||
db.metadataDao().countUnseen().observeForever { count: Int ->
|
||||
if (unreadBadgesAvailable)
|
||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,9 +276,15 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
App.config.lastProfileId = profile.id
|
||||
try {
|
||||
App.data = AppData.get(profile.loginStoreType)
|
||||
d("App", "Loaded AppData: ${App.data}")
|
||||
Timber.d("Loaded AppData: ${App.data}")
|
||||
// apply newly-added config overrides, if not changed by the user yet
|
||||
for ((key, value) in App.data.configOverrides) {
|
||||
val config = App.profile.config
|
||||
if (key !in config)
|
||||
config[key] = value
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("App", "Cannot load AppData", e)
|
||||
Timber.e(e, "Cannot load AppData")
|
||||
Toast.makeText(this, R.string.app_cannot_load_data, Toast.LENGTH_LONG).show()
|
||||
exitProcess(0)
|
||||
}
|
||||
@ -436,6 +297,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) {
|
||||
launch {
|
||||
val success = withContext(Dispatchers.Default) {
|
||||
@ -447,6 +309,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
profileLoadLast(onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) {
|
||||
launch {
|
||||
val success = withContext(Dispatchers.Default) {
|
||||
@ -454,12 +317,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
}
|
||||
if (!success) {
|
||||
EventBus.getDefault().post(ProfileListEmptyEvent())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
onSuccess(profile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun profileSave() = profileSave(profile)
|
||||
fun profileSave(profile: Profile) {
|
||||
if (profile.id == profileId)
|
||||
@ -470,10 +333,13 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
}
|
||||
|
||||
fun checkDevModePassword() {
|
||||
devMode = try {
|
||||
Utils.AESCrypt.decrypt("nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=", config.devModePassword) == "ok here you go it's enabled now" || BuildConfig.DEBUG
|
||||
devMode = devMode || try {
|
||||
Utils.AESCrypt.decrypt(
|
||||
"nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=",
|
||||
config.devModePassword
|
||||
) == "ok here you go it's enabled now"
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Timber.e(e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -15,70 +15,99 @@ import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.danimahardhika.cafebar.CafeBar
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.danimahardhika.cafebar.CafeBarTheme
|
||||
import com.jetradarmobile.snowfall.SnowfallView
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import com.mikepenz.materialdrawer.model.*
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ExpandableDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.descriptionRes
|
||||
import com.mikepenz.materialdrawer.model.interfaces.nameRes
|
||||
import com.mikepenz.materialdrawer.model.utils.hiddenInMiniDrawer
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pl.droidsonroids.gif.GifDrawable
|
||||
import pl.szczodrzynski.edziennik.core.manager.AvailabilityManager.Error.Type
|
||||
import pl.szczodrzynski.edziennik.core.manager.UserActionManager
|
||||
import pl.szczodrzynski.edziennik.core.work.AppManagerDetectedEvent
|
||||
import pl.szczodrzynski.edziennik.core.work.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateStateEvent
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_API_DEPRECATED
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskErrorEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskFinishedEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskProgressEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskStartedEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.RegisterAvailabilityEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.enums.FeatureType
|
||||
import pl.szczodrzynski.edziennik.data.enums.FeatureType
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTargetLocation
|
||||
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateStateEvent
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.ui.base.MainSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.base.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.base.enums.NavTargetLocation
|
||||
import pl.szczodrzynski.edziennik.ext.JsonObject
|
||||
import pl.szczodrzynski.edziennik.ext.getAppData
|
||||
import pl.szczodrzynski.edziennik.ext.getEnum
|
||||
import pl.szczodrzynski.edziennik.ext.getIntOrNull
|
||||
import pl.szczodrzynski.edziennik.ext.hasUIFeature
|
||||
import pl.szczodrzynski.edziennik.ext.isBeforeYear
|
||||
import pl.szczodrzynski.edziennik.ext.keys
|
||||
import pl.szczodrzynski.edziennik.ext.putExtras
|
||||
import pl.szczodrzynski.edziennik.ext.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.ext.resolveString
|
||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||
import pl.szczodrzynski.edziennik.ext.shouldArchive
|
||||
import pl.szczodrzynski.edziennik.ext.takePositive
|
||||
import pl.szczodrzynski.edziennik.ext.toDrawable
|
||||
import pl.szczodrzynski.edziennik.ext.toImageHolder
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.SimpleDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ChangelogDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.RegisterUnavailableDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.ServerMessageDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.UpdateAvailableDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.UpdateProgressDialog
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.ui.main.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.main.MainSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
||||
import pl.szczodrzynski.edziennik.utils.*
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.dpToPx
|
||||
import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type
|
||||
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
|
||||
import pl.szczodrzynski.edziennik.utils.BigNightUtil
|
||||
import pl.szczodrzynski.edziennik.utils.PausedNavigationData
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.appManagerIntentList
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_HALF_TRANSPARENT
|
||||
import pl.szczodrzynski.navlib.NavView
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -99,7 +128,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) }
|
||||
val requestHandler by lazy { MainActivityRequestHandler(this) }
|
||||
|
||||
val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout }
|
||||
val swipeRefreshLayout: SwipeRefreshLayout by lazy { b.swipeRefreshLayout }
|
||||
|
||||
var onBeforeNavigate: (() -> Boolean)? = null
|
||||
private var pausedNavigationData: PausedNavigationData? = null
|
||||
@ -125,22 +154,19 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
d(TAG, "Activity created")
|
||||
|
||||
setTheme(Themes.appTheme)
|
||||
|
||||
app.config.ui.language?.let {
|
||||
setLanguage(it)
|
||||
}
|
||||
Timber.i("Activity created")
|
||||
|
||||
app.uiManager.applyTheme(this)
|
||||
app.uiManager.applyLanguage(this)
|
||||
app.buildManager.validateBuild(this)
|
||||
|
||||
if (App.profileId == 0) {
|
||||
Timber.i("Profile is not loaded")
|
||||
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||
return
|
||||
}
|
||||
|
||||
d(TAG, "Profile is valid, inflating views")
|
||||
Timber.i("Profile is valid, inflating views")
|
||||
|
||||
setContentView(b.root)
|
||||
|
||||
@ -148,10 +174,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
||||
|
||||
val versionBadge = app.buildManager.versionBadge
|
||||
b.nightlyText.isVisible = versionBadge != null
|
||||
b.nightlyText.text = versionBadge
|
||||
navView.nightlyText.isVisible = versionBadge != null
|
||||
navView.nightlyText.text = versionBadge
|
||||
if (versionBadge != null) {
|
||||
b.nightlyText.background.setTintColor(0xa0ff0000.toInt())
|
||||
navView.nightlyText.background.setTintColor(0xa0ff0000.toInt())
|
||||
}
|
||||
|
||||
navLoading = true
|
||||
@ -159,57 +185,34 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
b.navView.apply {
|
||||
drawer.init(this@MainActivity)
|
||||
|
||||
SystemBarsUtil(this@MainActivity).run {
|
||||
//paddingByKeyboard = b.navView
|
||||
appFullscreen = false
|
||||
statusBarColor = getColorFromAttr(context, android.R.attr.colorBackground)
|
||||
statusBarDarker = false
|
||||
statusBarFallbackLight = COLOR_HALF_TRANSPARENT
|
||||
statusBarFallbackGradient = COLOR_HALF_TRANSPARENT
|
||||
navigationBarTransparent = false
|
||||
|
||||
b.navView.configSystemBarsUtil(this)
|
||||
|
||||
// fix for setting status bar color to window color, outside of navlib
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
window.statusBarColor = statusBarColor
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& ColorUtils.calculateLuminance(statusBarColor) > 0.6
|
||||
) {
|
||||
@Suppress("deprecation")
|
||||
window.decorView.systemUiVisibility =
|
||||
window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
|
||||
// TODO fix navlib navbar detection, orientation change issues, status bar color setting if not fullscreen
|
||||
|
||||
commit()
|
||||
val statusBarColor = android.R.attr.colorBackground.resolveAttr(context)
|
||||
// fix for setting status bar color to window color, outside of navlib
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
window.statusBarColor = statusBarColor
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& ColorUtils.calculateLuminance(statusBarColor) > 0.6
|
||||
) {
|
||||
@Suppress("deprecation")
|
||||
window.decorView.systemUiVisibility =
|
||||
window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
|
||||
toolbar.apply {
|
||||
subtitleFormat = R.string.toolbar_subtitle
|
||||
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||
enable = true
|
||||
enableMenuControls = true
|
||||
}
|
||||
|
||||
bottomBar.apply {
|
||||
enable = false
|
||||
enableMenuControls = false
|
||||
fabEnable = false
|
||||
fabExtendable = true
|
||||
fabExtended = false
|
||||
fabGravity = Gravity.CENTER
|
||||
if (Themes.isDark) {
|
||||
setBackgroundColor(blendColors(
|
||||
getColorFromAttr(context, R.attr.colorSurface),
|
||||
getColorFromRes(R.color.colorSurface_4dp)
|
||||
))
|
||||
elevation = dpToPx(4).toFloat()
|
||||
}
|
||||
fabGravity = Gravity.END
|
||||
}
|
||||
|
||||
bottomSheet.apply {
|
||||
removeAllItems()
|
||||
toggleGroupEnabled = false
|
||||
textInputEnabled = false
|
||||
onCloseListener = {
|
||||
if (!app.config.ui.bottomSheetOpened)
|
||||
app.config.ui.bottomSheetOpened = true
|
||||
@ -226,7 +229,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
if (item is ExpandableDrawerItem)
|
||||
false
|
||||
else
|
||||
navigate(navTarget = id.asNavTargetOrNull())
|
||||
navigate(navTarget = NavTarget.getById(id))
|
||||
}
|
||||
drawerProfileSelectedListener = { id, _, _, _ ->
|
||||
// why is this negated -_-
|
||||
@ -289,9 +292,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
drawer.setUnreadCounterList(unreadCounters)
|
||||
}
|
||||
|
||||
b.swipeRefreshLayout.isEnabled = true
|
||||
b.swipeRefreshLayout.setOnRefreshListener { launch { syncCurrentFeature() } }
|
||||
b.swipeRefreshLayout.setColorSchemeResources(
|
||||
swipeRefreshLayout.setOnRefreshListener { launch { syncCurrentFeature() } }
|
||||
swipeRefreshLayout.setColorSchemeResources(
|
||||
R.color.md_blue_500,
|
||||
R.color.md_amber_500,
|
||||
R.color.md_green_500
|
||||
@ -322,7 +324,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
|
||||
// IT'S WINTER MY DUDES
|
||||
val today = Date.getToday()
|
||||
if ((today.month % 11 == 1) && app.config.ui.snowfall) {
|
||||
if ((today.month / 3 % 4 == 0) && app.config.ui.snowfall) {
|
||||
b.rootFrame.addView(layoutInflater.inflate(R.layout.snowfall, b.rootFrame, false))
|
||||
} else if (app.config.ui.eggfall && BigNightUtil().isDataWielkanocyNearDzisiaj()) {
|
||||
val eggfall = layoutInflater.inflate(
|
||||
@ -358,12 +360,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
if (app.config.appRateSnackbarTime != 0L && app.config.appRateSnackbarTime <= System.currentTimeMillis()) {
|
||||
navView.coordinator.postDelayed({
|
||||
CafeBar.builder(this)
|
||||
.theme(CafeBarTheme.Custom(R.attr.colorSurfaceInverse.resolveAttr(this)))
|
||||
.content(R.string.rate_snackbar_text)
|
||||
.icon(IconicsDrawable(this).apply {
|
||||
icon = CommunityMaterial.Icon3.cmd_star_outline
|
||||
sizeDp = 24
|
||||
colorInt = Themes.getPrimaryTextColor(this@MainActivity)
|
||||
})
|
||||
.icon(CommunityMaterial.Icon3.cmd_star_outline.toDrawable())
|
||||
.positiveText(R.string.rate_snackbar_positive)
|
||||
.positiveColor(-0xb350b0)
|
||||
.negativeText(R.string.rate_snackbar_negative)
|
||||
@ -417,7 +416,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
|
||||
private var profileSettingClickListener = { itemId: Int, _: View? ->
|
||||
when (val item = itemId.asNavTarget()) {
|
||||
when (val item = NavTarget.getById(itemId)) {
|
||||
NavTarget.PROFILE_ADD -> {
|
||||
requestHandler.requestLogin()
|
||||
}
|
||||
@ -457,37 +456,37 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
|__*/
|
||||
private suspend fun syncCurrentFeature() {
|
||||
if (app.profile.archived) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.profile_archived_title)
|
||||
.setMessage(
|
||||
SimpleDialog<Unit>(this) {
|
||||
title(R.string.profile_archived_title)
|
||||
message(
|
||||
R.string.profile_archived_text,
|
||||
app.profile.studentSchoolYearStart,
|
||||
app.profile.studentSchoolYearStart + 1
|
||||
)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
positive(R.string.ok)
|
||||
}.show()
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
return
|
||||
}
|
||||
if (app.profile.shouldArchive()) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.profile_archiving_title)
|
||||
.setMessage(
|
||||
SimpleDialog<Unit>(this) {
|
||||
title(R.string.profile_archiving_title)
|
||||
message(
|
||||
R.string.profile_archiving_format,
|
||||
app.profile.dateYearEnd.formattedString
|
||||
)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
positive(R.string.ok)
|
||||
}.show()
|
||||
}
|
||||
if (app.profile.isBeforeYear()) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.profile_year_not_started_title)
|
||||
.setMessage(
|
||||
SimpleDialog<Unit>(this) {
|
||||
title(R.string.profile_year_not_started_title)
|
||||
message(
|
||||
R.string.profile_year_not_started_format,
|
||||
app.profile.dateSemester1Start.formattedString
|
||||
)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
positive(R.string.ok)
|
||||
}.show()
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
return
|
||||
}
|
||||
@ -560,8 +559,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
swipeRefreshLayout.isRefreshing = true
|
||||
if (event.profileId == App.profileId) {
|
||||
navView.toolbar.apply {
|
||||
subtitleFormat = null
|
||||
subtitleFormatWithUnread = null
|
||||
subtitle = getString(R.string.toolbar_subtitle_syncing)
|
||||
}
|
||||
}
|
||||
@ -569,7 +566,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) {
|
||||
d(TAG, "Profile list is empty. Launch LoginActivity.")
|
||||
app.config.loginFinished = false
|
||||
startActivity(Intent(this, LoginActivity::class.java))
|
||||
finish()
|
||||
@ -579,8 +575,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
||||
if (event.profileId == App.profileId) {
|
||||
navView.toolbar.apply {
|
||||
subtitleFormat = null
|
||||
subtitleFormatWithUnread = null
|
||||
subtitle = if (event.progress < 0f)
|
||||
event.progressText ?: ""
|
||||
else
|
||||
@ -599,8 +593,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
EventBus.getDefault().removeStickyEvent(event)
|
||||
if (event.profileId == App.profileId) {
|
||||
navView.toolbar.apply {
|
||||
subtitleFormat = R.string.toolbar_subtitle
|
||||
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||
subtitle = "Gotowe"
|
||||
}
|
||||
}
|
||||
@ -621,8 +613,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
ErrorDetailsDialog(this, listOf(event.error)).show()
|
||||
}
|
||||
navView.toolbar.apply {
|
||||
subtitleFormat = R.string.toolbar_subtitle
|
||||
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||
subtitle = "Gotowe"
|
||||
}
|
||||
mainSnackbar.dismiss()
|
||||
@ -634,10 +624,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
EventBus.getDefault().removeStickyEvent(event)
|
||||
if (app.config.sync.dontShowAppManagerDialog)
|
||||
return
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.app_manager_dialog_title)
|
||||
.setMessage(R.string.app_manager_dialog_text)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
SimpleDialog<Unit>(this) {
|
||||
title(R.string.app_manager_dialog_title)
|
||||
message(R.string.app_manager_dialog_text)
|
||||
positive(R.string.ok) {
|
||||
try {
|
||||
for (intent in appManagerIntentList) {
|
||||
if (packageManager.resolveActivity(intent,
|
||||
@ -650,17 +640,17 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
try {
|
||||
startActivity(Intent(Settings.ACTION_SETTINGS))
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this, R.string.app_manager_open_failed, Toast.LENGTH_SHORT)
|
||||
Timber.e(e)
|
||||
Toast.makeText(this@MainActivity, R.string.app_manager_open_failed, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNeutralButton(R.string.dont_ask_again) { _, _ ->
|
||||
neutral(R.string.dont_ask_again) {
|
||||
app.config.sync.dontShowAppManagerDialog = true
|
||||
}
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
cancelable(false)
|
||||
}.show()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
@ -698,14 +688,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
|
||||
fun handleIntent(extras: Bundle?) {
|
||||
d(TAG, "handleIntent() {")
|
||||
extras?.keySet()?.forEach { key ->
|
||||
d(TAG, " \"$key\": " + extras.get(key))
|
||||
}
|
||||
d(TAG, "}")
|
||||
Timber.d("handleIntent() ${extras?.keySet()}")
|
||||
|
||||
val intentProfileId = extras.getIntOrNull("profileId").takePositive()
|
||||
var intentNavTarget = extras.getIntOrNull("fragmentId").asNavTargetOrNull()
|
||||
var intentNavTarget = extras.getEnum<NavTarget>("fragmentId")
|
||||
|
||||
if (extras?.containsKey("action") == true) {
|
||||
val handled = when (extras.getString("action")) {
|
||||
@ -808,7 +794,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
if (arguments != null)
|
||||
intent.putExtras(arguments)
|
||||
if (navTarget != null) {
|
||||
intent.putExtra("fragmentId", navTarget.id)
|
||||
intent.putExtras("fragmentId" to navTarget)
|
||||
}
|
||||
finish()
|
||||
overridePendingTransition(R.anim.fade_in, R.anim.fade_out)
|
||||
@ -816,33 +802,38 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
d(TAG, "Activity started")
|
||||
Timber.i("Activity started")
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
d(TAG, "Activity stopped")
|
||||
Timber.i("Activity stopped")
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
d(TAG, "Activity resumed")
|
||||
Timber.i("Activity resumed")
|
||||
val filter = IntentFilter()
|
||||
filter.addAction(Intent.ACTION_MAIN)
|
||||
registerReceiver(intentReceiver, filter)
|
||||
ContextCompat.registerReceiver(
|
||||
this,
|
||||
intentReceiver,
|
||||
filter,
|
||||
ContextCompat.RECEIVER_NOT_EXPORTED,
|
||||
)
|
||||
EventBus.getDefault().register(this)
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
d(TAG, "Activity paused")
|
||||
Timber.i("Activity paused")
|
||||
unregisterReceiver(intentReceiver)
|
||||
EventBus.getDefault().unregister(this)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
d(TAG, "Activity destroyed")
|
||||
Timber.i("Activity destroyed")
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@ -896,7 +887,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
args: Bundle? = null,
|
||||
skipBeforeNavigate: Boolean = false,
|
||||
): Boolean {
|
||||
d(TAG, "navigate(profileId = ${profile?.id ?: profileId}, target = ${navTarget?.name}, args = $args)")
|
||||
Timber.d("navigate(profileId = ${profile?.id ?: profileId}, target = ${navTarget?.name}, args = $args)")
|
||||
if (!(skipBeforeNavigate || navTarget == this.navTarget) && !canNavigate()) {
|
||||
bottomSheet.close()
|
||||
drawer.close()
|
||||
@ -929,7 +920,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
args: Bundle?,
|
||||
profileChanged: Boolean,
|
||||
) {
|
||||
d(TAG, "navigateImpl(profileId = ${profile.id}, target = ${navTarget.name}, args = $args)")
|
||||
Timber.d("navigateImpl(profileId = ${profile.id}, target = ${navTarget.name}, args = $args)")
|
||||
|
||||
if (navTarget.featureType != null && !profile.hasUIFeature(navTarget.featureType)) {
|
||||
navigateImpl(profile, NavTarget.HOME, args, profileChanged)
|
||||
@ -971,9 +962,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
val arguments = args
|
||||
?: navBackStack.firstOrNull { it.first == navTarget }?.second
|
||||
?: Bundle()
|
||||
swipeRefreshLayout.isEnabled = false
|
||||
bottomSheet.close()
|
||||
bottomSheet.removeAllContextual()
|
||||
bottomSheet.toggleGroupEnabled = false
|
||||
drawer.close()
|
||||
if (drawer.getSelection() != navTarget.id)
|
||||
drawer.setSelection(navTarget.id, fireOnClick = false)
|
||||
@ -982,9 +973,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
navView.bottomBar.fabExtended = false
|
||||
navView.bottomBar.setFabOnClickListener(null)
|
||||
|
||||
d("NavDebug", "Navigating from ${this.navTarget.name} to ${navTarget.name}")
|
||||
Timber.d("Navigating from ${this.navTarget.name} to ${navTarget.name}")
|
||||
|
||||
val fragment = navTarget.fragmentClass?.newInstance() ?: return
|
||||
val fragment = navTarget.fragmentClass?.getDeclaredConstructor()?.newInstance() ?: return
|
||||
fragment.arguments = arguments
|
||||
val transaction = fragmentManager.beginTransaction()
|
||||
|
||||
@ -1042,9 +1033,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
d("NavDebug", "Current fragment ${navTarget.name}, back stack:")
|
||||
Timber.d("Current fragment ${navTarget.name}, back stack:")
|
||||
navBackStack.forEachIndexed { index, item ->
|
||||
d("NavDebug", " - $index: ${item.first.name}")
|
||||
Timber.d(" - $index: ${item.first.name}")
|
||||
}
|
||||
|
||||
transaction.replace(R.id.fragment, fragment)
|
||||
@ -1052,7 +1043,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
|
||||
// TASK DESCRIPTION
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val bm = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)
|
||||
val bm = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher_v5)
|
||||
|
||||
@Suppress("deprecation")
|
||||
val taskDesc = ActivityManager.TaskDescription(
|
||||
@ -1061,7 +1052,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
else
|
||||
getString(R.string.app_task_format, getString(navTarget.nameRes)),
|
||||
bm,
|
||||
getColorFromAttr(this, R.attr.colorSurface)
|
||||
R.attr.colorPrimary.resolveAttr(this)
|
||||
)
|
||||
setTaskDescription(taskDesc)
|
||||
}
|
||||
@ -1105,9 +1096,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
fun gainAttention() {
|
||||
if (app.config.ui.bottomSheetOpened)
|
||||
return
|
||||
b.navView.postDelayed({
|
||||
navView.gainAttentionOnBottomBar()
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
fun gainAttentionFAB() {
|
||||
@ -1130,8 +1118,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
else
|
||||
BitmapDrawable.createFromPath(it)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,7 +1160,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
|
||||
fun setDrawerItems() {
|
||||
d("NavDebug", "setDrawerItems() app.profile = ${app.profile}")
|
||||
Timber.d("setDrawerItems() app.profile = ${app.profile}")
|
||||
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
||||
val drawerItemsMore = arrayListOf<IDrawerItem<*>>()
|
||||
val drawerItemsBottom = arrayListOf<IDrawerItem<*>>()
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-27.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.ext.takePositive
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
abstract class BaseConfig(
|
||||
@Transient
|
||||
val db: AppDb,
|
||||
val profileId: Int? = null,
|
||||
protected var entries: List<ConfigEntry>? = null,
|
||||
) : CoroutineScope {
|
||||
|
||||
private val job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Default
|
||||
|
||||
val values = hashMapOf<String, String?>()
|
||||
|
||||
init {
|
||||
if (entries == null)
|
||||
entries = db.configDao().getAllNow()
|
||||
values.clear()
|
||||
for ((profileId, key, value) in entries!!) {
|
||||
if (profileId.takePositive() != this.profileId)
|
||||
continue
|
||||
values[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
fun set(key: String, value: String?) {
|
||||
values[key] = value
|
||||
launch(Dispatchers.IO) {
|
||||
db.configDao().add(ConfigEntry(profileId ?: -1, key, value))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-26.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.BuildConfig
|
||||
import pl.szczodrzynski.edziennik.config.utils.*
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
class Config(db: AppDb) : BaseConfig(db) {
|
||||
companion object {
|
||||
const val DATA_VERSION = 12
|
||||
}
|
||||
|
||||
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
|
||||
|
||||
val ui by lazy { ConfigUI(this) }
|
||||
val sync by lazy { ConfigSync(this) }
|
||||
val timetable by lazy { ConfigTimetable(this) }
|
||||
val grades by lazy { ConfigGrades(this) }
|
||||
|
||||
var dataVersion by config<Int>(DATA_VERSION)
|
||||
var hash by config<String>("")
|
||||
|
||||
var lastProfileId by config<Int>(0)
|
||||
var loginFinished by config<Boolean>(false)
|
||||
var privacyPolicyAccepted by config<Boolean>(false)
|
||||
var update by config<Update?>(null)
|
||||
var updatesChannel by config<String>("release")
|
||||
|
||||
var devMode by config<Boolean?>("debugMode", null)
|
||||
var devModePassword by config<String?>(null)
|
||||
var enableChucker by config<Boolean?>(null)
|
||||
|
||||
var apiAvailabilityCheck by config<Boolean>(true)
|
||||
var apiInvalidCert by config<String?>(null)
|
||||
var apiKeyCustom by config<String?>(null)
|
||||
var appInstalledTime by config<Long>(0L)
|
||||
var appRateSnackbarTime by config<Long>(0L)
|
||||
var appVersion by config<Int>(BuildConfig.VERSION_CODE)
|
||||
var validation by config<String?>(null, "buildValidation")
|
||||
|
||||
var archiverEnabled by config<Boolean>(true)
|
||||
var runSync by config<Boolean>(false)
|
||||
var widgetConfigs by config<JsonObject> { JsonObject() }
|
||||
|
||||
fun migrate(app: App) {
|
||||
if (dataVersion < DATA_VERSION || hash == "")
|
||||
// migrate old data version OR freshly installed app (or updated from 3.x)
|
||||
ConfigMigration(app, this)
|
||||
}
|
||||
|
||||
operator fun get(profileId: Int): ProfileConfig {
|
||||
return profileConfigs[profileId] ?: ProfileConfig(db, profileId, entries).also {
|
||||
profileConfigs[profileId] = it
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-26.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
class ConfigGrades(base: Config) {
|
||||
|
||||
var orderBy by base.config<Int>("gradesOrderBy", ORDER_BY_DATE_DESC)
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-26.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import pl.szczodrzynski.edziennik.BuildConfig
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
|
||||
import pl.szczodrzynski.edziennik.ext.HOUR
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
class ConfigSync(base: Config) {
|
||||
|
||||
var enabled by base.config<Boolean>("syncEnabled", true)
|
||||
var interval by base.config<Int>("syncInterval", 1 * HOUR.toInt())
|
||||
var onlyWifi by base.config<Boolean>("syncOnlyWifi", false)
|
||||
|
||||
var dontShowAppManagerDialog by base.config<Boolean>(false)
|
||||
var lastAppSync by base.config<Long>(0L)
|
||||
var notifyAboutUpdates by base.config<Boolean>(true)
|
||||
var webPushEnabled by base.config<Boolean>(true)
|
||||
|
||||
// Quiet Hours
|
||||
var quietHoursEnabled by base.config<Boolean>(false)
|
||||
var quietHoursStart by base.config<Time?>(null)
|
||||
var quietHoursEnd by base.config<Time?>(null)
|
||||
var quietDuringLessons by base.config<Boolean>(false)
|
||||
|
||||
// FCM Tokens
|
||||
var tokenApp by base.config<String?>(null)
|
||||
var tokenMobidziennik by base.config<String?>(null)
|
||||
var tokenLibrus by base.config<String?>(null)
|
||||
var tokenVulcan by base.config<String?>(null)
|
||||
var tokenVulcanHebe by base.config<String?>(null)
|
||||
|
||||
var tokenMobidziennikList by base.config<List<Int>> { listOf() }
|
||||
var tokenLibrusList by base.config<List<Int>> { listOf() }
|
||||
var tokenVulcanList by base.config<List<Int>> { listOf() }
|
||||
var tokenVulcanHebeList by base.config<List<Int>> { listOf() }
|
||||
|
||||
// Register Availability
|
||||
private var registerAvailabilityMap by base.config<Map<String, RegisterAvailabilityStatus>>("registerAvailability") { mapOf() }
|
||||
private var registerAvailabilityFlavor by base.config<String?>(null)
|
||||
|
||||
var registerAvailability: Map<String, RegisterAvailabilityStatus>
|
||||
get() {
|
||||
if (BuildConfig.FLAVOR != registerAvailabilityFlavor)
|
||||
return mapOf()
|
||||
return registerAvailabilityMap
|
||||
}
|
||||
set(value) {
|
||||
registerAvailabilityMap = value
|
||||
registerAvailabilityFlavor = BuildConfig.FLAVOR
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-26.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
@Suppress("RemoveExplicitTypeArguments")
|
||||
class ConfigTimetable(base: Config) {
|
||||
|
||||
var bellSyncMultiplier by base.config<Int>(0)
|
||||
var bellSyncDiff by base.config<Time?>(null)
|
||||
var countInSeconds by base.config<Boolean>(false)
|
||||
}
|