Compare commits

..

14 Commits

Author SHA1 Message Date
3947c5ccd2 feat: pwa 2024-12-05 09:36:51 +00:00
Rainer Killinger
4c9d330c88 fix: update jsonpath-plus depenency 2024-12-02 11:08:58 +01:00
Thea Schöbl
580ebee362 fix: user gets logged out when their token expires
Closes #230
2024-11-28 18:04:08 +00:00
Rainer Killinger
07e5c80223 docs: update changelogs for release
ci: publish release
2024-11-05 11:40:19 +01:00
Jovan Krunić
2ac840d845 fix: observable immediately returns false if scheduled beyond max delay
Closes #229
2024-11-04 18:04:48 +01:00
Thea Schöbl
8b581ef9ca feat: rework about pages changelog 2024-11-04 07:50:47 +00:00
Rainer Killinger
e2d5d4f187 docs: update changelogs for release
ci: publish release
2024-10-18 16:52:57 +02:00
Rainer Killinger
496b50d892 fix: update jsonpath-plus depenency 2024-10-18 16:12:29 +02:00
e6c17c860b fix: id cards are wiped/replaced when an error happens in the pipe 2024-10-11 15:33:03 +02:00
Jovan Krunić
bb1f596bfc fix: enable starting the app without backend
Closes #223
2024-09-30 11:03:53 +00:00
0c49fd8c34 refactor: update nix dependencies 2024-09-30 13:00:59 +02:00
Thea Schöbl
ce5016a992 fix: text of the feedback form not fully visible
Closes #227
2024-09-18 09:53:50 +00:00
3ac8c04765 fix: date range is now pipe has issues around boundaries 2024-08-06 17:43:59 +02:00
Rainer Killinger
5c260dd26b refactor: update android build dependencies for API level 34 2024-08-05 12:51:47 +00:00
68 changed files with 4861 additions and 2744 deletions

View File

@@ -0,0 +1,5 @@
---
"@openstapps/app": patch
---
fix user logout when token expires

142
flake.nix
View File

@@ -4,68 +4,86 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { outputs =
self, {
nixpkgs, self,
flake-utils, nixpkgs,
}: let flake-utils,
aapt2buildToolsVersion = "33.0.2"; }:
in let
flake-utils.lib.eachDefaultSystem (system: let aapt2buildToolsVersion = "33.0.2";
pkgs = import nixpkgs { in
inherit system; flake-utils.lib.eachDefaultSystem (
overlays = [ system:
(final: prev: rec { let
fontMin = prev.python311.withPackages (ps: with ps; [brotli fonttools] ++ (with fonttools.optional-dependencies; [woff])); pkgs = import nixpkgs {
android = prev.androidenv.composeAndroidPackages { inherit system;
buildToolsVersions = ["30.0.3" aapt2buildToolsVersion]; overlays = [
platformVersions = ["33"]; (final: prev: rec {
}; fontMin = prev.python311.withPackages (
cypress = prev.cypress.overrideAttrs (cyPrev: rec { ps:
version = "13.2.0"; with ps;
src = prev.fetchzip { [
url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip"; brotli
hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM="; fonttools
]
++ (with fonttools.optional-dependencies; [ woff ])
);
android = prev.androidenv.composeAndroidPackages {
buildToolsVersions = [
"34.0.0"
aapt2buildToolsVersion
];
platformVersions = [ "34" ];
}; };
}); cypress = prev.cypress.overrideAttrs (cyPrev: rec {
nodejs = prev.nodejs_18; version = "13.2.0";
}) src = prev.fetchzip {
]; url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip";
config = { hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM=";
allowUnfree = true; };
android_sdk.accept_license = true; });
nodejs = prev.nodejs_18;
corepack = prev.corepack_18;
})
];
config = {
allowUnfree = true;
android_sdk.accept_license = true;
};
}; };
}; androidFhs = pkgs.buildFHSUserEnv {
androidFhs = pkgs.buildFHSUserEnv { name = "android-env";
name = "android-env"; targetPkgs = pkgs: with pkgs; [ ];
targetPkgs = pkgs: with pkgs; []; runScript = "bash";
runScript = "bash"; profile = ''
profile = '' export ALLOW_NINJA_ENV=true
export ALLOW_NINJA_ENV=true export USE_CCACHE=1
export USE_CCACHE=1 export LD_LIBRARY_PATH=/usr/lib:/usr/lib32
export LD_LIBRARY_PATH=/usr/lib:/usr/lib32 '';
''; };
}; in
in { {
devShell = pkgs.mkShell rec { devShell = pkgs.mkShell rec {
nativeBuildInputs = [androidFhs]; nativeBuildInputs = [ androidFhs ];
buildInputs = with pkgs; [ buildInputs = with pkgs; [
nodejs nodejs
corepack corepack
# tools # tools
curl curl
jq jq
fontMin fontMin
cypress cypress
# android # android
jdk17 jdk17
android.androidsdk android.androidsdk
]; ];
ANDROID_JAVA_HOME = "${pkgs.jdk.home}"; ANDROID_JAVA_HOME = "${pkgs.jdk.home}";
ANDROID_SDK_ROOT = "${pkgs.android.androidsdk}/libexec/android-sdk"; ANDROID_SDK_ROOT = "${pkgs.android.androidsdk}/libexec/android-sdk";
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${aapt2buildToolsVersion}/aapt2"; GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${aapt2buildToolsVersion}/aapt2";
CYPRESS_INSTALL_BINARY = "0"; CYPRESS_INSTALL_BINARY = "0";
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress"; CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
}; };
}); }
);
} }

View File

@@ -1,5 +1,17 @@
# @openstapps/app # @openstapps/app
## 3.3.4
### Minor Changes
- 8b581ef9: Use user facing changelogs in the about pages as the primary source, with the technical changes accessible through a sub menu.
## 3.3.3
### Patch Changes
- 496b50d8: Bug fixes and Android target sdk version is now 34
## 3.3.2 ## 3.3.2
### Patch Changes ### Patch Changes
@@ -316,3 +328,225 @@
- Updated dependencies [64caebaf] - Updated dependencies [64caebaf]
- @openstapps/api@3.0.0-next.0 - @openstapps/api@3.0.0-next.0
- @openstapps/core@3.0.0-next.0 - @openstapps/core@3.0.0-next.0
## 2.1.1
### Bug Fixes
- autofocus searchbar only when no default data is displayed ([e90286f](https://gitlab.com/openstapps/app/commit/e90286fc6814f5c40af3e297be42f23128b991be))
- breadcrumbs are under parallax ([9e160e8](https://gitlab.com/openstapps/app/commit/9e160e8d1ee9409e4fbe518c9dd9748705e680e1))
- browser logout only if endSession url defined ([7f6de94](https://gitlab.com/openstapps/app/commit/7f6de94ab572be66d7f10758c37dcf10af46b4e0)), closes [#395](https://gitlab.com/openstapps/app/issues/395)
- can't select some list elements on safari 16.4 ([3e99d7f](https://gitlab.com/openstapps/app/commit/3e99d7fa8fcae4538e1afe6a017570b0cb6ff45e))
- canteen view removes item select listener on view exit ([05e996a](https://gitlab.com/openstapps/app/commit/05e996ae9052b11c23dc1093ef526f08e3e2e6b6))
- catalog module semester selection ([afbd1fc](https://gitlab.com/openstapps/app/commit/afbd1fc048997acbc0113f8957016f8947b58626))
- catalog semester selection ([a8c7d5a](https://gitlab.com/openstapps/app/commit/a8c7d5ab5934adf853cc40c1df311178df54057e))
- data detail local favorite fallback causing duplicate nested favorite view ([dff4a95](https://gitlab.com/openstapps/app/commit/dff4a95acc55574b4872b0e4e39555cce0b2fd60))
- data-detail favorite button color leaking to list items ([95f2da2](https://gitlab.com/openstapps/app/commit/95f2da2def39ec56f40a660a63e5f7fddb4b3d53))
- location flow on iOS devices ([f207e02](https://gitlab.com/openstapps/app/commit/f207e029f1b30624bf411a57b3c552ef259e13ed))
- parallax broken since safari 16.4 ([0f970fa](https://gitlab.com/openstapps/app/commit/0f970fa1f164a310e24a85140d8bf0da21e5a5f1))
- remove infinite scroll e2e test ([47565e5](https://gitlab.com/openstapps/app/commit/47565e51b0dda5c8227238b6dc19f0d277408429))
- replace breadcrumb popover with simply expanding the breadcrumbs ([1318cbc](https://gitlab.com/openstapps/app/commit/1318cbca7f0cf72e10d96fff1a1116ba073fe8dc))
- schedule tabs navigating to the wrong url ([abf2ab6](https://gitlab.com/openstapps/app/commit/abf2ab6a5a94941d439adf54ec677332823892db))
- translate simple pipe doesn't update on language changes ([f5ca150](https://gitlab.com/openstapps/app/commit/f5ca1508fb9d95693615bfb9e03bc127bd83be00))
- typo in catalog provider query ([f49c44f](https://gitlab.com/openstapps/app/commit/f49c44f5c53780e4794dc1ef4cbacfb20cabbd97))
- workaround for side menu items not being active on page load ([947cab4](https://gitlab.com/openstapps/app/commit/947cab458ca770f116d28a1f22687ae620e71b59))
### Features
- add content to empty catalogs ([982fb16](https://gitlab.com/openstapps/app/commit/982fb1653b3c1253aac9366733f14c22c94d2537))
- add easy way to configure search filtering for nested properties ([2220ab2](https://gitlab.com/openstapps/app/commit/2220ab24b385188515da7c176bf9c1ac72651fd9))
- dark theme ([e75a466](https://gitlab.com/openstapps/app/commit/e75a46633ca3685d6044eb9a8b2fd670f2cd030f))
- dashboard search rework ([8c30a47](https://gitlab.com/openstapps/app/commit/8c30a47706f07eb222fac47ad7fed61f9044328a))
- implement custom cdk virtual scroll behavior ([968cb72](https://gitlab.com/openstapps/app/commit/968cb729575c529fd6d1d35da1b50a8689057c46))
- optional logout from identity provider ([8cd2d77](https://gitlab.com/openstapps/app/commit/8cd2d777ab3a67b1ab24f03aa50a3ff73550c3d2)), closes [#372](https://gitlab.com/openstapps/app/issues/372)
- revamp dashboard mensa section ([33a74d9](https://gitlab.com/openstapps/app/commit/33a74d96ae92137f53a775e90bff99e5f2d41f6a))
- rework settings page design ([2f1298c](https://gitlab.com/openstapps/app/commit/2f1298c9d7df25d2a16576245ea62c1b6094e507))
- show in-place in date series modal, resolves [#385](https://gitlab.com/openstapps/app/issues/385) ([22e70ae](https://gitlab.com/openstapps/app/commit/22e70ae92b35578b559e6644dccb8d4bfd06af1e)), closes [#386](https://gitlab.com/openstapps/app/issues/386) [#388](https://gitlab.com/openstapps/app/issues/388)
- transition to full sidebar at xl instead of lg ([cc939f3](https://gitlab.com/openstapps/app/commit/cc939f38873833b7cc0260525a2ecd536f27bfa5))
## 2.0.1
### Bug Fixes
- assessment segments can become unreadable ([939fb6e](https://gitlab.com/openstapps/app/commit/939fb6ef0f11b40cb71fbe61da90f50b1f75c3f7))
- login button not easily found ([11d1ac3](https://gitlab.com/openstapps/app/commit/11d1ac3f7ce27c2822ea8f839df3f3dffbd6c020))
- remove misleading assessment calculations ([aefae33](https://gitlab.com/openstapps/app/commit/aefae33d5c9fa9ee3efe346e45429aca79ae3c48))
- right-align add event detail chip ([1eee652](https://gitlab.com/openstapps/app/commit/1eee652533c6b8f613ce09df9c3421f89209419a))
### Features
- offline notice ([9b4caf5](https://gitlab.com/openstapps/app/commit/9b4caf526ffb53ec8d8885342323fcc52fd9fc09))
- separate prettier from eslint ([a88d000](https://gitlab.com/openstapps/app/commit/a88d000ccd6cbdeb5fbb07d209f2491023f9d76c))
# 2.0.0
### Bug Fixes
- daia_url missing in environment configs ([863a3ff](https://gitlab.com/openstapps/app/commit/863a3ffd488425e3313ab9b812c4b6d50c68a244))
- 404 on all surge links ([f1b4930](https://gitlab.com/openstapps/app/commit/f1b4930a3068e73aee20b4c3d71dac551ab60c35))
- add areaServed to person detail ([488150f](https://gitlab.com/openstapps/app/commit/488150f7f5558c05c1ec8a71afcb9f9a37e68a37))
- add event popover expanding beyond screen width ([046a95b](https://gitlab.com/openstapps/app/commit/046a95ba1dca3f5ded7e5555d3167f52f95be107))
- add location info to dates from timetable ([92adb9d](https://gitlab.com/openstapps/app/commit/92adb9dd2db18027dcc327433027e28c81ecbd4b)), closes [#344](https://gitlab.com/openstapps/app/issues/344)
- add missing profile translation ([cdb6ac4](https://gitlab.com/openstapps/app/commit/cdb6ac4084f8704d7f2336387a837b86f78c062b))
- add nav button to schedule page ([e628f39](https://gitlab.com/openstapps/app/commit/e628f396e22e51da2c9f2489fe89e42ccf474e2b))
- add openingHours config and catch its errors ([6125d43](https://gitlab.com/openstapps/app/commit/6125d43e8c18f2bf2afda67c0ff72e00d98ab34f))
- add PKCE parameters for PAIA auth ([f3e83bf](https://gitlab.com/openstapps/app/commit/f3e83bfcc88423f0935a060ccd0bf6198da58351))
- address late init from ionic components ([0bce9e5](https://gitlab.com/openstapps/app/commit/0bce9e5452fc5d05123756348dc30308de675bfa))
- adjust code to overcome the breaking changes (ionic 4 to 5) ([f779042](https://gitlab.com/openstapps/app/commit/f7790426cd2da4a6b33e2aa73783943f45b3de02)), closes [#70](https://gitlab.com/openstapps/app/issues/70)
- adjust hebis catalog templates ([83d9a4a](https://gitlab.com/openstapps/app/commit/83d9a4a8b8fe5b8687c72a717b3a2964524006e0))
- adjust library account user info ([bafabb1](https://gitlab.com/openstapps/app/commit/bafabb1d4ec299e2bea43cd4b8442ef33be2329a)), closes [#331](https://gitlab.com/openstapps/app/issues/331)
- adjust npm docker scripts and typos ([82bb15b](https://gitlab.com/openstapps/app/commit/82bb15b863e2d2e4df20244fda2f2e0d049ff43f))
- angular1 ng-if leftover ([25434d5](https://gitlab.com/openstapps/app/commit/25434d54e3800fd72a6c5d9188fb11f441d73aa9))
- assign navigation app name dynamically ([90b9733](https://gitlab.com/openstapps/app/commit/90b97339d3948b0864f634519416fe4a458b459f))
- background fetch crashing android app ([3316ad9](https://gitlab.com/openstapps/app/commit/3316ad9169ed2b29a2755405589213f824aec9d1))
- calculating SCDateSeries for next unit view ([82ba5f8](https://gitlab.com/openstapps/app/commit/82ba5f81211fb10cc5fde04991856567c4ac9680))
- canteen module layout ([b89f5c4](https://gitlab.com/openstapps/app/commit/b89f5c4edd1ed14f7529edc4e4ea54f9d98fda7c))
- canteen module layout ([6f7c680](https://gitlab.com/openstapps/app/commit/6f7c680ed89f027d863ebc02f5b24895d84f32e4))
- cards not having rounded corners in safari ([8a04a43](https://gitlab.com/openstapps/app/commit/8a04a439032920ead799f8b7483f29b896797c37))
- catch error `Setting "language" not provided` ([584878d](https://gitlab.com/openstapps/app/commit/584878d9503b8406b6ee7ec69dde5b8b3c4fd954))
- CI stage/job setup ([ae429ca](https://gitlab.com/openstapps/app/commit/ae429ca5fb3b5f10cad377d37b251806b3dabf6c))
- config.get issue by updating ionic ([9386351](https://gitlab.com/openstapps/app/commit/93863510fac32ed5b887011175a4807df3f522b8))
- **config:** fix catch ConfigFetchError in getValue ([161da63](https://gitlab.com/openstapps/app/commit/161da630ea59f6205ee53dece950972d4f36ada5)), closes [#46](https://gitlab.com/openstapps/app/issues/46)
- correct data path color ([0d755bc](https://gitlab.com/openstapps/app/commit/0d755bcbd3d6fea59a4f7a59981fd28844ff90d5))
- correct html whitespace handling for icon detection ([9bc3642](https://gitlab.com/openstapps/app/commit/9bc3642990b687dd524470fd26df80351aa85f1e))
- daia availability ([13cee2d](https://gitlab.com/openstapps/app/commit/13cee2d4261c7301c1c763446ae44dcdd005172d))
- dashboard next unit structural directive causing animation issues ([c8f6a27](https://gitlab.com/openstapps/app/commit/c8f6a27c571e51bcc0ac0120968e6bc9a20c8dd7))
- **data:** fix and adjust detail test using translation ([478f49a](https://gitlab.com/openstapps/app/commit/478f49a8744211b3c9458b3dadc791d62a46ae46)), closes [#50](https://gitlab.com/openstapps/app/issues/50)
- **data:** fix template and other consistency issues ([c3bc227](https://gitlab.com/openstapps/app/commit/c3bc227a3ca4a295b2b31bfe7fd34830b33c9f05))
- detail page when dish of mensa selected ([e5c2270](https://gitlab.com/openstapps/app/commit/e5c227073a183a1c562e17f3fe14a51048d01637)), closes [#140](https://gitlab.com/openstapps/app/issues/140)
- download events should respect selection ([28fbfef](https://gitlab.com/openstapps/app/commit/28fbfef18cc3b457f7020a70157ea7a4fff345d0))
- enable background fetch on iOS ([a1592f8](https://gitlab.com/openstapps/app/commit/a1592f84cc48f7cae8c55ef806cddbe806034bb5))
- enable overflow for day labels in schedule ([1195c5f](https://gitlab.com/openstapps/app/commit/1195c5ffc8cea07f1e224d92a7fb25aa5858bf0a))
- encode URI parameter to proxy URI ([bc13cc5](https://gitlab.com/openstapps/app/commit/bc13cc5e1fe6144fe0a0e53c0748a154844a5c29)), closes [#326](https://gitlab.com/openstapps/app/issues/326)
- extend landing period button not working on android ([0caa69c](https://gitlab.com/openstapps/app/commit/0caa69c28cbb2f962b70a1da13659739c1c6dd3e)), closes [#333](https://gitlab.com/openstapps/app/issues/333)
- failing native http requests with body ([fed4f20](https://gitlab.com/openstapps/app/commit/fed4f20c3cf43221512f3d2b6dd3c3fe7a4cf43a))
- feedback not allowing valid emails ([cf74c8e](https://gitlab.com/openstapps/app/commit/cf74c8e19f8bd34a31d5af931781e84be2c04dea)), closes [#349](https://gitlab.com/openstapps/app/issues/349)
- fix issues found by ng build for production ([a503811](https://gitlab.com/openstapps/app/commit/a503811c1cfcf909571af766ccd884856aad8ec9)), closes [#48](https://gitlab.com/openstapps/app/issues/48)
- fix various typos ([ad0dae4](https://gitlab.com/openstapps/app/commit/ad0dae46ff04d28551d2ece950d9a4d3442541d2))
- fixate webdriver to match used chrome version ([24dbb42](https://gitlab.com/openstapps/app/commit/24dbb42b345458b7dbdd17b2759824b3b68cb0e4))
- generate library online links properly ([9854541](https://gitlab.com/openstapps/app/commit/9854541a0c062c31bce167673586dccc8af81785)), closes [#340](https://gitlab.com/openstapps/app/issues/340)
- handle prices as an optional property ([9e71efc](https://gitlab.com/openstapps/app/commit/9e71efca9f7b1086db26f580192d6b349bdcb964)), closes [#219](https://gitlab.com/openstapps/app/issues/219)
- header logo changing size on ios navigate ([38f0a30](https://gitlab.com/openstapps/app/commit/38f0a300769a5b7cda35af0927c17099f93981b8))
- ignore null-island location ([d3188f5](https://gitlab.com/openstapps/app/commit/d3188f50905d610097de6c90bc58e6373d30e0dc)), closes [#149](https://gitlab.com/openstapps/app/issues/149)
- item not available in offer template ([7b402d6](https://gitlab.com/openstapps/app/commit/7b402d61c30aed81a5671d778a38c8393a5bc7c8)), closes [#110](https://gitlab.com/openstapps/app/issues/110)
- library account missing ready for pickup ([e504d8c](https://gitlab.com/openstapps/app/commit/e504d8cf6dd1c12fcb8f6a315527337313662385)), closes [#330](https://gitlab.com/openstapps/app/issues/330)
- library fines should load item title only if needed ([cbb949e](https://gitlab.com/openstapps/app/commit/cbb949e3977a5821e6bd1b654dec66a82e4d8c81)), closes [#342](https://gitlab.com/openstapps/app/issues/342)
- links of timetable tabs ([837c69b](https://gitlab.com/openstapps/app/commit/837c69bb21c92a91259051d5680e1073b390fc0e)), closes [#144](https://gitlab.com/openstapps/app/issues/144)
- logged out button not showing on profile ([ebdc14d](https://gitlab.com/openstapps/app/commit/ebdc14d3c398ac7564c077757c564f4e414fe244)), closes [#239](https://gitlab.com/openstapps/app/issues/239)
- make action chips react to changes of their item ([c0d0b1b](https://gitlab.com/openstapps/app/commit/c0d0b1bd9934e8d9e23f47825cae6a5d8ea2f38a))
- make keyboard dismissable on mobile devices ([b2cc1fd](https://gitlab.com/openstapps/app/commit/b2cc1fd91fc5bd66c994dcbe10771a22d91a1b3e))
- map search on iOS ([7d449b4](https://gitlab.com/openstapps/app/commit/7d449b43d0d86825f711848110ac6f044084eba0)), closes [#148](https://gitlab.com/openstapps/app/issues/148)
- map widget not loading tiles properly ([09aa7bb](https://gitlab.com/openstapps/app/commit/09aa7bb5c59e8d167fa91c69745f5f80229094d7)), closes [#127](https://gitlab.com/openstapps/app/issues/127)
- missing init (config setup) in default auth service ([f16e539](https://gitlab.com/openstapps/app/commit/f16e5394cce5a8019f4dfe367e5e0a2f0cca4ce2)), closes [#227](https://gitlab.com/openstapps/app/issues/227)
- missing translations ([30d801a](https://gitlab.com/openstapps/app/commit/30d801a3b419b382d40d96dda995bd35e493523d))
- modals not reacting after several uses ([f39c29f](https://gitlab.com/openstapps/app/commit/f39c29f10bc05ab986b74dfa8a8648df5fb307b4))
- news module not scrollable on large screens ([44b6a4a](https://gitlab.com/openstapps/app/commit/44b6a4aea008ca6c89f6cb289467429fb3f8c1fa))
- ngx-translate defaultLanguage not set ([581a5b2](https://gitlab.com/openstapps/app/commit/581a5b2e55ceda99cf7c41200366c3c5e09f1c63))
- omit sync native calendar when no uuids ([c9720dc](https://gitlab.com/openstapps/app/commit/c9720dc104cce78ae1a422d5efed7b8a58946836)), closes [#177](https://gitlab.com/openstapps/app/issues/177)
- opening hours pipe refreshing too often ([95e1734](https://gitlab.com/openstapps/app/commit/95e1734d26b175d8d1156abb10863155fed89ec0))
- overhaul auth to avoid issues ([99e8d6c](https://gitlab.com/openstapps/app/commit/99e8d6c9bcbc68b639b035af36bc05de0237b1f9)), closes [#336](https://gitlab.com/openstapps/app/issues/336)
- overview search bar scrolling behind header ([a037090](https://gitlab.com/openstapps/app/commit/a037090eec06e867a703b88a43620a74770287fe))
- performance degradation when scrolling ([f0a45d1](https://gitlab.com/openstapps/app/commit/f0a45d1b8eb2b33a6c68b94ed7f96f81db3a728b))
- person list should use long-inline-text ([8b2b853](https://gitlab.com/openstapps/app/commit/8b2b853942ac76904ff49d940dfef625b0397150))
- prevent multiple heavy setting inits ([f772637](https://gitlab.com/openstapps/app/commit/f7726378f443d9809a6174411d25a811e1d0b5e9))
- prevent opening invalid links ([fdee2db](https://gitlab.com/openstapps/app/commit/fdee2db8a42b8f6c99c4a72b3104ae0ba1a41c5a)), closes [#328](https://gitlab.com/openstapps/app/issues/328)
- profile module items show click effect on scroll ([8b2f2c0](https://gitlab.com/openstapps/app/commit/8b2f2c063c65278580d9469b00d9e67f01caaffb))
- recurring schedule offset and event limit ([9c6b513](https://gitlab.com/openstapps/app/commit/9c6b5131cd4cadb2572769d368b346054f19de1c))
- refresh token not used by default auth provider ([15ccbe4](https://gitlab.com/openstapps/app/commit/15ccbe4c1879417f2fc5849204fa9f6bdcce87fc)), closes [#311](https://gitlab.com/openstapps/app/issues/311)
- remove "extend landing" button when renewal not possible ([f60a228](https://gitlab.com/openstapps/app/commit/f60a22839200019a38586a14a0cce32e2c0029e7)), closes [#338](https://gitlab.com/openstapps/app/issues/338)
- remove item before adding it to secure storage ([ec511fb](https://gitlab.com/openstapps/app/commit/ec511fb8f40219e2559b08c62bd915d773d2a36f))
- schedule navigation bar layout ([e7d5f83](https://gitlab.com/openstapps/app/commit/e7d5f83100f43564b55249909a6658e583e3a9b2))
- set android status bar color correctly ([b38a969](https://gitlab.com/openstapps/app/commit/b38a96996a10e4e43ff1b06ecd2235a0e3bdfa1c))
- setting of default language ([ccf8b1a](https://gitlab.com/openstapps/app/commit/ccf8b1a5cc9fe834ba3e04a1ed67b2d082004403))
- show nothing for empty array properties ([1c56c89](https://gitlab.com/openstapps/app/commit/1c56c891e15b034826b5d6b2b35141fc872c922d)), closes [#154](https://gitlab.com/openstapps/app/issues/154)
- single map place width ([88684f0](https://gitlab.com/openstapps/app/commit/88684f068ab130f43e520c87f1d7383e0ae43944)), closes [#147](https://gitlab.com/openstapps/app/issues/147)
- some android devices don't support implied css animation units ([54cc883](https://gitlab.com/openstapps/app/commit/54cc8838aefe8f8c2d25d9228a136ef727a08230))
- status bar being black on Android 13 devices ([feee9e8](https://gitlab.com/openstapps/app/commit/feee9e8db90e66cf2346f7c5cc24f075eb70676c))
- suppress router event logs in console ([28caaf1](https://gitlab.com/openstapps/app/commit/28caaf1d21f7961b678cf339a712abf860ade5e7)), closes [#207](https://gitlab.com/openstapps/app/issues/207)
- swap missing icon after ionic update ([643b6c9](https://gitlab.com/openstapps/app/commit/643b6c967f3268cb305a24d614c3bc91275b0ac3))
- temporary disable flaky ui test ([6b9b1fa](https://gitlab.com/openstapps/app/commit/6b9b1fa8548d5c5fca04b2c1d63e893de39278a2))
- timetable dates cannot be removed ([9242438](https://gitlab.com/openstapps/app/commit/924243813207fa791d3c4938f8653a999b6382ff))
- translate back button title ([b8db0f3](https://gitlab.com/openstapps/app/commit/b8db0f3e70a46f2b493e183a244cb29d1954c257))
- translations ([5e1a902](https://gitlab.com/openstapps/app/commit/5e1a902d4c0d2345f21500fba5394c1907e04eb8))
- typo in translation ([7928534](https://gitlab.com/openstapps/app/commit/7928534d88a26db28b098bbceb47bc1103022a57))
- update core and apply stricter tslint rules ([911492d](https://gitlab.com/openstapps/app/commit/911492d064ff0280dd6626244cd8038cbfc0f408))
- use HashLocationStrategy for routes ([9d68212](https://gitlab.com/openstapps/app/commit/9d682125db55c87cab2b33c7633bfa133d2fc5a9)), closes [#54](https://gitlab.com/openstapps/app/issues/54)
- use localized date and time ([6ca0b97](https://gitlab.com/openstapps/app/commit/6ca0b9763761c5204a757a243056a087c5f35fd9))
- use stapps core version to compare with backends' core version ([66b8720](https://gitlab.com/openstapps/app/commit/66b8720da0f264824a396f2d9e598b0e48c8e3d1)), closes [#77](https://gitlab.com/openstapps/app/issues/77)
- user info card ([998edcb](https://gitlab.com/openstapps/app/commit/998edcb5cdfb588c2986f466f4a2951f172a8bb4)), closes [#305](https://gitlab.com/openstapps/app/issues/305)
### Features
- add "no results" screen to search ([c75ca68](https://gitlab.com/openstapps/app/commit/c75ca68c440a20e197213ecbb47d05fc293afd9c))
- add about module ([d420008](https://gitlab.com/openstapps/app/commit/d42000892694f4a3b29fa623c43fb45f8ba54687))
- add action chips to search results ([67fb4a4](https://gitlab.com/openstapps/app/commit/67fb4a43c95043caba50d43ace2ab276f3319b81))
- add auth support (default and paia) ([b5f239e](https://gitlab.com/openstapps/app/commit/b5f239ea4edebd0d27b1cdaad4a830998ce2f681))
- add backend toggle ([c1d3330](https://gitlab.com/openstapps/app/commit/c1d33303aa11da3b3e150c6717d77ef484a16ac1))
- add basic templates for data list items ([3e697b1](https://gitlab.com/openstapps/app/commit/3e697b17b4448c15781d0f6dd55577b638e9d974))
- add catalog module ([03084b1](https://gitlab.com/openstapps/app/commit/03084b1c966de98b3723d0bee2b2475589393c59))
- add ConfigModule and FakeBackendInterceptor ([406f400](https://gitlab.com/openstapps/app/commit/406f40055567bfde4ec5edf26cff942411bd073e)), closes [#34](https://gitlab.com/openstapps/app/issues/34) [#37](https://gitlab.com/openstapps/app/issues/37)
- add detail view for news ([2566a71](https://gitlab.com/openstapps/app/commit/2566a71a81a3408dbb16b97d3a453d95e25d1f00))
- add duration pipe with frequency capabilites ([49a1758](https://gitlab.com/openstapps/app/commit/49a1758da358958ffe590700c19aaf90ec748ee5))
- add favorites support ([e9452d6](https://gitlab.com/openstapps/app/commit/e9452d6520c34f6513623c16e291dc23d6ea9757))
- add feedback module ([867f9e9](https://gitlab.com/openstapps/app/commit/867f9e9b832e3bd54c04801fef63a11543e8f3dd))
- add filter chips for news ([5435f85](https://gitlab.com/openstapps/app/commit/5435f85cc43dc3baa774a5008d2920ac7b3783f6))
- add formatting pipes basted on Intl ([4b932af](https://gitlab.com/openstapps/app/commit/4b932af1c07e1af4369414667a987d31181c073c))
- add HeBIS HDS search ([9a3241c](https://gitlab.com/openstapps/app/commit/9a3241c42ab59e15c0084178f76dc4a2450a2bb8))
- add library account screens ([080e6fa](https://gitlab.com/openstapps/app/commit/080e6fa3e8c18e9608d7fa2efc95e4fd65c43a15))
- add library action confirmations ([42b860e](https://gitlab.com/openstapps/app/commit/42b860e41793fc3983a39237a4f7128416485fae)), closes [#334](https://gitlab.com/openstapps/app/issues/334)
- add logger ([a0c798f](https://gitlab.com/openstapps/app/commit/a0c798f765d87c5eebcbed65b70f3b05f285d0ce))
- add map module ([c1c9a92](https://gitlab.com/openstapps/app/commit/c1c9a92ec900403218b887fdebfe5132b232e1e0))
- add new font and new icons ([915fd72](https://gitlab.com/openstapps/app/commit/915fd72bd4bfed16e15fcc3c57879db0ec0379e2))
- add not found screen ([e3d9ef4](https://gitlab.com/openstapps/app/commit/e3d9ef40ccd626c81c67ea2d790eecbe6e025780))
- add permission check for geoLocation setting ([d5fa2fd](https://gitlab.com/openstapps/app/commit/d5fa2fd9a578d48cd2513eeb1380f1d2bc4d3754))
- add service and pipe for core translator ([4565600](https://gitlab.com/openstapps/app/commit/456560026cc9550a10a9f42657d942122be34d53))
- apply new layout overhaul ([7bbdba5](https://gitlab.com/openstapps/app/commit/7bbdba5c0b886e2789d2a603c4be627dfd16b60e))
- assessment tree view ([0b037f9](https://gitlab.com/openstapps/app/commit/0b037f96e634b412fbaaee24747df08afdc0e565))
- assessments module ([e68d1b7](https://gitlab.com/openstapps/app/commit/e68d1b73f94b36abcefe9b2bf42e98de00b69188))
- calendar plugin ([a57c302](https://gitlab.com/openstapps/app/commit/a57c3029df61ac3157c856744380a85dc001abc6))
- dashboard ui tests ([9f8ab5c](https://gitlab.com/openstapps/app/commit/9f8ab5c7a15a918f7bd05423f0a43f22a33d9228))
- **data:** add basic methods of data provider ([ffe05e4](https://gitlab.com/openstapps/app/commit/ffe05e4548fc399183ef651047cb02a3cdc80c67)), closes [#1](https://gitlab.com/openstapps/app/issues/1)
- **data:** add data detail templates ([5855acc](https://gitlab.com/openstapps/app/commit/5855accc169579d87f5779fd602d4f00f2b479a1))
- **data:** add method that checks if data item has been saved ([017fc67](https://gitlab.com/openstapps/app/commit/017fc67765bdb75542045830fb85f8eb4b899485))
- **data:** implement basic facets handling ([b6f92a7](https://gitlab.com/openstapps/app/commit/b6f92a74494e1a39d5c828d593eb70c7002bb0f6)), closes [#1](https://gitlab.com/openstapps/app/issues/1)
- **data:** show skeleton screens before data is loaded ([e1039aa](https://gitlab.com/openstapps/app/commit/e1039aa2260a0e9d8ccca5a18ded480bf2f12530)), closes [#4](https://gitlab.com/openstapps/app/issues/4)
- **data:** use data provider for list and detail view ([7caaa18](https://gitlab.com/openstapps/app/commit/7caaa18b7eb94ed8e4ff4e54d760ba1dba3ae3be))
- **data:** use general template for all offers ([58960a2](https://gitlab.com/openstapps/app/commit/58960a29ea0cd73f26a43186b41f5b53864810e0))
- display availability and item data for library items ([d571b1d](https://gitlab.com/openstapps/app/commit/d571b1dbe59f8e2270d88dd050b94283bf0a7056))
- dynamic news page rows ([848d257](https://gitlab.com/openstapps/app/commit/848d2574c7046d6f84b91e32aa83ca57fca8ad2e))
- expandable accordion in grades module ([3f81afd](https://gitlab.com/openstapps/app/commit/3f81afda82cf87bb393fbb3b71d27eee77ae42d9))
- get tab navigation items from config ([c3130a3](https://gitlab.com/openstapps/app/commit/c3130a392a53c9ec3657e24a53ed0b3333ba162b))
- Implement variable for styling ([8ecf347](https://gitlab.com/openstapps/app/commit/8ecf347c9a8abac9347dca45e99ebe35eca8f252))
- include font licenses in the licenses section ([82479f4](https://gitlab.com/openstapps/app/commit/82479f463cbee834507a0c8faf895a729631eb06))
- Ionic v6 breadcrumbs in catalog module ([7b491ed](https://gitlab.com/openstapps/app/commit/7b491ed3bb5466a845493bd8ea0bbb836a4f03d2))
- lazy load all news ([e48134e](https://gitlab.com/openstapps/app/commit/e48134eddcd1ca4d5ec5dbf910571e33a3311ba1))
- **menu:** add context menu ([1dbf451](https://gitlab.com/openstapps/app/commit/1dbf4515fe57cc8250a7fa2213ced682e3e5e0fc)), closes [#3](https://gitlab.com/openstapps/app/issues/3)
- navigation rail ([6b08af6](https://gitlab.com/openstapps/app/commit/6b08af6a746bf12005d3297ec97c130e84477615))
- news module ([22cd0af](https://gitlab.com/openstapps/app/commit/22cd0af1bf92a4576316f5510c22f012e085a237))
- profile page sections ([e395e9d](https://gitlab.com/openstapps/app/commit/e395e9d270f41bd4f6e5ecd88e438a28dde92465)), closes [#233](https://gitlab.com/openstapps/app/issues/233) [#261](https://gitlab.com/openstapps/app/issues/261) [#267](https://gitlab.com/openstapps/app/issues/267)
- refresh on pull for news module ([1f3d9ad](https://gitlab.com/openstapps/app/commit/1f3d9ad5f0c0557add2dcf242cf0b7dd7685bb1b))
- resume at origin path after login ([a5e5a5b](https://gitlab.com/openstapps/app/commit/a5e5a5b40799e7505557f7ebd764b9c563be0f4b)), closes [#168](https://gitlab.com/openstapps/app/issues/168)
- schedule layout ([e416590](https://gitlab.com/openstapps/app/commit/e4165901bb5efa6b38e397cdf5d66138e396d7f2))
- scroll schedule cursor into view ([bc4c3d7](https://gitlab.com/openstapps/app/commit/bc4c3d78dbd906243dcddac4db9ac8ccaca79056))
- search url query param handling ([f349bd7](https://gitlab.com/openstapps/app/commit/f349bd72335c47d292d0a007b1a4ce7f5c694a61))
- seperate dishes by menu sections ([400c6b8](https://gitlab.com/openstapps/app/commit/400c6b8d8c5300035862186096e38883f781d297))
- show availability in offers ([5fdef95](https://gitlab.com/openstapps/app/commit/5fdef95c065e7b467a13045adbb56a641cb2dc12))
- show feedback when map search yields no results ([c54ea86](https://gitlab.com/openstapps/app/commit/c54ea867bd64af187446dbf8dc03967aae600961))
- show menu for multiple days for canteens and cafes ([3c079cd](https://gitlab.com/openstapps/app/commit/3c079cd189e3b75d3b203bd46ab57378f99e88cc)), closes [#19](https://gitlab.com/openstapps/app/issues/19) [#79](https://gitlab.com/openstapps/app/issues/79)
- **storage:** add search using regex ([86b9bff](https://gitlab.com/openstapps/app/commit/86b9bff09a51b17151efa5ec322cddcc50a54cb2))
- **storage:** support deletion of multiple entries ([63266f5](https://gitlab.com/openstapps/app/commit/63266f588f6ddb2476e2cea4bab42a3864f77470))
- **storage:** support search using a string ([4334cad](https://gitlab.com/openstapps/app/commit/4334cad68c7d0abb7443e245b6eb983804547925))
- support deep links ([2e3f668](https://gitlab.com/openstapps/app/commit/2e3f6684ef5fbac8e4fb127c536b2b438399ce37))
- support overlapping timetable dates ([93c37b2](https://gitlab.com/openstapps/app/commit/93c37b26cca7764dea66fb12c0e53acc8fd78d2b))
- tab navigation bar animations and state ([7ecba0b](https://gitlab.com/openstapps/app/commit/7ecba0b7819ae5a7ab32d86f6049de0ab6c68e55))
- timetable module - schedule and calendar ([d8ede00](https://gitlab.com/openstapps/app/commit/d8ede006dfbd613dfbc752eb6de80db2e7e84531))
- turn on oauth2 state check for PAIA ([5bd0b50](https://gitlab.com/openstapps/app/commit/5bd0b50816973548a0a4aa5dbed3f2d0902590dd)), closes [#172](https://gitlab.com/openstapps/app/issues/172)
- use http interceptor for backendless development ([2558163](https://gitlab.com/openstapps/app/commit/2558163ad6c3038445a79e6338f1827cb1e6510e)), closes [#37](https://gitlab.com/openstapps/app/issues/37)
- use school-neutral news image fallback via css ([bb94c71](https://gitlab.com/openstapps/app/commit/bb94c71761ca5d3bf6639476ba0c143678cfabbd))
- webpack bundle analyzer ([552911c](https://gitlab.com/openstapps/app/commit/552911cfcfecec8d9be8b8bbb155b597d1f70fa2))
## 0.0.1
### Features
- add the app ([8b23159](https://gitlab.com/openstapps/app/commit/8b23159e678773b08252bc5826510de2a302fa1d))

View File

@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android { android {
namespace "de.anyschool.app" namespace "de.anyschool.app"
compileSdkVersion rootProject.ext.compileSdkVersion compileSdk rootProject.ext.compileSdkVersion
defaultConfig { defaultConfig {
applicationId "de.anyschool.app" applicationId "de.anyschool.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion

View File

@@ -7,8 +7,8 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.0.0' classpath 'com.android.tools.build:gradle:8.2.1'
classpath 'com.google.gms:google-services:4.3.15' classpath 'com.google.gms:google-services:4.4.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@@ -1,57 +1,57 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
include ':capacitor-android' include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../../../node_modules/.pnpm/@capacitor+android@5.7.3_@capacitor+core@5.7.3/node_modules/@capacitor/android/capacitor') project(':capacitor-android').projectDir = new File('../../../node_modules/.pnpm/@capacitor+android@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/android/capacitor')
include ':capacitor-community-screen-brightness' include ':capacitor-community-screen-brightness'
project(':capacitor-community-screen-brightness').projectDir = new File('../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@5.7.3/node_modules/@capacitor-community/screen-brightness/android') project(':capacitor-community-screen-brightness').projectDir = new File('../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor-community/screen-brightness/android')
include ':capacitor-app' include ':capacitor-app'
project(':capacitor-app').projectDir = new File('../../../node_modules/.pnpm/@capacitor+app@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/app/android') project(':capacitor-app').projectDir = new File('../../../node_modules/.pnpm/@capacitor+app@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/app/android')
include ':capacitor-browser' include ':capacitor-browser'
project(':capacitor-browser').projectDir = new File('../../../node_modules/.pnpm/@capacitor+browser@5.2.0_@capacitor+core@5.7.3/node_modules/@capacitor/browser/android') project(':capacitor-browser').projectDir = new File('../../../node_modules/.pnpm/@capacitor+browser@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/browser/android')
include ':capacitor-clipboard' include ':capacitor-clipboard'
project(':capacitor-clipboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+clipboard@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/clipboard/android') project(':capacitor-clipboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+clipboard@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/clipboard/android')
include ':capacitor-device' include ':capacitor-device'
project(':capacitor-device').projectDir = new File('../../../node_modules/.pnpm/@capacitor+device@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/device/android') project(':capacitor-device').projectDir = new File('../../../node_modules/.pnpm/@capacitor+device@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/device/android')
include ':capacitor-dialog' include ':capacitor-dialog'
project(':capacitor-dialog').projectDir = new File('../../../node_modules/.pnpm/@capacitor+dialog@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/dialog/android') project(':capacitor-dialog').projectDir = new File('../../../node_modules/.pnpm/@capacitor+dialog@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/dialog/android')
include ':capacitor-filesystem' include ':capacitor-filesystem'
project(':capacitor-filesystem').projectDir = new File('../../../node_modules/.pnpm/@capacitor+filesystem@5.2.1_@capacitor+core@5.7.3/node_modules/@capacitor/filesystem/android') project(':capacitor-filesystem').projectDir = new File('../../../node_modules/.pnpm/@capacitor+filesystem@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/filesystem/android')
include ':capacitor-geolocation' include ':capacitor-geolocation'
project(':capacitor-geolocation').projectDir = new File('../../../node_modules/.pnpm/@capacitor+geolocation@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/geolocation/android') project(':capacitor-geolocation').projectDir = new File('../../../node_modules/.pnpm/@capacitor+geolocation@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/geolocation/android')
include ':capacitor-haptics' include ':capacitor-haptics'
project(':capacitor-haptics').projectDir = new File('../../../node_modules/.pnpm/@capacitor+haptics@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/haptics/android') project(':capacitor-haptics').projectDir = new File('../../../node_modules/.pnpm/@capacitor+haptics@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/haptics/android')
include ':capacitor-keyboard' include ':capacitor-keyboard'
project(':capacitor-keyboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+keyboard@5.0.8_@capacitor+core@5.7.3/node_modules/@capacitor/keyboard/android') project(':capacitor-keyboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+keyboard@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/keyboard/android')
include ':capacitor-local-notifications' include ':capacitor-local-notifications'
project(':capacitor-local-notifications').projectDir = new File('../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/local-notifications/android') project(':capacitor-local-notifications').projectDir = new File('../../../node_modules/.pnpm/@capacitor+local-notifications@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/local-notifications/android')
include ':capacitor-network' include ':capacitor-network'
project(':capacitor-network').projectDir = new File('../../../node_modules/.pnpm/@capacitor+network@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/network/android') project(':capacitor-network').projectDir = new File('../../../node_modules/.pnpm/@capacitor+network@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/network/android')
include ':capacitor-preferences' include ':capacitor-preferences'
project(':capacitor-preferences').projectDir = new File('../../../node_modules/.pnpm/@capacitor+preferences@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/preferences/android') project(':capacitor-preferences').projectDir = new File('../../../node_modules/.pnpm/@capacitor+preferences@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/preferences/android')
include ':capacitor-screen-orientation' include ':capacitor-screen-orientation'
project(':capacitor-screen-orientation').projectDir = new File('../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.0_@capacitor+core@5.7.3/node_modules/@capacitor/screen-orientation/android') project(':capacitor-screen-orientation').projectDir = new File('../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/screen-orientation/android')
include ':capacitor-share' include ':capacitor-share'
project(':capacitor-share').projectDir = new File('../../../node_modules/.pnpm/@capacitor+share@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/share/android') project(':capacitor-share').projectDir = new File('../../../node_modules/.pnpm/@capacitor+share@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/share/android')
include ':capacitor-splash-screen' include ':capacitor-splash-screen'
project(':capacitor-splash-screen').projectDir = new File('../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/splash-screen/android') project(':capacitor-splash-screen').projectDir = new File('../../../node_modules/.pnpm/@capacitor+splash-screen@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/splash-screen/android')
include ':transistorsoft-capacitor-background-fetch' include ':transistorsoft-capacitor-background-fetch'
project(':transistorsoft-capacitor-background-fetch').projectDir = new File('../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@5.7.3/node_modules/@transistorsoft/capacitor-background-fetch/android') project(':transistorsoft-capacitor-background-fetch').projectDir = new File('../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@6.1.1/node_modules/@transistorsoft/capacitor-background-fetch/android')
include ':capacitor-secure-storage-plugin' include ':capacitor-secure-storage-plugin'
project(':capacitor-secure-storage-plugin').projectDir = new File('../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.7.3/node_modules/capacitor-secure-storage-plugin/android') project(':capacitor-secure-storage-plugin').projectDir = new File('../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@6.1.1/node_modules/capacitor-secure-storage-plugin/android')

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
networkTimeout=10000 networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,14 +1,14 @@
ext { ext {
minSdkVersion = 22 minSdkVersion = 22
compileSdkVersion = 33 compileSdkVersion = 34
targetSdkVersion = 33 targetSdkVersion = 34
androidxActivityVersion = '1.7.0' androidxActivityVersion = '1.8.0'
androidxAppCompatVersion = '1.6.1' androidxAppCompatVersion = '1.6.1'
androidxCoordinatorLayoutVersion = '1.2.0' androidxCoordinatorLayoutVersion = '1.2.0'
androidxCoreVersion = '1.10.0' androidxCoreVersion = '1.12.0'
androidxFragmentVersion = '1.5.6' androidxFragmentVersion = '1.6.2'
coreSplashScreenVersion = '1.0.0' coreSplashScreenVersion = '1.0.1'
androidxWebkitVersion = '1.6.1' androidxWebkitVersion = '1.9.0'
junitVersion = '4.13.2' junitVersion = '4.13.2'
androidxJunitVersion = '1.1.5' androidxJunitVersion = '1.1.5'
androidxEspressoCoreVersion = '3.5.1' androidxEspressoCoreVersion = '3.5.1'

View File

@@ -35,14 +35,22 @@
"glob": "**/*", "glob": "**/*",
"input": "src/assets", "input": "src/assets",
"output": "assets" "output": "assets"
} },
{
"glob": "CHANGELOG.md",
"input": ".",
"output": "assets"
},
"src/manifest.webmanifest"
], ],
"styles": [ "styles": [
{ {
"input": "src/global.scss", "input": "src/global.scss",
"inject": true "inject": true
} }
] ],
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json"
}, },
"configurations": { "configurations": {
"production": { "production": {
@@ -124,7 +132,8 @@
"glob": "**/*", "glob": "**/*",
"input": "src/assets", "input": "src/assets",
"output": "/assets" "output": "/assets"
} },
"src/manifest.webmanifest"
] ]
} }
}, },

View File

@@ -1,4 +1,4 @@
require_relative '../../../../node_modules/.pnpm/@capacitor+ios@5.7.3_@capacitor+core@5.7.3/node_modules/@capacitor/ios/scripts/pods_helpers' require_relative '../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios/scripts/pods_helpers'
platform :ios, '13.0' platform :ios, '13.0'
use_frameworks! use_frameworks!
@@ -9,26 +9,26 @@ use_frameworks!
install! 'cocoapods', :disable_input_output_paths => true install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods def capacitor_pods
pod 'Capacitor', :path => '../../../../node_modules/.pnpm/@capacitor+ios@5.7.3_@capacitor+core@5.7.3/node_modules/@capacitor/ios' pod 'Capacitor', :path => '../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../../../../node_modules/.pnpm/@capacitor+ios@5.7.3_@capacitor+core@5.7.3/node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios'
pod 'CapacitorCommunityScreenBrightness', :path => '../../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@5.7.3/node_modules/@capacitor-community/screen-brightness' pod 'CapacitorCommunityScreenBrightness', :path => '../../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor-community/screen-brightness'
pod 'CapacitorApp', :path => '../../../../node_modules/.pnpm/@capacitor+app@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/app' pod 'CapacitorApp', :path => '../../../../node_modules/.pnpm/@capacitor+app@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/app'
pod 'CapacitorBrowser', :path => '../../../../node_modules/.pnpm/@capacitor+browser@5.2.0_@capacitor+core@5.7.3/node_modules/@capacitor/browser' pod 'CapacitorBrowser', :path => '../../../../node_modules/.pnpm/@capacitor+browser@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/browser'
pod 'CapacitorClipboard', :path => '../../../../node_modules/.pnpm/@capacitor+clipboard@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/clipboard' pod 'CapacitorClipboard', :path => '../../../../node_modules/.pnpm/@capacitor+clipboard@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/clipboard'
pod 'CapacitorDevice', :path => '../../../../node_modules/.pnpm/@capacitor+device@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/device' pod 'CapacitorDevice', :path => '../../../../node_modules/.pnpm/@capacitor+device@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/device'
pod 'CapacitorDialog', :path => '../../../../node_modules/.pnpm/@capacitor+dialog@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/dialog' pod 'CapacitorDialog', :path => '../../../../node_modules/.pnpm/@capacitor+dialog@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/dialog'
pod 'CapacitorFilesystem', :path => '../../../../node_modules/.pnpm/@capacitor+filesystem@5.2.1_@capacitor+core@5.7.3/node_modules/@capacitor/filesystem' pod 'CapacitorFilesystem', :path => '../../../../node_modules/.pnpm/@capacitor+filesystem@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/filesystem'
pod 'CapacitorGeolocation', :path => '../../../../node_modules/.pnpm/@capacitor+geolocation@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/geolocation' pod 'CapacitorGeolocation', :path => '../../../../node_modules/.pnpm/@capacitor+geolocation@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/geolocation'
pod 'CapacitorHaptics', :path => '../../../../node_modules/.pnpm/@capacitor+haptics@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/haptics' pod 'CapacitorHaptics', :path => '../../../../node_modules/.pnpm/@capacitor+haptics@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/haptics'
pod 'CapacitorKeyboard', :path => '../../../../node_modules/.pnpm/@capacitor+keyboard@5.0.8_@capacitor+core@5.7.3/node_modules/@capacitor/keyboard' pod 'CapacitorKeyboard', :path => '../../../../node_modules/.pnpm/@capacitor+keyboard@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/keyboard'
pod 'CapacitorLocalNotifications', :path => '../../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/local-notifications' pod 'CapacitorLocalNotifications', :path => '../../../../node_modules/.pnpm/@capacitor+local-notifications@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/local-notifications'
pod 'CapacitorNetwork', :path => '../../../../node_modules/.pnpm/@capacitor+network@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/network' pod 'CapacitorNetwork', :path => '../../../../node_modules/.pnpm/@capacitor+network@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/network'
pod 'CapacitorPreferences', :path => '../../../../node_modules/.pnpm/@capacitor+preferences@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/preferences' pod 'CapacitorPreferences', :path => '../../../../node_modules/.pnpm/@capacitor+preferences@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/preferences'
pod 'CapacitorScreenOrientation', :path => '../../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.0_@capacitor+core@5.7.3/node_modules/@capacitor/screen-orientation' pod 'CapacitorScreenOrientation', :path => '../../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/screen-orientation'
pod 'CapacitorShare', :path => '../../../../node_modules/.pnpm/@capacitor+share@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/share' pod 'CapacitorShare', :path => '../../../../node_modules/.pnpm/@capacitor+share@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/share'
pod 'CapacitorSplashScreen', :path => '../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.7_@capacitor+core@5.7.3/node_modules/@capacitor/splash-screen' pod 'CapacitorSplashScreen', :path => '../../../../node_modules/.pnpm/@capacitor+splash-screen@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/splash-screen'
pod 'TransistorsoftCapacitorBackgroundFetch', :path => '../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@5.7.3/node_modules/@transistorsoft/capacitor-background-fetch' pod 'TransistorsoftCapacitorBackgroundFetch', :path => '../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@6.1.1/node_modules/@transistorsoft/capacitor-background-fetch'
pod 'CapacitorSecureStoragePlugin', :path => '../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.7.3/node_modules/capacitor-secure-storage-plugin' pod 'CapacitorSecureStoragePlugin', :path => '../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@6.1.1/node_modules/capacitor-secure-storage-plugin'
pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins' pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
end end

View File

@@ -1,64 +1,70 @@
PODS: PODS:
- Capacitor (5.5.0): - Capacitor (6.1.1):
- CapacitorCordova - CapacitorCordova
- CapacitorApp (5.0.6): - CapacitorApp (6.0.0):
- Capacitor - Capacitor
- CapacitorBrowser (5.1.0): - CapacitorBrowser (6.0.1):
- Capacitor - Capacitor
- CapacitorClipboard (5.0.6): - CapacitorClipboard (6.0.0):
- Capacitor - Capacitor
- CapacitorCordova (5.5.0) - CapacitorCommunityScreenBrightness (6.0.0):
- CapacitorDevice (5.0.6):
- Capacitor - Capacitor
- CapacitorDialog (5.0.6): - CapacitorCordova (6.1.1)
- CapacitorDevice (6.0.0):
- Capacitor - Capacitor
- CapacitorFilesystem (5.1.4): - CapacitorDialog (6.0.0):
- Capacitor - Capacitor
- CapacitorGeolocation (5.0.6): - CapacitorFilesystem (6.0.0):
- Capacitor - Capacitor
- CapacitorHaptics (5.0.6): - CapacitorGeolocation (6.0.0):
- Capacitor - Capacitor
- CapacitorKeyboard (5.0.6): - CapacitorHaptics (6.0.0):
- Capacitor - Capacitor
- CapacitorLocalNotifications (5.0.6): - CapacitorKeyboard (6.0.1):
- Capacitor - Capacitor
- CapacitorNetwork (5.0.6): - CapacitorLocalNotifications (6.0.0):
- Capacitor - Capacitor
- CapacitorPreferences (5.0.6): - CapacitorNetwork (6.0.1):
- Capacitor
- CapacitorPreferences (6.0.1):
- Capacitor
- CapacitorScreenOrientation (6.0.1):
- Capacitor - Capacitor
- CapacitorSecureStoragePlugin (0.9.0): - CapacitorSecureStoragePlugin (0.9.0):
- Capacitor - Capacitor
- SwiftKeychainWrapper - SwiftKeychainWrapper
- CapacitorShare (5.0.6): - CapacitorShare (6.0.1):
- Capacitor - Capacitor
- CapacitorSplashScreen (5.0.6): - CapacitorSplashScreen (6.0.1):
- Capacitor - Capacitor
- CordovaPlugins (5.5.0): - CordovaPlugins (6.1.1):
- CapacitorCordova - CapacitorCordova
- SwiftKeychainWrapper (4.0.1) - SwiftKeychainWrapper (4.0.1)
- TransistorsoftCapacitorBackgroundFetch (5.1.1): - TransistorsoftCapacitorBackgroundFetch (5.2.0):
- Capacitor - Capacitor
DEPENDENCIES: DEPENDENCIES:
- "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios`)" - "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios`)"
- "CapacitorApp (from `../../../../node_modules/.pnpm/@capacitor+app@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/app`)" - "CapacitorApp (from `../../../../node_modules/.pnpm/@capacitor+app@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/app`)"
- "CapacitorBrowser (from `../../../../node_modules/.pnpm/@capacitor+browser@5.1.0_@capacitor+core@5.5.0/node_modules/@capacitor/browser`)" - "CapacitorBrowser (from `../../../../node_modules/.pnpm/@capacitor+browser@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/browser`)"
- "CapacitorClipboard (from `../../../../node_modules/.pnpm/@capacitor+clipboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/clipboard`)" - "CapacitorClipboard (from `../../../../node_modules/.pnpm/@capacitor+clipboard@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/clipboard`)"
- "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios`)" - "CapacitorCommunityScreenBrightness (from `../../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor-community/screen-brightness`)"
- "CapacitorDevice (from `../../../../node_modules/.pnpm/@capacitor+device@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/device`)" - "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios`)"
- "CapacitorDialog (from `../../../../node_modules/.pnpm/@capacitor+dialog@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/dialog`)" - "CapacitorDevice (from `../../../../node_modules/.pnpm/@capacitor+device@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/device`)"
- "CapacitorFilesystem (from `../../../../node_modules/.pnpm/@capacitor+filesystem@5.1.4_@capacitor+core@5.5.0/node_modules/@capacitor/filesystem`)" - "CapacitorDialog (from `../../../../node_modules/.pnpm/@capacitor+dialog@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/dialog`)"
- "CapacitorGeolocation (from `../../../../node_modules/.pnpm/@capacitor+geolocation@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/geolocation`)" - "CapacitorFilesystem (from `../../../../node_modules/.pnpm/@capacitor+filesystem@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/filesystem`)"
- "CapacitorHaptics (from `../../../../node_modules/.pnpm/@capacitor+haptics@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/haptics`)" - "CapacitorGeolocation (from `../../../../node_modules/.pnpm/@capacitor+geolocation@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/geolocation`)"
- "CapacitorKeyboard (from `../../../../node_modules/.pnpm/@capacitor+keyboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/keyboard`)" - "CapacitorHaptics (from `../../../../node_modules/.pnpm/@capacitor+haptics@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/haptics`)"
- "CapacitorLocalNotifications (from `../../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/local-notifications`)" - "CapacitorKeyboard (from `../../../../node_modules/.pnpm/@capacitor+keyboard@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/keyboard`)"
- "CapacitorNetwork (from `../../../../node_modules/.pnpm/@capacitor+network@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/network`)" - "CapacitorLocalNotifications (from `../../../../node_modules/.pnpm/@capacitor+local-notifications@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/local-notifications`)"
- "CapacitorPreferences (from `../../../../node_modules/.pnpm/@capacitor+preferences@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/preferences`)" - "CapacitorNetwork (from `../../../../node_modules/.pnpm/@capacitor+network@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/network`)"
- "CapacitorSecureStoragePlugin (from `../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin`)" - "CapacitorPreferences (from `../../../../node_modules/.pnpm/@capacitor+preferences@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/preferences`)"
- "CapacitorShare (from `../../../../node_modules/.pnpm/@capacitor+share@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/share`)" - "CapacitorScreenOrientation (from `../../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/screen-orientation`)"
- "CapacitorSplashScreen (from `../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/splash-screen`)" - "CapacitorSecureStoragePlugin (from `../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@6.1.1/node_modules/capacitor-secure-storage-plugin`)"
- "CapacitorShare (from `../../../../node_modules/.pnpm/@capacitor+share@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/share`)"
- "CapacitorSplashScreen (from `../../../../node_modules/.pnpm/@capacitor+splash-screen@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/splash-screen`)"
- CordovaPlugins (from `../capacitor-cordova-ios-plugins`) - CordovaPlugins (from `../capacitor-cordova-ios-plugins`)
- "TransistorsoftCapacitorBackgroundFetch (from `../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.1.1_@capacitor+core@5.5.0/node_modules/@transistorsoft/capacitor-background-fetch`)" - "TransistorsoftCapacitorBackgroundFetch (from `../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@6.1.1/node_modules/@transistorsoft/capacitor-background-fetch`)"
SPEC REPOS: SPEC REPOS:
trunk: trunk:
@@ -66,66 +72,72 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
Capacitor: Capacitor:
:path: "../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios" :path: "../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios"
CapacitorApp: CapacitorApp:
:path: "../../../../node_modules/.pnpm/@capacitor+app@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/app" :path: "../../../../node_modules/.pnpm/@capacitor+app@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/app"
CapacitorBrowser: CapacitorBrowser:
:path: "../../../../node_modules/.pnpm/@capacitor+browser@5.1.0_@capacitor+core@5.5.0/node_modules/@capacitor/browser" :path: "../../../../node_modules/.pnpm/@capacitor+browser@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/browser"
CapacitorClipboard: CapacitorClipboard:
:path: "../../../../node_modules/.pnpm/@capacitor+clipboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/clipboard" :path: "../../../../node_modules/.pnpm/@capacitor+clipboard@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/clipboard"
CapacitorCommunityScreenBrightness:
:path: "../../../../node_modules/.pnpm/@capacitor-community+screen-brightness@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor-community/screen-brightness"
CapacitorCordova: CapacitorCordova:
:path: "../../../../node_modules/.pnpm/@capacitor+ios@5.5.0_@capacitor+core@5.5.0/node_modules/@capacitor/ios" :path: "../../../../node_modules/.pnpm/@capacitor+ios@6.1.1_@capacitor+core@6.1.1/node_modules/@capacitor/ios"
CapacitorDevice: CapacitorDevice:
:path: "../../../../node_modules/.pnpm/@capacitor+device@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/device" :path: "../../../../node_modules/.pnpm/@capacitor+device@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/device"
CapacitorDialog: CapacitorDialog:
:path: "../../../../node_modules/.pnpm/@capacitor+dialog@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/dialog" :path: "../../../../node_modules/.pnpm/@capacitor+dialog@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/dialog"
CapacitorFilesystem: CapacitorFilesystem:
:path: "../../../../node_modules/.pnpm/@capacitor+filesystem@5.1.4_@capacitor+core@5.5.0/node_modules/@capacitor/filesystem" :path: "../../../../node_modules/.pnpm/@capacitor+filesystem@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/filesystem"
CapacitorGeolocation: CapacitorGeolocation:
:path: "../../../../node_modules/.pnpm/@capacitor+geolocation@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/geolocation" :path: "../../../../node_modules/.pnpm/@capacitor+geolocation@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/geolocation"
CapacitorHaptics: CapacitorHaptics:
:path: "../../../../node_modules/.pnpm/@capacitor+haptics@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/haptics" :path: "../../../../node_modules/.pnpm/@capacitor+haptics@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/haptics"
CapacitorKeyboard: CapacitorKeyboard:
:path: "../../../../node_modules/.pnpm/@capacitor+keyboard@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/keyboard" :path: "../../../../node_modules/.pnpm/@capacitor+keyboard@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/keyboard"
CapacitorLocalNotifications: CapacitorLocalNotifications:
:path: "../../../../node_modules/.pnpm/@capacitor+local-notifications@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/local-notifications" :path: "../../../../node_modules/.pnpm/@capacitor+local-notifications@6.0.0_@capacitor+core@6.1.1/node_modules/@capacitor/local-notifications"
CapacitorNetwork: CapacitorNetwork:
:path: "../../../../node_modules/.pnpm/@capacitor+network@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/network" :path: "../../../../node_modules/.pnpm/@capacitor+network@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/network"
CapacitorPreferences: CapacitorPreferences:
:path: "../../../../node_modules/.pnpm/@capacitor+preferences@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/preferences" :path: "../../../../node_modules/.pnpm/@capacitor+preferences@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/preferences"
CapacitorScreenOrientation:
:path: "../../../../node_modules/.pnpm/@capacitor+screen-orientation@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/screen-orientation"
CapacitorSecureStoragePlugin: CapacitorSecureStoragePlugin:
:path: "../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@5.5.0/node_modules/capacitor-secure-storage-plugin" :path: "../../../../node_modules/.pnpm/capacitor-secure-storage-plugin@0.9.0_@capacitor+core@6.1.1/node_modules/capacitor-secure-storage-plugin"
CapacitorShare: CapacitorShare:
:path: "../../../../node_modules/.pnpm/@capacitor+share@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/share" :path: "../../../../node_modules/.pnpm/@capacitor+share@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/share"
CapacitorSplashScreen: CapacitorSplashScreen:
:path: "../../../../node_modules/.pnpm/@capacitor+splash-screen@5.0.6_@capacitor+core@5.5.0/node_modules/@capacitor/splash-screen" :path: "../../../../node_modules/.pnpm/@capacitor+splash-screen@6.0.1_@capacitor+core@6.1.1/node_modules/@capacitor/splash-screen"
CordovaPlugins: CordovaPlugins:
:path: "../capacitor-cordova-ios-plugins" :path: "../capacitor-cordova-ios-plugins"
TransistorsoftCapacitorBackgroundFetch: TransistorsoftCapacitorBackgroundFetch:
:path: "../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.1.1_@capacitor+core@5.5.0/node_modules/@transistorsoft/capacitor-background-fetch" :path: "../../../../node_modules/.pnpm/@transistorsoft+capacitor-background-fetch@5.2.0_@capacitor+core@6.1.1/node_modules/@transistorsoft/capacitor-background-fetch"
SPEC CHECKSUMS: SPEC CHECKSUMS:
Capacitor: 57890b363df14d5d2d5d8461aa23e886cb34da2a Capacitor: 8941aba4364ba9d1b22188569001f2ce45cc2b00
CapacitorApp: 024e1b1bea5f883d79f6330d309bc441c88ad04a CapacitorApp: 9d53aec7101f7b030a950c5bdc4df8612576b279
CapacitorBrowser: 7a0fb6a1011abfaaf2dfedfd8248f942a8eda3d6 CapacitorBrowser: 473c7fd70ddbe541608ff09ec1be14da0078279e
CapacitorClipboard: 77edf49827ea21da2a9c05c690a4a6a4d07199c4 CapacitorClipboard: 80282f684154124b9019ebf401235b70b0cf4994
CapacitorCordova: 3d3908a3d208a11a75f9df3b18c4405c4de76e1d CapacitorCommunityScreenBrightness: 250184917bd0738a681c026a9513e18ddb0cb49b
CapacitorDevice: 2c968f98a1ec4d22357418c1521e7ddc46c675e6 CapacitorCordova: 8f2cc8d8d3619c566e9418fe8772064a94266106
CapacitorDialog: 0f3c15dfe9414b83bc64aef4078f1b92bcfead26 CapacitorDevice: f8fd88f9edd1261c55a109f32015b09bbbfdc4a0
CapacitorFilesystem: af704badfbc69f6f8623d9ed313e5490e3723dcb CapacitorDialog: 64aa82840ee5e9c066f9e1a49c1e186afd3f24d2
CapacitorGeolocation: 7be5f77abc205c0efe319fff8587a7183e7b0240 CapacitorFilesystem: 60e59ba274c234a979e7a3be2552feaadcee4263
CapacitorHaptics: 1fffc1217c7e64a472d7845be50fb0c2f7d4204c CapacitorGeolocation: 1f12bbe372b65116e851bd8e3a94cf0ef9bacebb
CapacitorKeyboard: b978154b024a5f65e044908e37d15b7de58b9d12 CapacitorHaptics: 9ebc9363f0e9b8eb4295088a0b474530acf1859b
CapacitorLocalNotifications: c2d8b14794064fd4814b1d6c4ddbac8029afa295 CapacitorKeyboard: 5f32a712adf41e07a61caafb82cf29fb6d8ba123
CapacitorNetwork: d80b3e79bef6ec37640ee2806c19771f07ff2d0c CapacitorLocalNotifications: 4ab68f0be5f697a579558fadd307d823a9ec1c26
CapacitorPreferences: f03954bcb0ff09c792909e46bff88e3183c16b10 CapacitorNetwork: 5c94acfdddc22043f2ffaff224ce9b4aa5a179f0
CapacitorPreferences: 72909b165bc7807103778ddbb86d5d8ce06abf71
CapacitorScreenOrientation: 3d4965dcbda5d901b6a48350a5d270ad7d404e05
CapacitorSecureStoragePlugin: e91d7df060f2495a1acff9583641a6953e3aacba CapacitorSecureStoragePlugin: e91d7df060f2495a1acff9583641a6953e3aacba
CapacitorShare: cd41743331cb71d217c029de54b681cbd91e0fcc CapacitorShare: 02222f2457ff003e642370a9c1ecd101baaa27c8
CapacitorSplashScreen: 5fa2ab5e46cf5cc530cf16a51c80c7a986579ccd CapacitorSplashScreen: 61645214e8f955ff2b80f16a6a3648960fe4c89f
CordovaPlugins: de5669381702d76ed5b1d442177a6a5fc3252a9d CordovaPlugins: 1078156cfc354dd440b38ce4062e69fd9b07033c
SwiftKeychainWrapper: 807ba1d63c33a7d0613288512399cd1eda1e470c SwiftKeychainWrapper: 807ba1d63c33a7d0613288512399cd1eda1e470c
TransistorsoftCapacitorBackgroundFetch: ce4b3e01b898cef516e68485d2160a078016ee97 TransistorsoftCapacitorBackgroundFetch: f130c5dcb6048401e74cc531e691e1d513045366
PODFILE CHECKSUM: 229278f2c257e8ab555325c7115b2e187e8e628d PODFILE CHECKSUM: d0561b89b66368df409c77587e3e02b48e737203
COCOAPODS: 1.13.0 COCOAPODS: 1.15.2

View File

@@ -0,0 +1,21 @@
{
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js"]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/assets/**", "/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"]
}
}
]
}

View File

@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/app", "name": "@openstapps/app",
"description": "The generic app tailored to fulfill needs of German universities, written using Ionic Framework.", "description": "The generic app tailored to fulfill needs of German universities, written using Ionic Framework.",
"version": "3.3.2", "version": "3.3.4",
"private": true, "private": true,
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>", "author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
@@ -59,25 +59,26 @@
"@angular/forms": "17.3.0", "@angular/forms": "17.3.0",
"@angular/platform-browser": "17.3.0", "@angular/platform-browser": "17.3.0",
"@angular/router": "17.3.0", "@angular/router": "17.3.0",
"@angular/service-worker": "17.3.0",
"@awesome-cordova-plugins/calendar": "6.6.0", "@awesome-cordova-plugins/calendar": "6.6.0",
"@awesome-cordova-plugins/core": "6.6.0", "@awesome-cordova-plugins/core": "6.6.0",
"@capacitor-community/screen-brightness": "6.0.0", "@capacitor-community/screen-brightness": "6.0.0",
"@capacitor/app": "5.0.7", "@capacitor/app": "6.0.0",
"@capacitor/browser": "5.2.0", "@capacitor/browser": "6.0.1",
"@capacitor/clipboard": "5.0.7", "@capacitor/clipboard": "6.0.0",
"@capacitor/core": "5.7.3", "@capacitor/core": "6.1.1",
"@capacitor/device": "5.0.7", "@capacitor/device": "6.0.0",
"@capacitor/dialog": "5.0.7", "@capacitor/dialog": "6.0.0",
"@capacitor/filesystem": "5.2.1", "@capacitor/filesystem": "6.0.0",
"@capacitor/geolocation": "5.0.7", "@capacitor/geolocation": "6.0.0",
"@capacitor/haptics": "5.0.7", "@capacitor/haptics": "6.0.0",
"@capacitor/keyboard": "5.0.8", "@capacitor/keyboard": "6.0.1",
"@capacitor/local-notifications": "5.0.7", "@capacitor/local-notifications": "6.0.0",
"@capacitor/network": "5.0.7", "@capacitor/network": "6.0.1",
"@capacitor/preferences": "5.0.7", "@capacitor/preferences": "6.0.1",
"@capacitor/screen-orientation": "6.0.0", "@capacitor/screen-orientation": "6.0.1",
"@capacitor/share": "5.0.7", "@capacitor/share": "6.0.1",
"@capacitor/splash-screen": "5.0.7", "@capacitor/splash-screen": "6.0.1",
"@ionic-native/core": "5.36.0", "@ionic-native/core": "5.36.0",
"@ionic/angular": "7.8.0", "@ionic/angular": "7.8.0",
"@ionic/storage-angular": "4.0.0", "@ionic/storage-angular": "4.0.0",
@@ -97,7 +98,7 @@
"form-data": "4.0.0", "form-data": "4.0.0",
"geojson": "0.5.0", "geojson": "0.5.0",
"ionic-appauth": "0.9.0", "ionic-appauth": "0.9.0",
"jsonpath-plus": "6.0.1", "jsonpath-plus": "10.0.7",
"maplibre-gl": "4.0.2", "maplibre-gl": "4.0.2",
"material-symbols": "0.17.1", "material-symbols": "0.17.1",
"moment": "2.30.1", "moment": "2.30.1",
@@ -129,10 +130,10 @@
"@angular/language-server": "17.3.0", "@angular/language-server": "17.3.0",
"@angular/language-service": "17.3.0", "@angular/language-service": "17.3.0",
"@angular/platform-browser-dynamic": "17.3.0", "@angular/platform-browser-dynamic": "17.3.0",
"@capacitor/android": "5.7.3", "@capacitor/android": "6.1.1",
"@capacitor/assets": "3.0.4", "@capacitor/assets": "3.0.4",
"@capacitor/cli": "5.7.3", "@capacitor/cli": "6.1.1",
"@capacitor/ios": "5.7.3", "@capacitor/ios": "6.1.1",
"@compodoc/compodoc": "1.1.23", "@compodoc/compodoc": "1.1.23",
"@cypress/schematic": "2.5.1", "@cypress/schematic": "2.5.1",
"@ionic/angular-toolkit": "11.0.1", "@ionic/angular-toolkit": "11.0.1",

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="1024"
height="1024"
viewBox="0 0 1024 1024"
sodipodi:docname="logo_pwa.svg"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
xml:space="preserve"
inkscape:export-filename="../src/assets/icons/icon-512x512.png"
inkscape:export-xdpi="48"
inkscape:export-ydpi="48"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs6" /><sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="true"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="0.49999772"
inkscape:cx="454.00207"
inkscape:cy="347.00158"
inkscape:window-width="1504"
inkscape:window-height="1729"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g8" /><g
inkscape:groupmode="layer"
inkscape:label="Image"
id="g8"><rect
style="fill:#00b5cc;fill-opacity:1;stroke-width:1.10978"
id="rect2351"
width="379.77051"
height="379.77051"
x="143.85109"
y="141.62936"
ry="50.263741"
sodipodi:insensitive="true" /><rect
style="fill:#3be40b;fill-opacity:1;stroke-width:1.11352"
id="rect2353"
width="154.14215"
height="154.14215"
x="580.75684"
y="367.25772"
ry="25.690359"
sodipodi:insensitive="true" /><rect
style="fill:#c90e20;fill-opacity:1;stroke-width:1.10084"
id="rect2355"
width="306.05032"
height="306.05032"
x="580.75684"
y="578.53516"
ry="35.743107"
sodipodi:insensitive="true" /><rect
style="fill:#e4a20b;fill-opacity:1;stroke-width:1.11912"
id="rect2357"
width="232.33018"
height="232.33018"
x="291.29138"
y="578.53516"
ry="33.509159"
sodipodi:insensitive="true" /></g></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -15,7 +15,7 @@
import {CommonModule, LocationStrategy, PathLocationStrategy, registerLocaleData} from '@angular/common'; import {CommonModule, LocationStrategy, PathLocationStrategy, registerLocaleData} from '@angular/common';
import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule} from '@angular/common/http'; import {HTTP_INTERCEPTORS, HttpClient, HttpClientModule} from '@angular/common/http';
import localeDe from '@angular/common/locales/de'; import localeDe from '@angular/common/locales/de';
import {APP_INITIALIZER, NgModule} from '@angular/core'; import {APP_INITIALIZER, NgModule, isDevMode} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import {RouteReuseStrategy} from '@angular/router'; import {RouteReuseStrategy} from '@angular/router';
import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular'; import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular';
@@ -71,6 +71,7 @@ import {Capacitor} from '@capacitor/core';
import {SplashScreen} from '@capacitor/splash-screen'; import {SplashScreen} from '@capacitor/splash-screen';
import maplibregl from 'maplibre-gl'; import maplibregl from 'maplibre-gl';
import {Protocol} from 'pmtiles'; import {Protocol} from 'pmtiles';
import {ServiceWorkerModule} from '@angular/service-worker';
registerLocaleData(localeDe); registerLocaleData(localeDe);
@@ -185,6 +186,12 @@ export function createTranslateLoader(http: HttpClient) {
LoggerModule.forRoot({ LoggerModule.forRoot({
level: environment.production ? NgxLoggerLevel.FATAL : NgxLoggerLevel.TRACE, level: environment.production ? NgxLoggerLevel.FATAL : NgxLoggerLevel.TRACE,
}), }),
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: !isDevMode(),
// Register the ServiceWorker as soon as the application is stable
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000',
}),
], ],
providers: [ providers: [
{ {

View File

@@ -13,11 +13,15 @@
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {Component} from '@angular/core'; import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {ConfigProvider} from '../config/config.provider';
@Component({ @Component({
selector: 'about-changelog', selector: 'about-changelog',
templateUrl: 'about-changelog.html', templateUrl: 'about-changelog.html',
styleUrls: ['about-changelog.scss', './about-page/about-page.scss'], styleUrls: ['about-changelog.scss', './about-page/about-page.scss', 'release-notes-markdown.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class AboutChangelogComponent {} export class AboutChangelogComponent {
config = inject(ConfigProvider);
}

View File

@@ -16,14 +16,14 @@
<ion-header> <ion-header>
<ion-toolbar color="primary" mode="ios"> <ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start"> <ion-buttons slot="start">
<ion-back-button></ion-back-button> <ion-back-button defaultHref="/about/changelog"></ion-back-button>
</ion-buttons> </ion-buttons>
<ion-title>Changelog</ion-title> <ion-title>{{ 'about.TECHNICAL_CHANGELOG' | translate }}</ion-title>
<!-- TODO: translation -->
</ion-toolbar> </ion-toolbar>
</ion-header> </ion-header>
<ion-content parallax> <ion-content parallax>
<p class="disclaimer">{{ 'about.TECHNICAL_CHANGELOG_DISCLAIMER' | translate }}</p>
<div class="about-changelog"> <div class="about-changelog">
<markdown src="assets/about/CHANGELOG.md"></markdown> <markdown class="release-notes" src="assets/CHANGELOG.md"></markdown>
</div> </div>
</ion-content> </ion-content>

View File

@@ -13,6 +13,13 @@
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
ion-content { ion-toggle {
--padding-start: 16px; width: fit-content;
padding-inline: var(--spacing-md);
color: var(--ion-color-primary-contrast);
}
.disclaimer {
margin-block: var(--spacing-xs);
color: var(--ion-color-primary-contrast);
} }

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {ChangeDetectionStrategy, Component, inject} from '@angular/core';
import {ConfigProvider} from '../config/config.provider';
@Component({
selector: 'about-changelog',
templateUrl: 'about-release-notes.html',
styleUrls: ['about-release-notes.scss', './about-page/about-page.scss', 'release-notes-markdown.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AboutReleaseNotesComponent {
config = inject(ConfigProvider);
}

View File

@@ -0,0 +1,32 @@
<!--
~ Copyright (C) 2023 StApps
~ This program is free software: you can redistribute it and/or modify it
~ under the terms of the GNU General Public License as published by the Free
~ Software Foundation, version 3.
~
~ This program is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
~ more details.
~
~ You should have received a copy of the GNU General Public License along with
~ this program. If not, see <https://www.gnu.org/licenses/>.
-->
<ion-header>
<ion-toolbar color="primary" mode="ios">
<ion-buttons slot="start">
<ion-back-button defaultHref="/about"></ion-back-button>
</ion-buttons>
<ion-title>{{ 'about.CHANGELOG' | translate }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content parallax>
<ion-button fill="clear" [routerLink]="['/about', 'stapps-changelog']"
>{{ 'about.TECHNICAL_CHANGELOG' | translate
}}<ion-icon slot="end" name="arrow_forward" ios="arrow_forward_ios"></ion-icon
></ion-button>
@for (version of config.config.app.versionHistory; track version) {
<markdown class="release-notes" [data]="'releaseNotes' | translateSimple: version"></markdown>
}
</ion-content>

View File

@@ -0,0 +1,31 @@
/*!
* Copyright (C) 2021 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
@import '../../../theme/util/mixins';
ion-button {
--color: var(--ion-color-primary-contrast);
width: fit-content;
margin-block: 0;
}
.release-notes {
@include border-radius-in-parallax(var(--border-radius-default));
display: block;
margin: var(--spacing-md);
margin-block-start: 0;
background: var(--ion-item-background);
}

View File

@@ -29,10 +29,12 @@ import {AboutLicenseModalComponent} from './about-license-modal.component';
import {AboutChangelogComponent} from './about-changelog.component'; import {AboutChangelogComponent} from './about-changelog.component';
import {UtilModule} from '../../util/util.module'; import {UtilModule} from '../../util/util.module';
import {IonIconModule} from '../../util/ion-icon/ion-icon.module'; import {IonIconModule} from '../../util/ion-icon/ion-icon.module';
import {AboutReleaseNotesComponent} from './about-release-notes.component';
const settingsRoutes: Routes = [ const settingsRoutes: Routes = [
{path: 'about', component: AboutPageComponent}, {path: 'about', component: AboutPageComponent},
{path: 'about/changelog', component: AboutChangelogComponent}, {path: 'about/changelog', component: AboutReleaseNotesComponent},
{path: 'about/stapps-changelog', component: AboutChangelogComponent},
{path: 'about/imprint', component: AboutPageComponent}, {path: 'about/imprint', component: AboutPageComponent},
{path: 'about/privacy', component: AboutPageComponent}, {path: 'about/privacy', component: AboutPageComponent},
{path: 'about/terms', component: AboutPageComponent}, {path: 'about/terms', component: AboutPageComponent},
@@ -49,6 +51,7 @@ const settingsRoutes: Routes = [
AboutLicensesComponent, AboutLicensesComponent,
AboutLicenseModalComponent, AboutLicenseModalComponent,
AboutChangelogComponent, AboutChangelogComponent,
AboutReleaseNotesComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

View File

@@ -2,11 +2,11 @@ import {Injectable} from '@angular/core';
import {StorageProvider} from '../storage/storage.provider'; import {StorageProvider} from '../storage/storage.provider';
import {ConfigProvider} from '../config/config.provider'; import {ConfigProvider} from '../config/config.provider';
import {ModalController} from '@ionic/angular'; import {ModalController} from '@ionic/angular';
import {Capacitor} from '@capacitor/core';
import {ReleaseNotesComponent} from './release-notes.component'; import {ReleaseNotesComponent} from './release-notes.component';
import {SCAppVersionInfo} from '@openstapps/core'; import {SCAppVersionInfo} from '@openstapps/core';
import {App} from '@capacitor/app'; import {App} from '@capacitor/app';
import {coerce} from 'semver'; import {coerce} from 'semver';
import {Capacitor} from '@capacitor/core';
export const RELEASE_NOTES_SHOWN_KEY = 'release_notes_shown'; export const RELEASE_NOTES_SHOWN_KEY = 'release_notes_shown';
@@ -25,12 +25,11 @@ export class AppVersionService {
if (Capacitor.getPlatform() === 'web') { if (Capacitor.getPlatform() === 'web') {
return; return;
} }
const storedVersion = coerce(
(await this.storage.has(RELEASE_NOTES_SHOWN_KEY))
? await this.storage.get<string>(RELEASE_NOTES_SHOWN_KEY)
: '0.0.0',
)!;
const currentVersion = coerce(await App.getInfo().then(info => info.version))!; const currentVersion = coerce(await App.getInfo().then(info => info.version))!;
if (!(await this.storage.has(RELEASE_NOTES_SHOWN_KEY))) {
await this.storage.put(RELEASE_NOTES_SHOWN_KEY, currentVersion);
}
const storedVersion = coerce(await this.storage.get<string>(RELEASE_NOTES_SHOWN_KEY))!;
return this.config.config.app.versionHistory return this.config.config.app.versionHistory
?.filter(({version}) => { ?.filter(({version}) => {
@@ -39,7 +38,7 @@ export class AppVersionService {
const isNotFutureVersion = semanticVersion.compare(currentVersion) <= 0; const isNotFutureVersion = semanticVersion.compare(currentVersion) <= 0;
return wasNotShown && isNotFutureVersion; return wasNotShown && isNotFutureVersion;
}) })
?.sort((a, b) => coerce(a.version)!.compare(b.version)); ?.sort((a, b) => -coerce(a.version)!.compare(b.version));
} }
/** /**

View File

@@ -0,0 +1,26 @@
.release-notes {
max-width: 16cm;
}
.release-notes ::ng-deep {
h1 {
font-size: 1.5em;
font-weight: bold;
color: var(--ion-color-primary);
}
h2 {
font-size: 1.2em;
font-weight: bold;
}
h3 {
font-size: 1.1em;
font-weight: bold;
}
blockquote {
background: var(--ion-item-background);
border-left: 0.25em solid var(--ion-color-medium);
}
}

View File

@@ -9,7 +9,7 @@ import {UtilModule} from '../../util/util.module';
@Component({ @Component({
selector: 'stapps-release-notes', selector: 'stapps-release-notes',
templateUrl: 'release-notes.html', templateUrl: 'release-notes.html',
styleUrls: ['release-notes.scss'], styleUrls: ['release-notes.scss', 'release-notes-markdown.scss'],
standalone: true, standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [UtilModule, MarkdownModule, ThingTranslateModule, IonicModule, TranslateModule], imports: [UtilModule, MarkdownModule, ThingTranslateModule, IonicModule, TranslateModule],

View File

@@ -13,7 +13,7 @@
<ion-content parallax> <ion-content parallax>
@for (versionInfo of versionInfos; track versionInfo) { @for (versionInfo of versionInfos; track versionInfo) {
<markdown <markdown
class="content-card ion-padding" class="content-card ion-padding release-notes"
[data]="'releaseNotes' | translateSimple: versionInfo" [data]="'releaseNotes' | translateSimple: versionInfo"
></markdown> ></markdown>
} }

View File

@@ -9,5 +9,6 @@ ion-title {
display: block; display: block;
margin: var(--spacing-md); margin: var(--spacing-md);
margin-block-start: 0;
background: var(--ion-item-background); background: var(--ion-item-background);
} }

View File

@@ -81,7 +81,6 @@ export class AuthHelperService {
user[key as keyof SCUserConfiguration] = JSONPath({ user[key as keyof SCUserConfiguration] = JSONPath({
path: this.userConfigurationMap[key as keyof SCUserConfiguration] as string, path: this.userConfigurationMap[key as keyof SCUserConfiguration] as string,
json: userInfo, json: userInfo,
preventEval: true,
})[0]; })[0];
} }
if (user.givenName && user.givenName.length > 0 && user.familyName && user.familyName.length > 0) { if (user.givenName && user.givenName.length > 0 && user.familyName && user.familyName.length > 0) {

View File

@@ -86,6 +86,8 @@ export abstract class AuthService implements IAuthService {
private _authenticatedSubject = new BehaviorSubject<boolean>(false); private _authenticatedSubject = new BehaviorSubject<boolean>(false);
private _loggedInSubject = new BehaviorSubject<boolean>(false);
private _initComplete = new BehaviorSubject<boolean>(false); private _initComplete = new BehaviorSubject<boolean>(false);
protected tokenHandler: TokenRequestHandler; protected tokenHandler: TokenRequestHandler;
@@ -133,6 +135,13 @@ export abstract class AuthService implements IAuthService {
return this._authenticatedSubject.asObservable(); return this._authenticatedSubject.asObservable();
} }
/**
* Similar to isAuthenticated$, but will also return true if the token is expired
*/
get isLoggedIn$(): Observable<boolean> {
return this._loggedInSubject.asObservable();
}
get initComplete$(): Observable<boolean> { get initComplete$(): Observable<boolean> {
return this._initComplete.asObservable(); return this._initComplete.asObservable();
} }
@@ -183,19 +192,20 @@ export abstract class AuthService implements IAuthService {
protected notifyActionListers(action: IAuthAction) { protected notifyActionListers(action: IAuthAction) {
/* eslint-disable unicorn/no-useless-undefined */ /* eslint-disable unicorn/no-useless-undefined */
switch (action.action) { switch (action.action) {
case AuthActions.RefreshFailed:
case AuthActions.SignInFailed: case AuthActions.SignInFailed:
case AuthActions.SignOutSuccess: case AuthActions.SignOutSuccess:
case AuthActions.SignOutFailed: { case AuthActions.SignOutFailed: {
this._tokenSubject.next(undefined); this._tokenSubject.next(undefined);
this._userSubject.next(undefined); this._userSubject.next(undefined);
this._authenticatedSubject.next(false); this._authenticatedSubject.next(false);
this._loggedInSubject.next(false);
break; break;
} }
case AuthActions.LoadTokenFromStorageFailed: { case AuthActions.LoadTokenFromStorageFailed: {
this._tokenSubject.next(undefined); this._tokenSubject.next(undefined);
this._userSubject.next(undefined); this._userSubject.next(undefined);
this._authenticatedSubject.next(false); this._authenticatedSubject.next(false);
this._loggedInSubject.next(false);
this._initComplete.next(true); this._initComplete.next(true);
break; break;
} }
@@ -203,11 +213,13 @@ export abstract class AuthService implements IAuthService {
case AuthActions.RefreshSuccess: { case AuthActions.RefreshSuccess: {
this._tokenSubject.next(action.tokenResponse); this._tokenSubject.next(action.tokenResponse);
this._authenticatedSubject.next(true); this._authenticatedSubject.next(true);
this._loggedInSubject.next(true);
break; break;
} }
case AuthActions.LoadTokenFromStorageSuccess: { case AuthActions.LoadTokenFromStorageSuccess: {
this._tokenSubject.next(action.tokenResponse); this._tokenSubject.next(action.tokenResponse);
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0)); this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
this._loggedInSubject.next(true);
this._initComplete.next(true); this._initComplete.next(true);
break; break;
} }
@@ -442,7 +454,6 @@ export abstract class AuthService implements IAuthService {
public async refreshToken() { public async refreshToken() {
await this.requestTokenRefresh().catch(error => { await this.requestTokenRefresh().catch(error => {
this.storage.removeItem(TOKEN_RESPONSE_KEY);
this.notifyActionListers(AuthActionBuilder.RefreshFailed(error)); this.notifyActionListers(AuthActionBuilder.RefreshFailed(error));
}); });
} }

View File

@@ -81,6 +81,8 @@ export class PAIAAuthService {
private _authenticatedSubject = new BehaviorSubject<boolean>(false); private _authenticatedSubject = new BehaviorSubject<boolean>(false);
private _loggedIn = new BehaviorSubject<boolean>(false);
private _initComplete = new BehaviorSubject<boolean>(false); private _initComplete = new BehaviorSubject<boolean>(false);
protected tokenHandler: PAIATokenRequestHandler; protected tokenHandler: PAIATokenRequestHandler;
@@ -118,6 +120,13 @@ export class PAIAAuthService {
return this._authenticatedSubject.asObservable(); return this._authenticatedSubject.asObservable();
} }
/**
* Similar to isAuthenticated$, but will also return true if the token is expired
*/
get isLoggedIn$(): Observable<boolean> {
return this._loggedIn.asObservable();
}
get initComplete$(): Observable<boolean> { get initComplete$(): Observable<boolean> {
return this._initComplete.asObservable(); return this._initComplete.asObservable();
} }
@@ -170,23 +179,27 @@ export class PAIAAuthService {
this._tokenSubject.next(undefined); this._tokenSubject.next(undefined);
this._userSubject.next(undefined); this._userSubject.next(undefined);
this._authenticatedSubject.next(false); this._authenticatedSubject.next(false);
this._loggedIn.next(false);
break; break;
} }
case AuthActions.LoadTokenFromStorageFailed: { case AuthActions.LoadTokenFromStorageFailed: {
this._tokenSubject.next(undefined); this._tokenSubject.next(undefined);
this._userSubject.next(undefined); this._userSubject.next(undefined);
this._authenticatedSubject.next(false); this._authenticatedSubject.next(false);
this._loggedIn.next(false);
this._initComplete.next(true); this._initComplete.next(true);
break; break;
} }
case AuthActions.SignInSuccess: { case AuthActions.SignInSuccess: {
this._tokenSubject.next(action.tokenResponse); this._tokenSubject.next(action.tokenResponse);
this._authenticatedSubject.next(true); this._authenticatedSubject.next(true);
this._loggedIn.next(true);
break; break;
} }
case AuthActions.LoadTokenFromStorageSuccess: { case AuthActions.LoadTokenFromStorageSuccess: {
this._tokenSubject.next(action.tokenResponse); this._tokenSubject.next(action.tokenResponse);
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0)); this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
this._loggedIn.next(true);
this._initComplete.next(true); this._initComplete.next(true);
break; break;
} }

View File

@@ -67,7 +67,8 @@ describe('ConfigProvider', () => {
it('should fetch app configuration', async () => { it('should fetch app configuration', async () => {
spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(sampleIndexResponse)); spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(sampleIndexResponse));
const result = await configProvider.fetch(); await configProvider.fetch();
const result = configProvider.config;
expect(result).toEqual(sampleIndexResponse); expect(result).toEqual(sampleIndexResponse);
}); });
@@ -110,7 +111,7 @@ describe('ConfigProvider', () => {
expect(storageProviderSpy.has).toHaveBeenCalled(); expect(storageProviderSpy.has).toHaveBeenCalled();
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0); expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
expect(configProvider.client.handshake).toHaveBeenCalled(); expect(configProvider.client.handshake).toHaveBeenCalled();
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name); expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
}); });
it('should throw error on failed initialisation', async () => { it('should throw error on failed initialisation', async () => {
@@ -192,4 +193,31 @@ describe('ConfigProvider', () => {
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name); expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
}); });
it('should fetch new config from remote on init', async () => {
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
storageProviderSpy.get.and.returnValue(Promise.resolve(sampleIndexResponse));
spyOn(configProvider, 'fetch');
await configProvider.init();
expect(configProvider.fetch).toHaveBeenCalled();
});
it('should update the local config with the one from remote', async () => {
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
storageProviderSpy.get.and.returnValue(Promise.resolve(sampleIndexResponse));
const newConfig = structuredClone(sampleIndexResponse);
newConfig.app.name = 'New app name';
spyOn(configProvider.client, 'handshake').and.returnValue(Promise.resolve(newConfig));
await configProvider.init();
// Validate that the initial configuration is loaded
expect(configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
// Fetch the new configuration from the remote
await configProvider.fetch();
// Validate that the new configuration is now set
expect(configProvider.getValue('name')).toEqual(newConfig.app.name);
});
}); });

View File

@@ -83,17 +83,20 @@ export class ConfigProvider {
/** /**
* Fetches configuration from backend * Fetches configuration from backend
*/ */
async fetch(): Promise<SCIndexResponse> { async fetch(): Promise<void> {
try { try {
const isOffline = await firstValueFrom(this.internetConnectionService.offline$); const isOffline = await firstValueFrom(this.internetConnectionService.offline$);
if (isOffline) { if (isOffline) {
throw new Error('Device is offline.'); throw new Error('Device is offline.');
} else { } else {
return await this.client.handshake(this.scVersion); const fetchedConfig: SCIndexResponse = await this.client.handshake(this.scVersion);
await this.set(fetchedConfig);
this.logger.log(`Configuration updated from remote`);
} }
} catch (error) { } catch (error) {
const error_ = error instanceof Error ? new ConfigFetchError(error.message) : new ConfigFetchError(); const error_ = error instanceof Error ? new ConfigFetchError(error.message) : new ConfigFetchError();
throw error_; this.logger.warn(`Failed to fetch remote configuration:`, error_);
throw error_; // Rethrow the error to handle it in init()
} }
} }
@@ -121,40 +124,33 @@ export class ConfigProvider {
/** /**
* Initialises the ConfigProvider * Initialises the ConfigProvider
* @throws ConfigInitError if no configuration could be loaded. * @throws ConfigInitError if no configuration could be loaded both locally and remote.
* @throws WrongConfigVersionInStorage if fetch failed and saved config has wrong SCVersion
*/ */
async init(): Promise<void> { async init(): Promise<void> {
let loadError;
let fetchError;
// load saved configuration
try { try {
// Attempt to load the configuration from local storage
this.config = await this.loadLocal(); this.config = await this.loadLocal();
this.firstSession = false; this.firstSession = false;
this.logger.log(`initialised configuration from storage`); this.logger.log(`initialised configuration from storage`);
// Check if the stored configuration has the correct version
if (this.config.backend.SCVersion.split('.')[0] !== this.scVersion.split('.')[0]) { if (this.config.backend.SCVersion.split('.')[0] !== this.scVersion.split('.')[0]) {
loadError = new WrongConfigVersionInStorage(this.scVersion, this.config.backend.SCVersion); throw new WrongConfigVersionInStorage(this.scVersion, this.config.backend.SCVersion);
} }
} catch (error) {
loadError = error; // Fetch the remote configuration in a non-blocking manner
} void this.fetch();
// fetch remote configuration from backend } catch (loadError) {
try {
const fetchedConfig: SCIndexResponse = await this.fetch();
await this.set(fetchedConfig);
this.logger.log(`initialised configuration from remote`);
} catch (error) {
fetchError = error;
}
// check for occurred errors and throw them
if (loadError !== undefined && fetchError !== undefined) {
throw new ConfigInitError();
}
if (loadError !== undefined) {
this.logger.warn(loadError); this.logger.warn(loadError);
}
if (fetchError !== undefined) { try {
this.logger.warn(fetchError); // If local loading fails, immediately try to fetch the configuration from remote
await this.fetch();
} catch (fetchError) {
this.logger.warn(`Failed to fetch remote configuration:`, fetchError);
// If both local loading and remote fetching fail, throw ConfigInitError
throw new ConfigInitError();
}
} }
} }

View File

@@ -80,13 +80,12 @@
</ion-item> </ion-item>
<ion-item> <ion-item>
<ion-checkbox <ion-checkbox
class="ion-text-wrap"
color="primary" color="primary"
label-placement="end" label-placement="end"
justify="start" justify="start"
[(ngModel)]="termsAgree" [(ngModel)]="termsAgree"
name="termsAgree" name="termsAgree"
>{{ 'feedback.form.termsAgree.0' | translate }}</ion-checkbox ><span class="ion-text-wrap">{{ 'feedback.form.termsAgree.0' | translate }}</span></ion-checkbox
> >
</ion-item> </ion-item>
<ion-item lines="none"> <ion-item lines="none">
@@ -104,7 +103,9 @@
justify="start" justify="start"
[(ngModel)]="protocolDataAgree" [(ngModel)]="protocolDataAgree"
name="protocolDataAgree" name="protocolDataAgree"
>{{ 'feedback.form.protocolDataAgree' | translate }}</ion-checkbox ><span class="ion-text-wrap">{{
'feedback.form.protocolDataAgree' | translate
}}</span></ion-checkbox
> >
</ion-item> </ion-item>
<ion-card> <ion-card>

View File

@@ -2,7 +2,7 @@ import {ChangeDetectionStrategy, Component, ElementRef, Input} from '@angular/co
import {SCIdCard} from '@openstapps/core'; import {SCIdCard} from '@openstapps/core';
import {ThingTranslateModule} from '../../translation/thing-translate.module'; import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {AsyncPipe, TitleCasePipe} from '@angular/common'; import {AsyncPipe, TitleCasePipe} from '@angular/common';
import {InRangeNowPipe, ToDateRangePipe} from '../../util/in-range.pipe'; import {IntervalIsNowPipe, ToDateIntervalPipe} from '../../util/in-range.pipe';
import {TranslateModule} from '@ngx-translate/core'; import {TranslateModule} from '@ngx-translate/core';
import {AnimationController, ModalController} from '@ionic/angular'; import {AnimationController, ModalController} from '@ionic/angular';
import {ScreenBrightness} from '@capacitor-community/screen-brightness'; import {ScreenBrightness} from '@capacitor-community/screen-brightness';
@@ -16,7 +16,14 @@ import {iosDuration, iosEasing, mdDuration, mdEasing} from 'src/app/animation/ea
styleUrls: ['id-card.scss'], styleUrls: ['id-card.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [ThingTranslateModule, InRangeNowPipe, ToDateRangePipe, AsyncPipe, TranslateModule, TitleCasePipe], imports: [
ThingTranslateModule,
IntervalIsNowPipe,
ToDateIntervalPipe,
AsyncPipe,
TranslateModule,
TitleCasePipe,
],
}) })
export class IdCardComponent { export class IdCardComponent {
@Input({required: true}) item: SCIdCard; @Input({required: true}) item: SCIdCard;

View File

@@ -4,6 +4,6 @@
draggable="false" draggable="false"
(click)="presentFullscreen()" (click)="presentFullscreen()"
/> />
@if (item.validity && (item.validity | toDateRange | isInRangeNow | async) === false) { @if (item.validity && (item.validity | rangeToDateInterval | dfnsIntervalIsNow | async) === false) {
<div class="expired">{{ 'profile.userInfo.expired' | translate | titlecase }}</div> <div class="expired">{{ 'profile.userInfo.expired' | translate | titlecase }}</div>
} }

View File

@@ -23,9 +23,9 @@ export class IdCardsProvider {
this.encryptedStorageProvider.get<SCIdCard[]>('id-cards') as Promise<SCIdCard[]>, this.encryptedStorageProvider.get<SCIdCard[]>('id-cards') as Promise<SCIdCard[]>,
).pipe(filter(it => it !== undefined)); ).pipe(filter(it => it !== undefined));
return auth.isAuthenticated$.pipe( return auth.isLoggedIn$.pipe(
mergeMap(isAuthenticated => mergeMap(isLoggedIn =>
isAuthenticated isLoggedIn
? feature ? feature
? storedIdCards.pipe( ? storedIdCards.pipe(
concatWith( concatWith(
@@ -41,7 +41,7 @@ export class IdCardsProvider {
mergeMap(user => this.fetchFallbackIdCards(user)), mergeMap(user => this.fetchFallbackIdCards(user)),
startWith([]), startWith([]),
) )
: of([]).pipe(tap(() => this.encryptedStorageProvider.delete('id-cards'))), : of([]).pipe(tap({next: () => this.encryptedStorageProvider.delete('id-cards')})),
), ),
); );
} }
@@ -54,7 +54,7 @@ export class IdCardsProvider {
}, },
responseType: 'json', responseType: 'json',
}) })
.pipe(tap(idCards => this.encryptedStorageProvider.set('id-cards', idCards))); .pipe(tap({next: idCards => this.encryptedStorageProvider.set('id-cards', idCards)}));
} }
private fetchFallbackIdCards(user: SCUserConfiguration): Observable<SCIdCard[]> { private fetchFallbackIdCards(user: SCUserConfiguration): Observable<SCIdCard[]> {

View File

@@ -7,7 +7,7 @@ import {SCAuthorizationProviderType} from '@openstapps/core';
import {EncryptedStorageProvider} from '../storage/encrypted-storage.provider'; import {EncryptedStorageProvider} from '../storage/encrypted-storage.provider';
class FakeAuth { class FakeAuth {
isAuthenticated$ = new BehaviorSubject(false); isLoggedIn$ = new BehaviorSubject(false);
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
getValidToken() {} getValidToken() {}
@@ -42,7 +42,7 @@ describe('IdCards', () => {
}); });
it('should emit network result when logged in', async () => { it('should emit network result when logged in', async () => {
fakeAuth.isAuthenticated$.next(true); fakeAuth.isLoggedIn$.next(true);
httpClient.get = jasmine.createSpy().and.returnValue(of(['abc'])); httpClient.get = jasmine.createSpy().and.returnValue(of(['abc']));
fakeAuth.getValidToken = jasmine.createSpy().and.resolveTo({accessToken: 'fake-token'}); fakeAuth.getValidToken = jasmine.createSpy().and.resolveTo({accessToken: 'fake-token'});
const provider = new IdCardsProvider(authHelper, configProvider, httpClient, encryptedStorageProvider); const provider = new IdCardsProvider(authHelper, configProvider, httpClient, encryptedStorageProvider);
@@ -63,7 +63,7 @@ describe('IdCards', () => {
expect(await firstValueFrom(observable)).toEqual([]); expect(await firstValueFrom(observable)).toEqual([]);
httpClient.get = jasmine.createSpy().and.returnValue(of(['abc'])); httpClient.get = jasmine.createSpy().and.returnValue(of(['abc']));
fakeAuth.getValidToken = jasmine.createSpy().and.resolveTo({accessToken: 'fake-token'}); fakeAuth.getValidToken = jasmine.createSpy().and.resolveTo({accessToken: 'fake-token'});
fakeAuth.isAuthenticated$.next(true); fakeAuth.isLoggedIn$.next(true);
// this is counter-intuitive, but because we unsubscribed above the first value // this is counter-intuitive, but because we unsubscribed above the first value
// will now contain the network result. // will now contain the network result.
expect(await firstValueFrom(observable)).toEqual(['abc' as never]); expect(await firstValueFrom(observable)).toEqual(['abc' as never]);

View File

@@ -6,74 +6,56 @@
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAr purpose. see the gnu general public license for
* more details. * more details.
* *
* You should have received a copy of the GNU General Public License along with * you should have received a copy of the gnu general public license along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. if not, see <https://www.gnu.org/licenses/>.
*/ */
import {Component, DestroyRef, inject, Input, OnInit} from '@angular/core'; import {Component, inject, input} from '@angular/core';
import {SCSection} from '../../../../config/profile-page-sections'; import {SCSection} from '../../../../config/profile-page-sections';
import {AuthHelperService} from '../../auth/auth-helper.service'; import {AuthHelperService} from '../../auth/auth-helper.service';
import {Observable} from 'rxjs'; import {mergeMap, of} from 'rxjs';
import {SCAuthorizationProviderType} from '@openstapps/core';
import Swiper from 'swiper'; import Swiper from 'swiper';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; import {toObservable, toSignal} from '@angular/core/rxjs-interop';
@Component({ @Component({
selector: 'stapps-profile-page-section', selector: 'stapps-profile-page-section',
templateUrl: 'profile-page-section.html', templateUrl: 'profile-page-section.html',
styleUrls: ['profile-page-section.scss'], styleUrls: ['profile-page-section.scss'],
}) })
export class ProfilePageSectionComponent implements OnInit { export class ProfilePageSectionComponent {
@Input() item: SCSection; item = input.required<SCSection>();
@Input() minSlideWidth = 110; minSlideWidth = input(110);
isLoggedIn: boolean; authHelper = inject(AuthHelperService);
loggedIn = toSignal(
toObservable(this.item).pipe(
mergeMap(item =>
item.authProvider ? this.authHelper.getProvider(item.authProvider).isLoggedIn$ : of(false),
),
),
);
isEnd = false; isEnd = false;
isBeginning = true; isBeginning = true;
slidesPerView: number; slidesPerView?: number;
slidesFillScreen = false; slidesFillScreen = false;
data: {
[key in SCAuthorizationProviderType]: {loggedIn$: Observable<boolean>};
} = {
default: {
loggedIn$: this.authHelper.getProvider('default').isAuthenticated$,
},
paia: {
loggedIn$: this.authHelper.getProvider('paia').isAuthenticated$,
},
};
destroy$ = inject(DestroyRef);
constructor(private authHelper: AuthHelperService) {}
ngOnInit() {
if (this.item.authProvider) {
this.data[this.item.authProvider].loggedIn$
.pipe(takeUntilDestroyed(this.destroy$))
.subscribe(loggedIn => {
this.isLoggedIn = loggedIn;
});
}
}
activeIndexChange(swiper: Swiper) { activeIndexChange(swiper: Swiper) {
this.isBeginning = swiper.isBeginning; this.isBeginning = swiper.isBeginning;
this.isEnd = swiper.isEnd; this.isEnd = swiper.isEnd;
this.slidesFillScreen = this.slidesPerView >= swiper.slides.length; this.slidesFillScreen = this.slidesPerView! >= swiper.slides.length;
} }
resizeSwiper(resizeEvent: ResizeObserverEntry, swiper: Swiper) { resizeSwiper(resizeEvent: ResizeObserverEntry, swiper: Swiper) {
const slidesPerView = const slidesPerView =
Math.floor((resizeEvent.contentRect.width - this.minSlideWidth / 2) / this.minSlideWidth) + 0.5; Math.floor((resizeEvent.contentRect.width - this.minSlideWidth() / 2) / this.minSlideWidth()) + 0.5;
if (slidesPerView > 1 && slidesPerView !== this.slidesPerView) { if (slidesPerView > 1 && slidesPerView !== this.slidesPerView) {
this.slidesPerView = slidesPerView; this.slidesPerView = slidesPerView;
@@ -84,16 +66,13 @@ export class ProfilePageSectionComponent implements OnInit {
} }
async toggleLogIn() { async toggleLogIn() {
if (!this.item.authProvider) return; const providerType = this.item().authProvider;
await (this.isLoggedIn ? this.signOut(this.item.authProvider) : this.signIn(this.item.authProvider)); if (!providerType) return;
} if (this.loggedIn()) {
await this.authHelper.getProvider(providerType).signOut();
async signIn(providerType: SCAuthorizationProviderType) { await this.authHelper.endBrowserSession(providerType);
await this.authHelper.getProvider(providerType).signIn(); } else {
} await this.authHelper.getProvider(providerType).signIn();
}
async signOut(providerType: SCAuthorizationProviderType) {
await this.authHelper.getProvider(providerType).signOut();
await this.authHelper.endBrowserSession(providerType);
} }
} }

View File

@@ -13,24 +13,24 @@
~ this program. If not, see <https://www.gnu.org/licenses/>. ~ this program. If not, see <https://www.gnu.org/licenses/>.
--> -->
<stapps-section [title]="'name' | translateSimple: item"> <stapps-section [title]="'name' | translateSimple: item()">
@if (item.authProvider) { @if (item().authProvider) {
<ion-button slot="button-end" fill="clear" color="dark" (click)="toggleLogIn()"> <ion-button slot="button-end" fill="clear" color="dark" (click)="toggleLogIn()">
@if (isLoggedIn) { @if (loggedIn()) {
<ion-icon slot="end" name="logout"></ion-icon> <ion-icon slot="end" name="logout"></ion-icon>
} @else { } @else {
<ion-icon slot="end" name="login"></ion-icon> <ion-icon slot="end" name="login"></ion-icon>
} }
<ion-label>{{ 'profile.buttons.default.log_' + (isLoggedIn ? 'out' : 'in') | translate }}</ion-label> <ion-label>{{ 'profile.buttons.default.log_' + (loggedIn() ? 'out' : 'in') | translate }}</ion-label>
</ion-button> </ion-button>
} }
<simple-swiper> <simple-swiper>
@for (link of item.links; track link) { @for (link of item().links; track link) {
<ion-item <ion-item
lines="none" lines="none"
[routerLink]="link.link" [routerLink]="link.link"
[disabled]="link.needsAuth && !isLoggedIn" [disabled]="link.needsAuth && !loggedIn()"
[detail]="false" [detail]="false"
> >
<div> <div>

View File

@@ -1,7 +1,7 @@
import {Pipe, PipeTransform} from '@angular/core'; import {Pipe, PipeTransform} from '@angular/core';
import {SCRange, isInRange, SCISO8601DateRange} from '@openstapps/core'; import {SCRange, isInRange, SCISO8601DateRange} from '@openstapps/core';
import {merge, Observable, timer} from 'rxjs'; import {NormalizedInterval, differenceInMilliseconds, interval} from 'date-fns';
import {distinctUntilChanged, map, startWith} from 'rxjs/operators'; import {EMPTY, Observable, SchedulerLike, asyncScheduler, concat, defer, map, of, timer} from 'rxjs';
@Pipe({ @Pipe({
name: 'isInRange', name: 'isInRange',
@@ -14,28 +14,51 @@ export class InRangePipe implements PipeTransform {
} }
} }
export const MIN_DATE = new Date(0);
export const MAX_DATE = new Date(1e15);
// Maximum safe delay for JavaScript timers (~24.8 days)
export const MAX_DELAY = 2 ** 31 - 1;
@Pipe({ @Pipe({
name: 'toDateRange', name: 'rangeToDateInterval',
pure: true, pure: true,
standalone: true, standalone: true,
}) })
export class ToDateRangePipe implements PipeTransform { export class ToDateIntervalPipe implements PipeTransform {
transform(value: SCISO8601DateRange): SCRange<Date> { transform(value: SCISO8601DateRange): NormalizedInterval {
return Object.fromEntries(Object.entries(value).map(([key, value]) => [key, new Date(value)])); return interval(new Date(value.gte ?? value.gt ?? MIN_DATE), new Date(value.lte ?? value.lt ?? MAX_DATE));
} }
} }
/**
* Returns an Observable that will change its value when the current date is within the given interval.
*/
export function isWithinIntervalObservable(
value: NormalizedInterval,
scheduler: SchedulerLike = asyncScheduler,
): Observable<boolean> {
return defer(() => {
const now = scheduler.now();
const activate = differenceInMilliseconds(value.start, now);
const deactivate = differenceInMilliseconds(value.end, now);
return concat(
of(activate <= 0 && deactivate > 0),
activate <= 0 ? EMPTY : timer(value.start, scheduler).pipe(map(() => true)),
differenceInMilliseconds(value.end, now) >= MAX_DELAY || deactivate <= 0
? EMPTY
: timer(value.end, scheduler).pipe(map(() => false)),
);
});
}
@Pipe({ @Pipe({
name: 'isInRangeNow', name: 'dfnsIntervalIsNow',
pure: true, pure: true,
standalone: true, standalone: true,
}) })
export class InRangeNowPipe implements PipeTransform { export class IntervalIsNowPipe implements PipeTransform {
transform(value: SCRange<Date>): Observable<boolean> { transform(value: NormalizedInterval): Observable<boolean> {
return merge(timer(value.lte || value.lt || 0), timer(value.gte || value.gt || 0)).pipe( return isWithinIntervalObservable(value);
startWith(0),
map(() => isInRange(new Date(), value)),
distinctUntilChanged(),
);
} }
} }

View File

@@ -0,0 +1,46 @@
import {TestScheduler} from 'rxjs/testing';
import {MAX_DATE, MIN_DATE, isWithinIntervalObservable} from './in-range.pipe';
import {interval} from 'date-fns';
import {MAX_DELAY} from './in-range.pipe';
/**
* Test macro
*/
function test(range: [number | undefined, number | undefined], subscribe: string, expected: string) {
const testScheduler = new TestScheduler((actual, expected) => {
expect(actual).withContext(actual.map(JSON.stringify).join('\n')).toEqual(expected);
});
it(`should emit "${expected}" when "${subscribe}" for range ${range[0] ?? ''}..${range[1] ?? ''}`, () => {
testScheduler.run(({expectObservable}) => {
expectObservable(
isWithinIntervalObservable(
interval(new Date(range[0] ?? MIN_DATE), new Date(range[1] ?? MAX_DATE)),
testScheduler,
),
subscribe,
).toBe(expected, {t: true, f: false});
});
});
}
describe('isWithinIntervalObservable', () => {
test([500, undefined], '1s ^', '1s (t|)');
test([1000, undefined], '500ms ^', '500ms f 499ms (t|)');
test([undefined, 500], '1s ^', '1s (f|)');
test([undefined, 1000], '500ms ^', '500ms t 499ms (f|)');
test([1000, 2000], '500ms ^', '500ms f 499ms t 999ms (f|)');
test([500, 1000], '1500ms ^', '1500ms (f|)');
test([500, 1000], '1s ^', '1000ms (f|)');
test([500, 1000], '999ms ^', '999ms t (f|)');
test([500, 1000], '500ms ^', '500ms t 499ms (f|)');
test([500, 1000], '499ms ^', '499ms f t 499ms (f|)');
test([500, 1000], '^ 750ms !', 'f 499ms t');
// Long interval test case: emit `true` and then complete (EMPTY) because `end` is beyond the delay limit
test([500, 500 + MAX_DELAY + 2000], '1s ^', '1s (t|)');
});

View File

@@ -1,221 +0,0 @@
## [2.1.1](https://gitlab.com/openstapps/app/compare/v2.0.1...v2.1.1) (2023-05-10)
### Bug Fixes
- autofocus searchbar only when no default data is displayed ([e90286f](https://gitlab.com/openstapps/app/commit/e90286fc6814f5c40af3e297be42f23128b991be))
- breadcrumbs are under parallax ([9e160e8](https://gitlab.com/openstapps/app/commit/9e160e8d1ee9409e4fbe518c9dd9748705e680e1))
- browser logout only if endSession url defined ([7f6de94](https://gitlab.com/openstapps/app/commit/7f6de94ab572be66d7f10758c37dcf10af46b4e0)), closes [#395](https://gitlab.com/openstapps/app/issues/395)
- can't select some list elements on safari 16.4 ([3e99d7f](https://gitlab.com/openstapps/app/commit/3e99d7fa8fcae4538e1afe6a017570b0cb6ff45e))
- canteen view removes item select listener on view exit ([05e996a](https://gitlab.com/openstapps/app/commit/05e996ae9052b11c23dc1093ef526f08e3e2e6b6))
- catalog module semester selection ([afbd1fc](https://gitlab.com/openstapps/app/commit/afbd1fc048997acbc0113f8957016f8947b58626))
- catalog semester selection ([a8c7d5a](https://gitlab.com/openstapps/app/commit/a8c7d5ab5934adf853cc40c1df311178df54057e))
- data detail local favorite fallback causing duplicate nested favorite view ([dff4a95](https://gitlab.com/openstapps/app/commit/dff4a95acc55574b4872b0e4e39555cce0b2fd60))
- data-detail favorite button color leaking to list items ([95f2da2](https://gitlab.com/openstapps/app/commit/95f2da2def39ec56f40a660a63e5f7fddb4b3d53))
- location flow on iOS devices ([f207e02](https://gitlab.com/openstapps/app/commit/f207e029f1b30624bf411a57b3c552ef259e13ed))
- parallax broken since safari 16.4 ([0f970fa](https://gitlab.com/openstapps/app/commit/0f970fa1f164a310e24a85140d8bf0da21e5a5f1))
- remove infinite scroll e2e test ([47565e5](https://gitlab.com/openstapps/app/commit/47565e51b0dda5c8227238b6dc19f0d277408429))
- replace breadcrumb popover with simply expanding the breadcrumbs ([1318cbc](https://gitlab.com/openstapps/app/commit/1318cbca7f0cf72e10d96fff1a1116ba073fe8dc))
- schedule tabs navigating to the wrong url ([abf2ab6](https://gitlab.com/openstapps/app/commit/abf2ab6a5a94941d439adf54ec677332823892db))
- translate simple pipe doesn't update on language changes ([f5ca150](https://gitlab.com/openstapps/app/commit/f5ca1508fb9d95693615bfb9e03bc127bd83be00))
- typo in catalog provider query ([f49c44f](https://gitlab.com/openstapps/app/commit/f49c44f5c53780e4794dc1ef4cbacfb20cabbd97))
- workaround for side menu items not being active on page load ([947cab4](https://gitlab.com/openstapps/app/commit/947cab458ca770f116d28a1f22687ae620e71b59))
### Features
- add content to empty catalogs ([982fb16](https://gitlab.com/openstapps/app/commit/982fb1653b3c1253aac9366733f14c22c94d2537))
- add easy way to configure search filtering for nested properties ([2220ab2](https://gitlab.com/openstapps/app/commit/2220ab24b385188515da7c176bf9c1ac72651fd9))
- dark theme ([e75a466](https://gitlab.com/openstapps/app/commit/e75a46633ca3685d6044eb9a8b2fd670f2cd030f))
- dashboard search rework ([8c30a47](https://gitlab.com/openstapps/app/commit/8c30a47706f07eb222fac47ad7fed61f9044328a))
- implement custom cdk virtual scroll behavior ([968cb72](https://gitlab.com/openstapps/app/commit/968cb729575c529fd6d1d35da1b50a8689057c46))
- optional logout from identity provider ([8cd2d77](https://gitlab.com/openstapps/app/commit/8cd2d777ab3a67b1ab24f03aa50a3ff73550c3d2)), closes [#372](https://gitlab.com/openstapps/app/issues/372)
- revamp dashboard mensa section ([33a74d9](https://gitlab.com/openstapps/app/commit/33a74d96ae92137f53a775e90bff99e5f2d41f6a))
- rework settings page design ([2f1298c](https://gitlab.com/openstapps/app/commit/2f1298c9d7df25d2a16576245ea62c1b6094e507))
- show in-place in date series modal, resolves [#385](https://gitlab.com/openstapps/app/issues/385) ([22e70ae](https://gitlab.com/openstapps/app/commit/22e70ae92b35578b559e6644dccb8d4bfd06af1e)), closes [#386](https://gitlab.com/openstapps/app/issues/386) [#388](https://gitlab.com/openstapps/app/issues/388)
- transition to full sidebar at xl instead of lg ([cc939f3](https://gitlab.com/openstapps/app/commit/cc939f38873833b7cc0260525a2ecd536f27bfa5))
## [2.0.1](https://gitlab.com/openstapps/app/compare/v2.0.0...v2.0.1) (2023-02-13)
### Bug Fixes
- assessment segments can become unreadable ([939fb6e](https://gitlab.com/openstapps/app/commit/939fb6ef0f11b40cb71fbe61da90f50b1f75c3f7))
- login button not easily found ([11d1ac3](https://gitlab.com/openstapps/app/commit/11d1ac3f7ce27c2822ea8f839df3f3dffbd6c020))
- remove misleading assessment calculations ([aefae33](https://gitlab.com/openstapps/app/commit/aefae33d5c9fa9ee3efe346e45429aca79ae3c48))
- right-align add event detail chip ([1eee652](https://gitlab.com/openstapps/app/commit/1eee652533c6b8f613ce09df9c3421f89209419a))
### Features
- offline notice ([9b4caf5](https://gitlab.com/openstapps/app/commit/9b4caf526ffb53ec8d8885342323fcc52fd9fc09))
- separate prettier from eslint ([a88d000](https://gitlab.com/openstapps/app/commit/a88d000ccd6cbdeb5fbb07d209f2491023f9d76c))
# [2.0.0](https://gitlab.com/openstapps/app/compare/v0.0.1...v2.0.0) (2023-01-11)
### Bug Fixes
- daia_url missing in environment configs ([863a3ff](https://gitlab.com/openstapps/app/commit/863a3ffd488425e3313ab9b812c4b6d50c68a244))
- 404 on all surge links ([f1b4930](https://gitlab.com/openstapps/app/commit/f1b4930a3068e73aee20b4c3d71dac551ab60c35))
- add areaServed to person detail ([488150f](https://gitlab.com/openstapps/app/commit/488150f7f5558c05c1ec8a71afcb9f9a37e68a37))
- add event popover expanding beyond screen width ([046a95b](https://gitlab.com/openstapps/app/commit/046a95ba1dca3f5ded7e5555d3167f52f95be107))
- add location info to dates from timetable ([92adb9d](https://gitlab.com/openstapps/app/commit/92adb9dd2db18027dcc327433027e28c81ecbd4b)), closes [#344](https://gitlab.com/openstapps/app/issues/344)
- add missing profile translation ([cdb6ac4](https://gitlab.com/openstapps/app/commit/cdb6ac4084f8704d7f2336387a837b86f78c062b))
- add nav button to schedule page ([e628f39](https://gitlab.com/openstapps/app/commit/e628f396e22e51da2c9f2489fe89e42ccf474e2b))
- add openingHours config and catch its errors ([6125d43](https://gitlab.com/openstapps/app/commit/6125d43e8c18f2bf2afda67c0ff72e00d98ab34f))
- add PKCE parameters for PAIA auth ([f3e83bf](https://gitlab.com/openstapps/app/commit/f3e83bfcc88423f0935a060ccd0bf6198da58351))
- address late init from ionic components ([0bce9e5](https://gitlab.com/openstapps/app/commit/0bce9e5452fc5d05123756348dc30308de675bfa))
- adjust code to overcome the breaking changes (ionic 4 to 5) ([f779042](https://gitlab.com/openstapps/app/commit/f7790426cd2da4a6b33e2aa73783943f45b3de02)), closes [#70](https://gitlab.com/openstapps/app/issues/70)
- adjust hebis catalog templates ([83d9a4a](https://gitlab.com/openstapps/app/commit/83d9a4a8b8fe5b8687c72a717b3a2964524006e0))
- adjust library account user info ([bafabb1](https://gitlab.com/openstapps/app/commit/bafabb1d4ec299e2bea43cd4b8442ef33be2329a)), closes [#331](https://gitlab.com/openstapps/app/issues/331)
- adjust npm docker scripts and typos ([82bb15b](https://gitlab.com/openstapps/app/commit/82bb15b863e2d2e4df20244fda2f2e0d049ff43f))
- angular1 ng-if leftover ([25434d5](https://gitlab.com/openstapps/app/commit/25434d54e3800fd72a6c5d9188fb11f441d73aa9))
- assign navigation app name dynamically ([90b9733](https://gitlab.com/openstapps/app/commit/90b97339d3948b0864f634519416fe4a458b459f))
- background fetch crashing android app ([3316ad9](https://gitlab.com/openstapps/app/commit/3316ad9169ed2b29a2755405589213f824aec9d1))
- calculating SCDateSeries for next unit view ([82ba5f8](https://gitlab.com/openstapps/app/commit/82ba5f81211fb10cc5fde04991856567c4ac9680))
- canteen module layout ([b89f5c4](https://gitlab.com/openstapps/app/commit/b89f5c4edd1ed14f7529edc4e4ea54f9d98fda7c))
- canteen module layout ([6f7c680](https://gitlab.com/openstapps/app/commit/6f7c680ed89f027d863ebc02f5b24895d84f32e4))
- cards not having rounded corners in safari ([8a04a43](https://gitlab.com/openstapps/app/commit/8a04a439032920ead799f8b7483f29b896797c37))
- catch error `Setting "language" not provided` ([584878d](https://gitlab.com/openstapps/app/commit/584878d9503b8406b6ee7ec69dde5b8b3c4fd954))
- CI stage/job setup ([ae429ca](https://gitlab.com/openstapps/app/commit/ae429ca5fb3b5f10cad377d37b251806b3dabf6c))
- config.get issue by updating ionic ([9386351](https://gitlab.com/openstapps/app/commit/93863510fac32ed5b887011175a4807df3f522b8))
- **config:** fix catch ConfigFetchError in getValue ([161da63](https://gitlab.com/openstapps/app/commit/161da630ea59f6205ee53dece950972d4f36ada5)), closes [#46](https://gitlab.com/openstapps/app/issues/46)
- correct data path color ([0d755bc](https://gitlab.com/openstapps/app/commit/0d755bcbd3d6fea59a4f7a59981fd28844ff90d5))
- correct html whitespace handling for icon detection ([9bc3642](https://gitlab.com/openstapps/app/commit/9bc3642990b687dd524470fd26df80351aa85f1e))
- daia availability ([13cee2d](https://gitlab.com/openstapps/app/commit/13cee2d4261c7301c1c763446ae44dcdd005172d))
- dashboard next unit structural directive causing animation issues ([c8f6a27](https://gitlab.com/openstapps/app/commit/c8f6a27c571e51bcc0ac0120968e6bc9a20c8dd7))
- **data:** fix and adjust detail test using translation ([478f49a](https://gitlab.com/openstapps/app/commit/478f49a8744211b3c9458b3dadc791d62a46ae46)), closes [#50](https://gitlab.com/openstapps/app/issues/50)
- **data:** fix template and other consistency issues ([c3bc227](https://gitlab.com/openstapps/app/commit/c3bc227a3ca4a295b2b31bfe7fd34830b33c9f05))
- detail page when dish of mensa selected ([e5c2270](https://gitlab.com/openstapps/app/commit/e5c227073a183a1c562e17f3fe14a51048d01637)), closes [#140](https://gitlab.com/openstapps/app/issues/140)
- download events should respect selection ([28fbfef](https://gitlab.com/openstapps/app/commit/28fbfef18cc3b457f7020a70157ea7a4fff345d0))
- enable background fetch on iOS ([a1592f8](https://gitlab.com/openstapps/app/commit/a1592f84cc48f7cae8c55ef806cddbe806034bb5))
- enable overflow for day labels in schedule ([1195c5f](https://gitlab.com/openstapps/app/commit/1195c5ffc8cea07f1e224d92a7fb25aa5858bf0a))
- encode URI parameter to proxy URI ([bc13cc5](https://gitlab.com/openstapps/app/commit/bc13cc5e1fe6144fe0a0e53c0748a154844a5c29)), closes [#326](https://gitlab.com/openstapps/app/issues/326)
- extend landing period button not working on android ([0caa69c](https://gitlab.com/openstapps/app/commit/0caa69c28cbb2f962b70a1da13659739c1c6dd3e)), closes [#333](https://gitlab.com/openstapps/app/issues/333)
- failing native http requests with body ([fed4f20](https://gitlab.com/openstapps/app/commit/fed4f20c3cf43221512f3d2b6dd3c3fe7a4cf43a))
- feedback not allowing valid emails ([cf74c8e](https://gitlab.com/openstapps/app/commit/cf74c8e19f8bd34a31d5af931781e84be2c04dea)), closes [#349](https://gitlab.com/openstapps/app/issues/349)
- fix issues found by ng build for production ([a503811](https://gitlab.com/openstapps/app/commit/a503811c1cfcf909571af766ccd884856aad8ec9)), closes [#48](https://gitlab.com/openstapps/app/issues/48)
- fix various typos ([ad0dae4](https://gitlab.com/openstapps/app/commit/ad0dae46ff04d28551d2ece950d9a4d3442541d2))
- fixate webdriver to match used chrome version ([24dbb42](https://gitlab.com/openstapps/app/commit/24dbb42b345458b7dbdd17b2759824b3b68cb0e4))
- generate library online links properly ([9854541](https://gitlab.com/openstapps/app/commit/9854541a0c062c31bce167673586dccc8af81785)), closes [#340](https://gitlab.com/openstapps/app/issues/340)
- handle prices as an optional property ([9e71efc](https://gitlab.com/openstapps/app/commit/9e71efca9f7b1086db26f580192d6b349bdcb964)), closes [#219](https://gitlab.com/openstapps/app/issues/219)
- header logo changing size on ios navigate ([38f0a30](https://gitlab.com/openstapps/app/commit/38f0a300769a5b7cda35af0927c17099f93981b8))
- ignore null-island location ([d3188f5](https://gitlab.com/openstapps/app/commit/d3188f50905d610097de6c90bc58e6373d30e0dc)), closes [#149](https://gitlab.com/openstapps/app/issues/149)
- item not available in offer template ([7b402d6](https://gitlab.com/openstapps/app/commit/7b402d61c30aed81a5671d778a38c8393a5bc7c8)), closes [#110](https://gitlab.com/openstapps/app/issues/110)
- library account missing ready for pickup ([e504d8c](https://gitlab.com/openstapps/app/commit/e504d8cf6dd1c12fcb8f6a315527337313662385)), closes [#330](https://gitlab.com/openstapps/app/issues/330)
- library fines should load item title only if needed ([cbb949e](https://gitlab.com/openstapps/app/commit/cbb949e3977a5821e6bd1b654dec66a82e4d8c81)), closes [#342](https://gitlab.com/openstapps/app/issues/342)
- links of timetable tabs ([837c69b](https://gitlab.com/openstapps/app/commit/837c69bb21c92a91259051d5680e1073b390fc0e)), closes [#144](https://gitlab.com/openstapps/app/issues/144)
- logged out button not showing on profile ([ebdc14d](https://gitlab.com/openstapps/app/commit/ebdc14d3c398ac7564c077757c564f4e414fe244)), closes [#239](https://gitlab.com/openstapps/app/issues/239)
- make action chips react to changes of their item ([c0d0b1b](https://gitlab.com/openstapps/app/commit/c0d0b1bd9934e8d9e23f47825cae6a5d8ea2f38a))
- make keyboard dismissable on mobile devices ([b2cc1fd](https://gitlab.com/openstapps/app/commit/b2cc1fd91fc5bd66c994dcbe10771a22d91a1b3e))
- map search on iOS ([7d449b4](https://gitlab.com/openstapps/app/commit/7d449b43d0d86825f711848110ac6f044084eba0)), closes [#148](https://gitlab.com/openstapps/app/issues/148)
- map widget not loading tiles properly ([09aa7bb](https://gitlab.com/openstapps/app/commit/09aa7bb5c59e8d167fa91c69745f5f80229094d7)), closes [#127](https://gitlab.com/openstapps/app/issues/127)
- missing init (config setup) in default auth service ([f16e539](https://gitlab.com/openstapps/app/commit/f16e5394cce5a8019f4dfe367e5e0a2f0cca4ce2)), closes [#227](https://gitlab.com/openstapps/app/issues/227)
- missing translations ([30d801a](https://gitlab.com/openstapps/app/commit/30d801a3b419b382d40d96dda995bd35e493523d))
- modals not reacting after several uses ([f39c29f](https://gitlab.com/openstapps/app/commit/f39c29f10bc05ab986b74dfa8a8648df5fb307b4))
- news module not scrollable on large screens ([44b6a4a](https://gitlab.com/openstapps/app/commit/44b6a4aea008ca6c89f6cb289467429fb3f8c1fa))
- ngx-translate defaultLanguage not set ([581a5b2](https://gitlab.com/openstapps/app/commit/581a5b2e55ceda99cf7c41200366c3c5e09f1c63))
- omit sync native calendar when no uuids ([c9720dc](https://gitlab.com/openstapps/app/commit/c9720dc104cce78ae1a422d5efed7b8a58946836)), closes [#177](https://gitlab.com/openstapps/app/issues/177)
- opening hours pipe refreshing too often ([95e1734](https://gitlab.com/openstapps/app/commit/95e1734d26b175d8d1156abb10863155fed89ec0))
- overhaul auth to avoid issues ([99e8d6c](https://gitlab.com/openstapps/app/commit/99e8d6c9bcbc68b639b035af36bc05de0237b1f9)), closes [#336](https://gitlab.com/openstapps/app/issues/336)
- overview search bar scrolling behind header ([a037090](https://gitlab.com/openstapps/app/commit/a037090eec06e867a703b88a43620a74770287fe))
- performance degradation when scrolling ([f0a45d1](https://gitlab.com/openstapps/app/commit/f0a45d1b8eb2b33a6c68b94ed7f96f81db3a728b))
- person list should use long-inline-text ([8b2b853](https://gitlab.com/openstapps/app/commit/8b2b853942ac76904ff49d940dfef625b0397150))
- prevent multiple heavy setting inits ([f772637](https://gitlab.com/openstapps/app/commit/f7726378f443d9809a6174411d25a811e1d0b5e9))
- prevent opening invalid links ([fdee2db](https://gitlab.com/openstapps/app/commit/fdee2db8a42b8f6c99c4a72b3104ae0ba1a41c5a)), closes [#328](https://gitlab.com/openstapps/app/issues/328)
- profile module items show click effect on scroll ([8b2f2c0](https://gitlab.com/openstapps/app/commit/8b2f2c063c65278580d9469b00d9e67f01caaffb))
- recurring schedule offset and event limit ([9c6b513](https://gitlab.com/openstapps/app/commit/9c6b5131cd4cadb2572769d368b346054f19de1c))
- refresh token not used by default auth provider ([15ccbe4](https://gitlab.com/openstapps/app/commit/15ccbe4c1879417f2fc5849204fa9f6bdcce87fc)), closes [#311](https://gitlab.com/openstapps/app/issues/311)
- remove "extend landing" button when renewal not possible ([f60a228](https://gitlab.com/openstapps/app/commit/f60a22839200019a38586a14a0cce32e2c0029e7)), closes [#338](https://gitlab.com/openstapps/app/issues/338)
- remove item before adding it to secure storage ([ec511fb](https://gitlab.com/openstapps/app/commit/ec511fb8f40219e2559b08c62bd915d773d2a36f))
- schedule navigation bar layout ([e7d5f83](https://gitlab.com/openstapps/app/commit/e7d5f83100f43564b55249909a6658e583e3a9b2))
- set android status bar color correctly ([b38a969](https://gitlab.com/openstapps/app/commit/b38a96996a10e4e43ff1b06ecd2235a0e3bdfa1c))
- setting of default language ([ccf8b1a](https://gitlab.com/openstapps/app/commit/ccf8b1a5cc9fe834ba3e04a1ed67b2d082004403))
- show nothing for empty array properties ([1c56c89](https://gitlab.com/openstapps/app/commit/1c56c891e15b034826b5d6b2b35141fc872c922d)), closes [#154](https://gitlab.com/openstapps/app/issues/154)
- single map place width ([88684f0](https://gitlab.com/openstapps/app/commit/88684f068ab130f43e520c87f1d7383e0ae43944)), closes [#147](https://gitlab.com/openstapps/app/issues/147)
- some android devices don't support implied css animation units ([54cc883](https://gitlab.com/openstapps/app/commit/54cc8838aefe8f8c2d25d9228a136ef727a08230))
- status bar being black on Android 13 devices ([feee9e8](https://gitlab.com/openstapps/app/commit/feee9e8db90e66cf2346f7c5cc24f075eb70676c))
- suppress router event logs in console ([28caaf1](https://gitlab.com/openstapps/app/commit/28caaf1d21f7961b678cf339a712abf860ade5e7)), closes [#207](https://gitlab.com/openstapps/app/issues/207)
- swap missing icon after ionic update ([643b6c9](https://gitlab.com/openstapps/app/commit/643b6c967f3268cb305a24d614c3bc91275b0ac3))
- temporary disable flaky ui test ([6b9b1fa](https://gitlab.com/openstapps/app/commit/6b9b1fa8548d5c5fca04b2c1d63e893de39278a2))
- timetable dates cannot be removed ([9242438](https://gitlab.com/openstapps/app/commit/924243813207fa791d3c4938f8653a999b6382ff))
- translate back button title ([b8db0f3](https://gitlab.com/openstapps/app/commit/b8db0f3e70a46f2b493e183a244cb29d1954c257))
- translations ([5e1a902](https://gitlab.com/openstapps/app/commit/5e1a902d4c0d2345f21500fba5394c1907e04eb8))
- typo in translation ([7928534](https://gitlab.com/openstapps/app/commit/7928534d88a26db28b098bbceb47bc1103022a57))
- update core and apply stricter tslint rules ([911492d](https://gitlab.com/openstapps/app/commit/911492d064ff0280dd6626244cd8038cbfc0f408))
- use HashLocationStrategy for routes ([9d68212](https://gitlab.com/openstapps/app/commit/9d682125db55c87cab2b33c7633bfa133d2fc5a9)), closes [#54](https://gitlab.com/openstapps/app/issues/54)
- use localized date and time ([6ca0b97](https://gitlab.com/openstapps/app/commit/6ca0b9763761c5204a757a243056a087c5f35fd9))
- use stapps core version to compare with backends' core version ([66b8720](https://gitlab.com/openstapps/app/commit/66b8720da0f264824a396f2d9e598b0e48c8e3d1)), closes [#77](https://gitlab.com/openstapps/app/issues/77)
- user info card ([998edcb](https://gitlab.com/openstapps/app/commit/998edcb5cdfb588c2986f466f4a2951f172a8bb4)), closes [#305](https://gitlab.com/openstapps/app/issues/305)
### Features
- add "no results" screen to search ([c75ca68](https://gitlab.com/openstapps/app/commit/c75ca68c440a20e197213ecbb47d05fc293afd9c))
- add about module ([d420008](https://gitlab.com/openstapps/app/commit/d42000892694f4a3b29fa623c43fb45f8ba54687))
- add action chips to search results ([67fb4a4](https://gitlab.com/openstapps/app/commit/67fb4a43c95043caba50d43ace2ab276f3319b81))
- add auth support (default and paia) ([b5f239e](https://gitlab.com/openstapps/app/commit/b5f239ea4edebd0d27b1cdaad4a830998ce2f681))
- add backend toggle ([c1d3330](https://gitlab.com/openstapps/app/commit/c1d33303aa11da3b3e150c6717d77ef484a16ac1))
- add basic templates for data list items ([3e697b1](https://gitlab.com/openstapps/app/commit/3e697b17b4448c15781d0f6dd55577b638e9d974))
- add catalog module ([03084b1](https://gitlab.com/openstapps/app/commit/03084b1c966de98b3723d0bee2b2475589393c59))
- add ConfigModule and FakeBackendInterceptor ([406f400](https://gitlab.com/openstapps/app/commit/406f40055567bfde4ec5edf26cff942411bd073e)), closes [#34](https://gitlab.com/openstapps/app/issues/34) [#37](https://gitlab.com/openstapps/app/issues/37)
- add detail view for news ([2566a71](https://gitlab.com/openstapps/app/commit/2566a71a81a3408dbb16b97d3a453d95e25d1f00))
- add duration pipe with frequency capabilites ([49a1758](https://gitlab.com/openstapps/app/commit/49a1758da358958ffe590700c19aaf90ec748ee5))
- add favorites support ([e9452d6](https://gitlab.com/openstapps/app/commit/e9452d6520c34f6513623c16e291dc23d6ea9757))
- add feedback module ([867f9e9](https://gitlab.com/openstapps/app/commit/867f9e9b832e3bd54c04801fef63a11543e8f3dd))
- add filter chips for news ([5435f85](https://gitlab.com/openstapps/app/commit/5435f85cc43dc3baa774a5008d2920ac7b3783f6))
- add formatting pipes basted on Intl ([4b932af](https://gitlab.com/openstapps/app/commit/4b932af1c07e1af4369414667a987d31181c073c))
- add HeBIS HDS search ([9a3241c](https://gitlab.com/openstapps/app/commit/9a3241c42ab59e15c0084178f76dc4a2450a2bb8))
- add library account screens ([080e6fa](https://gitlab.com/openstapps/app/commit/080e6fa3e8c18e9608d7fa2efc95e4fd65c43a15))
- add library action confirmations ([42b860e](https://gitlab.com/openstapps/app/commit/42b860e41793fc3983a39237a4f7128416485fae)), closes [#334](https://gitlab.com/openstapps/app/issues/334)
- add logger ([a0c798f](https://gitlab.com/openstapps/app/commit/a0c798f765d87c5eebcbed65b70f3b05f285d0ce))
- add map module ([c1c9a92](https://gitlab.com/openstapps/app/commit/c1c9a92ec900403218b887fdebfe5132b232e1e0))
- add new font and new icons ([915fd72](https://gitlab.com/openstapps/app/commit/915fd72bd4bfed16e15fcc3c57879db0ec0379e2))
- add not found screen ([e3d9ef4](https://gitlab.com/openstapps/app/commit/e3d9ef40ccd626c81c67ea2d790eecbe6e025780))
- add permission check for geoLocation setting ([d5fa2fd](https://gitlab.com/openstapps/app/commit/d5fa2fd9a578d48cd2513eeb1380f1d2bc4d3754))
- add service and pipe for core translator ([4565600](https://gitlab.com/openstapps/app/commit/456560026cc9550a10a9f42657d942122be34d53))
- apply new layout overhaul ([7bbdba5](https://gitlab.com/openstapps/app/commit/7bbdba5c0b886e2789d2a603c4be627dfd16b60e))
- assessment tree view ([0b037f9](https://gitlab.com/openstapps/app/commit/0b037f96e634b412fbaaee24747df08afdc0e565))
- assessments module ([e68d1b7](https://gitlab.com/openstapps/app/commit/e68d1b73f94b36abcefe9b2bf42e98de00b69188))
- calendar plugin ([a57c302](https://gitlab.com/openstapps/app/commit/a57c3029df61ac3157c856744380a85dc001abc6))
- dashboard ui tests ([9f8ab5c](https://gitlab.com/openstapps/app/commit/9f8ab5c7a15a918f7bd05423f0a43f22a33d9228))
- **data:** add basic methods of data provider ([ffe05e4](https://gitlab.com/openstapps/app/commit/ffe05e4548fc399183ef651047cb02a3cdc80c67)), closes [#1](https://gitlab.com/openstapps/app/issues/1)
- **data:** add data detail templates ([5855acc](https://gitlab.com/openstapps/app/commit/5855accc169579d87f5779fd602d4f00f2b479a1))
- **data:** add method that checks if data item has been saved ([017fc67](https://gitlab.com/openstapps/app/commit/017fc67765bdb75542045830fb85f8eb4b899485))
- **data:** implement basic facets handling ([b6f92a7](https://gitlab.com/openstapps/app/commit/b6f92a74494e1a39d5c828d593eb70c7002bb0f6)), closes [#1](https://gitlab.com/openstapps/app/issues/1)
- **data:** show skeleton screens before data is loaded ([e1039aa](https://gitlab.com/openstapps/app/commit/e1039aa2260a0e9d8ccca5a18ded480bf2f12530)), closes [#4](https://gitlab.com/openstapps/app/issues/4)
- **data:** use data provider for list and detail view ([7caaa18](https://gitlab.com/openstapps/app/commit/7caaa18b7eb94ed8e4ff4e54d760ba1dba3ae3be))
- **data:** use general template for all offers ([58960a2](https://gitlab.com/openstapps/app/commit/58960a29ea0cd73f26a43186b41f5b53864810e0))
- display availability and item data for library items ([d571b1d](https://gitlab.com/openstapps/app/commit/d571b1dbe59f8e2270d88dd050b94283bf0a7056))
- dynamic news page rows ([848d257](https://gitlab.com/openstapps/app/commit/848d2574c7046d6f84b91e32aa83ca57fca8ad2e))
- expandable accordion in grades module ([3f81afd](https://gitlab.com/openstapps/app/commit/3f81afda82cf87bb393fbb3b71d27eee77ae42d9))
- get tab navigation items from config ([c3130a3](https://gitlab.com/openstapps/app/commit/c3130a392a53c9ec3657e24a53ed0b3333ba162b))
- Implement variable for styling ([8ecf347](https://gitlab.com/openstapps/app/commit/8ecf347c9a8abac9347dca45e99ebe35eca8f252))
- include font licenses in the licenses section ([82479f4](https://gitlab.com/openstapps/app/commit/82479f463cbee834507a0c8faf895a729631eb06))
- Ionic v6 breadcrumbs in catalog module ([7b491ed](https://gitlab.com/openstapps/app/commit/7b491ed3bb5466a845493bd8ea0bbb836a4f03d2))
- lazy load all news ([e48134e](https://gitlab.com/openstapps/app/commit/e48134eddcd1ca4d5ec5dbf910571e33a3311ba1))
- **menu:** add context menu ([1dbf451](https://gitlab.com/openstapps/app/commit/1dbf4515fe57cc8250a7fa2213ced682e3e5e0fc)), closes [#3](https://gitlab.com/openstapps/app/issues/3)
- navigation rail ([6b08af6](https://gitlab.com/openstapps/app/commit/6b08af6a746bf12005d3297ec97c130e84477615))
- news module ([22cd0af](https://gitlab.com/openstapps/app/commit/22cd0af1bf92a4576316f5510c22f012e085a237))
- profile page sections ([e395e9d](https://gitlab.com/openstapps/app/commit/e395e9d270f41bd4f6e5ecd88e438a28dde92465)), closes [#233](https://gitlab.com/openstapps/app/issues/233) [#261](https://gitlab.com/openstapps/app/issues/261) [#267](https://gitlab.com/openstapps/app/issues/267)
- refresh on pull for news module ([1f3d9ad](https://gitlab.com/openstapps/app/commit/1f3d9ad5f0c0557add2dcf242cf0b7dd7685bb1b))
- resume at origin path after login ([a5e5a5b](https://gitlab.com/openstapps/app/commit/a5e5a5b40799e7505557f7ebd764b9c563be0f4b)), closes [#168](https://gitlab.com/openstapps/app/issues/168)
- schedule layout ([e416590](https://gitlab.com/openstapps/app/commit/e4165901bb5efa6b38e397cdf5d66138e396d7f2))
- scroll schedule cursor into view ([bc4c3d7](https://gitlab.com/openstapps/app/commit/bc4c3d78dbd906243dcddac4db9ac8ccaca79056))
- search url query param handling ([f349bd7](https://gitlab.com/openstapps/app/commit/f349bd72335c47d292d0a007b1a4ce7f5c694a61))
- seperate dishes by menu sections ([400c6b8](https://gitlab.com/openstapps/app/commit/400c6b8d8c5300035862186096e38883f781d297))
- show availability in offers ([5fdef95](https://gitlab.com/openstapps/app/commit/5fdef95c065e7b467a13045adbb56a641cb2dc12))
- show feedback when map search yields no results ([c54ea86](https://gitlab.com/openstapps/app/commit/c54ea867bd64af187446dbf8dc03967aae600961))
- show menu for multiple days for canteens and cafes ([3c079cd](https://gitlab.com/openstapps/app/commit/3c079cd189e3b75d3b203bd46ab57378f99e88cc)), closes [#19](https://gitlab.com/openstapps/app/issues/19) [#79](https://gitlab.com/openstapps/app/issues/79)
- **storage:** add search using regex ([86b9bff](https://gitlab.com/openstapps/app/commit/86b9bff09a51b17151efa5ec322cddcc50a54cb2))
- **storage:** support deletion of multiple entries ([63266f5](https://gitlab.com/openstapps/app/commit/63266f588f6ddb2476e2cea4bab42a3864f77470))
- **storage:** support search using a string ([4334cad](https://gitlab.com/openstapps/app/commit/4334cad68c7d0abb7443e245b6eb983804547925))
- support deep links ([2e3f668](https://gitlab.com/openstapps/app/commit/2e3f6684ef5fbac8e4fb127c536b2b438399ce37))
- support overlapping timetable dates ([93c37b2](https://gitlab.com/openstapps/app/commit/93c37b26cca7764dea66fb12c0e53acc8fd78d2b))
- tab navigation bar animations and state ([7ecba0b](https://gitlab.com/openstapps/app/commit/7ecba0b7819ae5a7ab32d86f6049de0ab6c68e55))
- timetable module - schedule and calendar ([d8ede00](https://gitlab.com/openstapps/app/commit/d8ede006dfbd613dfbc752eb6de80db2e7e84531))
- turn on oauth2 state check for PAIA ([5bd0b50](https://gitlab.com/openstapps/app/commit/5bd0b50816973548a0a4aa5dbed3f2d0902590dd)), closes [#172](https://gitlab.com/openstapps/app/issues/172)
- use http interceptor for backendless development ([2558163](https://gitlab.com/openstapps/app/commit/2558163ad6c3038445a79e6338f1827cb1e6510e)), closes [#37](https://gitlab.com/openstapps/app/issues/37)
- use school-neutral news image fallback via css ([bb94c71](https://gitlab.com/openstapps/app/commit/bb94c71761ca5d3bf6639476ba0c143678cfabbd))
- webpack bundle analyzer ([552911c](https://gitlab.com/openstapps/app/commit/552911cfcfecec8d9be8b8bbb155b597d1f70fa2))
## [0.0.1](https://gitlab.com/openstapps/app/compare/8b23159e678773b08252bc5826510de2a302fa1d...v0.0.1) (2018-12-11)
### Features
- add the app ([8b23159](https://gitlab.com/openstapps/app/commit/8b23159e678773b08252bc5826510de2a302fa1d))

View File

@@ -29,7 +29,10 @@
"TITLE_COPIED": "In die Zwischenablage kopiert" "TITLE_COPIED": "In die Zwischenablage kopiert"
}, },
"about": { "about": {
"VERSION_INFO": "{{name}} {{version}} basierend auf StApps {{stappsVersion}}" "VERSION_INFO": "{{name}} {{version}} basierend auf StApps {{stappsVersion}}",
"CHANGELOG": "Versionshistorie",
"TECHNICAL_CHANGELOG": "StApps Basis Versionshistorie",
"TECHNICAL_CHANGELOG_DISCLAIMER": "Die StApps Basis ist anders versioniert als die App. Versionsnummern zwischen StApps und App weichen daher ab."
}, },
"releaseNotes": { "releaseNotes": {
"TITLE_UPDATED": "Deine App wurde aktualisiert!" "TITLE_UPDATED": "Deine App wurde aktualisiert!"

View File

@@ -29,7 +29,10 @@
"TITLE_COPIED": "Copied to clipboard" "TITLE_COPIED": "Copied to clipboard"
}, },
"about": { "about": {
"VERSION_INFO": "{{name}} {{version}} based on StApps {{stappsVersion}}" "VERSION_INFO": "{{name}} {{version}} based on StApps {{stappsVersion}}",
"CHANGELOG": "Changelog",
"TECHNICAL_CHANGELOG": "StApps Base Changelog",
"TECHNICAL_CHANGELOG_DISCLAIMER": "The StApps base is versioned separately from the app. Version numbers will not match those of the app itself."
}, },
"releaseNotes": { "releaseNotes": {
"TITLE_UPDATED": "Your app was updated!" "TITLE_UPDATED": "Your app was updated!"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 KiB

View File

@@ -23,8 +23,11 @@
<!-- add to homescreen for ios --> <!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="manifest" href="manifest.webmanifest" />
<meta name="theme-color" content="#1976d2" />
</head> </head>
<body style="background-color: var(--ion-color-primary)"> <body style="background-color: var(--ion-color-primary)">
<app-root></app-root> <app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body> </body>
</html> </html>

View File

@@ -12,6 +12,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import '@capacitor/core';
import {enableProdMode} from '@angular/core'; import {enableProdMode} from '@angular/core';
import {platformBrowser} from '@angular/platform-browser'; import {platformBrowser} from '@angular/platform-browser';
import {AppModule} from './app/app.module'; import {AppModule} from './app/app.module';

View File

@@ -0,0 +1,140 @@
{
"name": "StApps",
"short_name": "StApps",
"description": "Goethe-Uni App (powered by Open StApps)\n\nMit der Goethe-Uni App kannst dein Studium noch besser organisieren. Informationen über die Universität, Bibliotheken, Räumen, Veranstaltungen und Personen sind leicht über die Suche auffindbar. Zudem sind nun die Bibliotheksdienste und Notenübersicht integriert. Die Informationssysteme des Fachbereich 16 sind nicht integriert.\n\nBei Fragen und Anregungen kann das Feedback Tool in der App genutzt werden.\n\nWeiterhin ist das App-Team der Goethe-Universität unter app@rz.uni-frankfurt.de erreichbar.\n\nFeatures:\n\n- aktuelle Uni News\n- Vorlesungsverzeichnis\n- Umfassende Suche\n- Stellenangebote des Career Service\n- Bibliotheksdienste & Bibliothekskatalog\n- Notenübersicht\n- tagesaktuelle Speisepläne der Mensen und Cafeterien\n- Favoritenliste anlegen und verwalten\n- persönlichen Stundenplan erstellen (nicht mit QIS/LSF synchronisiert)",
"theme_color": "#3880ff",
"background_color": "#3880ff",
"display": "standalone",
"scope": "./",
"start_url": "./",
"prefer_related_applications": true,
"related_applications": [
{
"platform": "play",
"id": "de.goetheuni"
}
],
"categories": ["education"],
"shortcuts": [
{
"name": "Mensa",
"url": "/canteen"
},
{
"name": "Karte",
"url": "/map"
},
{
"name": "Kalender",
"url": "/schedule/now"
},
{
"name": "Wochenübersicht",
"url": "/schedule/week-overview"
},
{
"name": "Suche",
"url": "/search"
},
{
"name": "Meine App",
"url": "/profile"
}
],
"icons": [
{
"src": "assets/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png",
"purpose": "maskable any"
},
{
"src": "assets/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable any"
}
],
"screnshots": [
{
"src": "assets/screenshots/overview.png",
"type": "image/png",
"sizes": "664x1440"
},
{
"src": "assets/screenshots/canteens.png",
"type": "image/png",
"sizes": "664x1440"
},
{
"src": "assets/screenshots/map.png",
"type": "image/png",
"sizes": "664x1440"
},
{
"src": "assets/screenshots/my-app.png",
"type": "image/png",
"sizes": "664x1440"
},
{
"src": "assets/screenshots/overview-wide.png",
"type": "image/png",
"sizes": "3204x1440",
"form_factor": "wide"
},
{
"src": "assets/screenshots/canteens-wide.png",
"type": "image/png",
"sizes": "3204x1440",
"form_factor": "wide"
},
{
"src": "assets/screenshots/map-wide.png",
"type": "image/png",
"sizes": "3204x1440",
"form_factor": "wide"
},
{
"src": "assets/screenshots/my-app-wide.png",
"type": "image/png",
"sizes": "3204x1440",
"form_factor": "wide"
}
]
}

View File

@@ -18,15 +18,15 @@
@import './dark'; @import './dark';
@function to-rgb($color) { @function to-rgb($color) {
@return red($color) + ',' + green($color) + ',' + blue($color); @return color.red($color) + ',' + color.green($color) + ',' + color.blue($color);
} }
@function to-shade($color) { @function to-shade($color) {
@return darken($color, $shade-amount); @return color.adjust($color, $lightness: -$shade-amount);
} }
@function to-tint($color) { @function to-tint($color) {
@return lighten($color, $tint-amount); @return color.adjust($color, $lightness: $tint-amount);
} }
@function to-contrast($color) { @function to-contrast($color) {
@@ -35,7 +35,11 @@
} }
@function fade($color, $amount) { @function fade($color, $amount) {
@return if(lightness($color) > $fade-threshold, darken($color, $amount), lighten($color, $amount)); @return if(
color.lightness($color) > $fade-threshold,
color.adjust($color, $lightness: -$amount),
color.adjust($color, $lightness: $amount)
);
} }
@function map-range($value, $input-min, $input-max, $output-min, $output-max) { @function map-range($value, $input-min, $input-max, $output-min, $output-max) {
@@ -44,9 +48,9 @@
@function interpolate-colors($from, $to, $progress, $progress-min: 0, $progress-max: 100) { @function interpolate-colors($from, $to, $progress, $progress-min: 0, $progress-max: 100) {
@return rgb( @return rgb(
map-range($progress, $progress-min, $progress-max, red($from), red($to)), map-range($progress, $progress-min, $progress-max, color.red($from), color.red($to)),
map-range($progress, $progress-min, $progress-max, green($from), green($to)), map-range($progress, $progress-min, $progress-max, color.green($from), color.green($to)),
map-range($progress, $progress-min, $progress-max, blue($from), blue($to)) map-range($progress, $progress-min, $progress-max, color.blue($from), color.blue($to))
); );
} }

View File

@@ -6,8 +6,8 @@ LABEL version="2.0.0" \
maintainer="Jovan Krunić <krunic@uni-frankfurt.de>" maintainer="Jovan Krunić <krunic@uni-frankfurt.de>"
### Configure versions to install ### Configure versions to install
ENV ANDROID_APIS="android-33" \ ENV ANDROID_APIS="android-34" \
ANDROID_BUILD_TOOLS_VERSION="30.0.2" \ ANDROID_BUILD_TOOLS_VERSION="34.0.0" \
NPM_VERSION="^10.0.0" \ NPM_VERSION="^10.0.0" \
IONIC_VERSION="^6.0.0" \ IONIC_VERSION="^6.0.0" \
CORDOVA_RES_VERSION="latest" \ CORDOVA_RES_VERSION="latest" \

View File

@@ -2,8 +2,8 @@
"name": "@openstapps/openstapps", "name": "@openstapps/openstapps",
"private": true, "private": true,
"engines": { "engines": {
"node": ">=18.16", "node": "^18.19.1",
"pnpm": ">=8" "pnpm": "^8.15.4"
}, },
"scripts": { "scripts": {
"build": "dotenv -c -- turbo run build", "build": "dotenv -c -- turbo run build",

5895
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff