From cea5d73a063d85be39d71d48bc34b9cc63a9da30 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Tue, 27 Feb 2024 15:17:34 +0100 Subject: [PATCH 1/3] feat(nextcloud_test): Add presets for drop_account Signed-off-by: provokateurin --- packages/nextcloud_test/bin/generate_presets.dart | 1 + packages/nextcloud_test/docker/Dockerfile | 7 +++++++ packages/nextcloud_test/docker/presets/drop_account/2.3 | 6 ++++++ packages/nextcloud_test/docker/presets/drop_account/2.4 | 6 ++++++ packages/nextcloud_test/docker/presets/news/21.0 | 1 + packages/nextcloud_test/docker/presets/news/21.1 | 1 + packages/nextcloud_test/docker/presets/news/21.2 | 1 + packages/nextcloud_test/docker/presets/news/22.0 | 1 + packages/nextcloud_test/docker/presets/news/23.0 | 1 + packages/nextcloud_test/docker/presets/news/24.0 | 1 + packages/nextcloud_test/docker/presets/news/25.0 | 1 + packages/nextcloud_test/docker/presets/notes/4.7 | 1 + packages/nextcloud_test/docker/presets/notes/4.8 | 1 + packages/nextcloud_test/docker/presets/notes/4.9 | 1 + packages/nextcloud_test/docker/presets/server/26.0 | 1 + packages/nextcloud_test/docker/presets/server/27.0 | 1 + packages/nextcloud_test/docker/presets/server/27.1 | 1 + packages/nextcloud_test/docker/presets/server/28.0 | 1 + packages/nextcloud_test/docker/presets/spreed/16.0 | 1 + packages/nextcloud_test/docker/presets/spreed/17.0 | 1 + packages/nextcloud_test/docker/presets/spreed/17.1 | 1 + packages/nextcloud_test/docker/presets/spreed/18.0 | 1 + packages/nextcloud_test/docker/presets/uppush/1.3 | 1 + packages/nextcloud_test/docker/presets/uppush/1.4 | 1 + tool/generate-nextcloud-test-presets.sh | 3 +++ 25 files changed, 43 insertions(+) create mode 100644 packages/nextcloud_test/docker/presets/drop_account/2.3 create mode 100644 packages/nextcloud_test/docker/presets/drop_account/2.4 diff --git a/packages/nextcloud_test/bin/generate_presets.dart b/packages/nextcloud_test/bin/generate_presets.dart index 4a2978b9956..26c92c05f6d 100644 --- a/packages/nextcloud_test/bin/generate_presets.dart +++ b/packages/nextcloud_test/bin/generate_presets.dart @@ -10,6 +10,7 @@ Future main() async { 'notes', 'spreed', 'uppush', + 'drop_account', ]; final httpClient = HttpClient(); diff --git a/packages/nextcloud_test/docker/Dockerfile b/packages/nextcloud_test/docker/Dockerfile index 8f6982867bc..342d5d8b7f1 100644 --- a/packages/nextcloud_test/docker/Dockerfile +++ b/packages/nextcloud_test/docker/Dockerfile @@ -42,6 +42,10 @@ FROM apps as spreed ARG SPREED_URL RUN curl -L "$SPREED_URL" | tar -xz -C / +FROM apps as drop_account +ARG DROP_ACCOUNT_URL +RUN curl -L "$DROP_ACCOUNT_URL" | tar -xz -C / + FROM nextcloud COPY --from=news /news /usr/src/nextcloud/apps/news @@ -56,3 +60,6 @@ RUN ./occ app:enable uppush COPY --from=spreed /spreed /usr/src/nextcloud/apps/spreed RUN ./occ app:enable spreed RUN ./occ talk:turn:add turn,turns staticauth.openrelay.metered.ca:443 udp,tcp --secret openrelayprojectsecret + +COPY --from=drop_account /drop_account /usr/src/nextcloud/apps/drop_account +RUN ./occ app:enable drop_account diff --git a/packages/nextcloud_test/docker/presets/drop_account/2.3 b/packages/nextcloud_test/docker/presets/drop_account/2.3 new file mode 100644 index 00000000000..33d75a479de --- /dev/null +++ b/packages/nextcloud_test/docker/presets/drop_account/2.3 @@ -0,0 +1,6 @@ +SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz +NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz +NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz +SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz +UPPUSH_URL=https://codeberg.org/NextPush/uppush/archive/1.4.2.tar.gz diff --git a/packages/nextcloud_test/docker/presets/drop_account/2.4 b/packages/nextcloud_test/docker/presets/drop_account/2.4 new file mode 100644 index 00000000000..e33377adb7a --- /dev/null +++ b/packages/nextcloud_test/docker/presets/drop_account/2.4 @@ -0,0 +1,6 @@ +SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz +NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz +NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz +SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz +UPPUSH_URL=https://codeberg.org/NextPush/uppush/archive/1.4.2.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/21.0 b/packages/nextcloud_test/docker/presets/news/21.0 index 516cc0c0825..57f066808ec 100644 --- a/packages/nextcloud_test/docker/presets/news/21.0 +++ b/packages/nextcloud_test/docker/presets/news/21.0 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/21.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/21.1 b/packages/nextcloud_test/docker/presets/news/21.1 index e1b061a1e01..a94fb43e798 100644 --- a/packages/nextcloud_test/docker/presets/news/21.1 +++ b/packages/nextcloud_test/docker/presets/news/21.1 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/21.1.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/21.2 b/packages/nextcloud_test/docker/presets/news/21.2 index e3742b3bfdb..57ae3077fdd 100644 --- a/packages/nextcloud_test/docker/presets/news/21.2 +++ b/packages/nextcloud_test/docker/presets/news/21.2 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/21.2.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/22.0 b/packages/nextcloud_test/docker/presets/news/22.0 index d7ff29ca3c9..4f0086609c2 100644 --- a/packages/nextcloud_test/docker/presets/news/22.0 +++ b/packages/nextcloud_test/docker/presets/news/22.0 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/22.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/23.0 b/packages/nextcloud_test/docker/presets/news/23.0 index 809f510b805..ee9c4a7e142 100644 --- a/packages/nextcloud_test/docker/presets/news/23.0 +++ b/packages/nextcloud_test/docker/presets/news/23.0 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/23.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/24.0 b/packages/nextcloud_test/docker/presets/news/24.0 index 8f643c8dedb..33d75a479de 100644 --- a/packages/nextcloud_test/docker/presets/news/24.0 +++ b/packages/nextcloud_test/docker/presets/news/24.0 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/news/25.0 b/packages/nextcloud_test/docker/presets/news/25.0 index 5377e6031f0..e33377adb7a 100644 --- a/packages/nextcloud_test/docker/presets/news/25.0 +++ b/packages/nextcloud_test/docker/presets/news/25.0 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/notes/4.7 b/packages/nextcloud_test/docker/presets/notes/4.7 index 7eab2d4574e..d48519ea173 100644 --- a/packages/nextcloud_test/docker/presets/notes/4.7 +++ b/packages/nextcloud_test/docker/presets/notes/4.7 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.7.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/notes/4.8 b/packages/nextcloud_test/docker/presets/notes/4.8 index 50681ab9fc9..4f79ef3a0eb 100644 --- a/packages/nextcloud_test/docker/presets/notes/4.8 +++ b/packages/nextcloud_test/docker/presets/notes/4.8 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.8.1/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/notes/4.9 b/packages/nextcloud_test/docker/presets/notes/4.9 index 5377e6031f0..e33377adb7a 100644 --- a/packages/nextcloud_test/docker/presets/notes/4.9 +++ b/packages/nextcloud_test/docker/presets/notes/4.9 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/server/26.0 b/packages/nextcloud_test/docker/presets/server/26.0 index a9c119bb18b..6dacdbe2508 100644 --- a/packages/nextcloud_test/docker/presets/server/26.0 +++ b/packages/nextcloud_test/docker/presets/server/26.0 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/server/27.0 b/packages/nextcloud_test/docker/presets/server/27.0 index 2e135257147..fd18779494e 100644 --- a/packages/nextcloud_test/docker/presets/server/27.0 +++ b/packages/nextcloud_test/docker/presets/server/27.0 @@ -1,4 +1,5 @@ SERVER_VERSION=27.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/server/27.1 b/packages/nextcloud_test/docker/presets/server/27.1 index 8f643c8dedb..33d75a479de 100644 --- a/packages/nextcloud_test/docker/presets/server/27.1 +++ b/packages/nextcloud_test/docker/presets/server/27.1 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/server/28.0 b/packages/nextcloud_test/docker/presets/server/28.0 index 5377e6031f0..e33377adb7a 100644 --- a/packages/nextcloud_test/docker/presets/server/28.0 +++ b/packages/nextcloud_test/docker/presets/server/28.0 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/spreed/16.0 b/packages/nextcloud_test/docker/presets/spreed/16.0 index a9c119bb18b..6dacdbe2508 100644 --- a/packages/nextcloud_test/docker/presets/spreed/16.0 +++ b/packages/nextcloud_test/docker/presets/spreed/16.0 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/spreed/17.0 b/packages/nextcloud_test/docker/presets/spreed/17.0 index c551db5884a..188b1a23ac7 100644 --- a/packages/nextcloud_test/docker/presets/spreed/17.0 +++ b/packages/nextcloud_test/docker/presets/spreed/17.0 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.0.3/spreed-v17.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/spreed/17.1 b/packages/nextcloud_test/docker/presets/spreed/17.1 index 8f643c8dedb..33d75a479de 100644 --- a/packages/nextcloud_test/docker/presets/spreed/17.1 +++ b/packages/nextcloud_test/docker/presets/spreed/17.1 @@ -1,4 +1,5 @@ SERVER_VERSION=27.1.6 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v17.1.5/spreed-v17.1.5.tar.gz diff --git a/packages/nextcloud_test/docker/presets/spreed/18.0 b/packages/nextcloud_test/docker/presets/spreed/18.0 index 5377e6031f0..e33377adb7a 100644 --- a/packages/nextcloud_test/docker/presets/spreed/18.0 +++ b/packages/nextcloud_test/docker/presets/spreed/18.0 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/packages/nextcloud_test/docker/presets/uppush/1.3 b/packages/nextcloud_test/docker/presets/uppush/1.3 index 97eb22aebf6..dfbb99cc8bc 100644 --- a/packages/nextcloud_test/docker/presets/uppush/1.3 +++ b/packages/nextcloud_test/docker/presets/uppush/1.3 @@ -1,4 +1,5 @@ SERVER_VERSION=26.0.11 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.3.2.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/24.0.0/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v16.0.10/spreed-v16.0.10.tar.gz diff --git a/packages/nextcloud_test/docker/presets/uppush/1.4 b/packages/nextcloud_test/docker/presets/uppush/1.4 index 5377e6031f0..e33377adb7a 100644 --- a/packages/nextcloud_test/docker/presets/uppush/1.4 +++ b/packages/nextcloud_test/docker/presets/uppush/1.4 @@ -1,4 +1,5 @@ SERVER_VERSION=28.0.2 +DROP_ACCOUNT_URL=https://packages.framasoft.org/projects/nextcloud-apps/drop-account/drop_account-2.4.0.tar.gz NEWS_URL=https://github.com/nextcloud/news/releases/download/25.0.0-alpha4/news.tar.gz NOTES_URL=https://github.com/nextcloud-releases/notes/releases/download/v4.9.2/notes.tar.gz SPREED_URL=https://github.com/nextcloud-releases/spreed/releases/download/v18.0.3/spreed-v18.0.3.tar.gz diff --git a/tool/generate-nextcloud-test-presets.sh b/tool/generate-nextcloud-test-presets.sh index d5f277a9459..5fcf549ac60 100755 --- a/tool/generate-nextcloud-test-presets.sh +++ b/tool/generate-nextcloud-test-presets.sh @@ -10,4 +10,7 @@ cd "$(dirname "$0")/.." rm docker/presets/notes/4.4 rm docker/presets/notes/4.5 rm docker/presets/notes/4.6 + + # 2.2 does not expose the capability and 2.3 is also compatible with 26 so it can be easily upgraded. + rm docker/presets/drop_account/2.2 ) From 0b9f502e654713b74fcbd327f1e1e70b7163251e Mon Sep 17 00:00:00 2001 From: provokateurin Date: Tue, 27 Feb 2024 15:18:28 +0100 Subject: [PATCH 2/3] feat(tool,nextcloud): Add drop_account app Signed-off-by: provokateurin --- .gitmodules | 3 + external/nextcloud-drop_account | 1 + .../test/weather_status_bloc_test.dart | 1 + packages/nextcloud/README.md | 17 +- packages/nextcloud/lib/drop_account.dart | 1 + packages/nextcloud/lib/ids.dart | 3 + .../nextcloud/lib/src/api/core.openapi.dart | 169 +++++- .../nextcloud/lib/src/api/core.openapi.g.dart | 515 ++++++++++++++++++ .../nextcloud/lib/src/api/core.openapi.json | 48 ++ .../lib/src/api/drop_account.openapi.dart | 159 ++++++ .../lib/src/api/drop_account.openapi.g.dart | 503 +++++++++++++++++ .../lib/src/api/drop_account.openapi.json | 73 +++ .../drop_account/0-password-confirmation.json | 11 + packages/nextcloud/test/core_test.dart | 1 + tool/generate-specs.sh | 4 + 15 files changed, 1486 insertions(+), 23 deletions(-) create mode 160000 external/nextcloud-drop_account create mode 100644 packages/nextcloud/lib/drop_account.dart create mode 100644 packages/nextcloud/lib/src/api/drop_account.openapi.dart create mode 100644 packages/nextcloud/lib/src/api/drop_account.openapi.g.dart create mode 100644 packages/nextcloud/lib/src/api/drop_account.openapi.json create mode 100644 packages/nextcloud/lib/src/patches/drop_account/0-password-confirmation.json diff --git a/.gitmodules b/.gitmodules index 7f43de3dc12..71f006da52f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "external/nextcloud-openapi-extractor"] path = external/nextcloud-openapi-extractor url = https://github.com/nextcloud/openapi-extractor.git +[submodule "external/nextcloud-drop_account"] + path = external/nextcloud-drop_account + url = https://framagit.org/framasoft/nextcloud/drop_account.git diff --git a/external/nextcloud-drop_account b/external/nextcloud-drop_account new file mode 160000 index 00000000000..7829dd429a7 --- /dev/null +++ b/external/nextcloud-drop_account @@ -0,0 +1 @@ +Subproject commit 7829dd429a79490bd2727610af8b7e0ade24bf36 diff --git a/packages/neon_framework/test/weather_status_bloc_test.dart b/packages/neon_framework/test/weather_status_bloc_test.dart index 4c1ccb78c21..26e4c484751 100644 --- a/packages/neon_framework/test/weather_status_bloc_test.dart +++ b/packages/neon_framework/test/weather_status_bloc_test.dart @@ -109,6 +109,7 @@ core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data buildCapabilities({requi ..capabilities = ( commentsCapabilities: null, davCapabilities: null, + dropAccountCapabilities: null, filesCapabilities: null, filesSharingCapabilities: null, filesTrashbinCapabilities: null, diff --git a/packages/nextcloud/README.md b/packages/nextcloud/README.md index 2bbc13063c8..ff17d34ea56 100644 --- a/packages/nextcloud/README.md +++ b/packages/nextcloud/README.md @@ -47,14 +47,15 @@ These OpenAPI specifications are [generated](https://github.com/nextcloud/openap ## Compatibility/Support policy -| Component | Supported versions (1) | -|-----------------------------------------------------------------|------------------------| -| [Server](https://github.com/nextcloud/server) (2) | 26 - 28 | -| [News app](https://github.com/nextcloud/news) | 21 - 25 | -| [Notes app](https://github.com/nextcloud/notes) | 4.7 - 4.9 | -| [Notifications app](https://github.com/nextcloud/notifications) | 26 - 28 | -| [Talk app](https://github.com/nextcloud/spreed) | 16 - 18 | -| [NextPush app](https://codeberg.org/NextPush/uppush) | 1.3 - 1.4 | +| Component | Supported versions (1) | +|------------------------------------------------------------------------------------|------------------------| +| [Server](https://github.com/nextcloud/server) (2) | 26 - 28 | +| [News app](https://github.com/nextcloud/news) | 21 - 25 | +| [Notes app](https://github.com/nextcloud/notes) | 4.7 - 4.9 | +| [Notifications app](https://github.com/nextcloud/notifications) | 26 - 28 | +| [Talk app](https://github.com/nextcloud/spreed) | 16 - 18 | +| [NextPush app](https://codeberg.org/NextPush/uppush) | 1.3 - 1.4 | +| [User account deletion app](https://framagit.org/framasoft/nextcloud/drop_account) | 2.3 - 2.4 | 1: Other versions might be supported too or at least mostly working, but we do not test against those. 2: Server includes the following apps: comments, core, dashboard, dav, files, files_external, files_reminders, files_sharing, files_trashbin, files_versions, provisioning_api, settings, sharebymail, theming, updatenotification, user_status, weather_status and WebDAV. diff --git a/packages/nextcloud/lib/drop_account.dart b/packages/nextcloud/lib/drop_account.dart new file mode 100644 index 00000000000..5cf18654693 --- /dev/null +++ b/packages/nextcloud/lib/drop_account.dart @@ -0,0 +1 @@ +export 'src/api/drop_account.openapi.dart'; diff --git a/packages/nextcloud/lib/ids.dart b/packages/nextcloud/lib/ids.dart index 05c0729fa66..b81b9069838 100644 --- a/packages/nextcloud/lib/ids.dart +++ b/packages/nextcloud/lib/ids.dart @@ -12,6 +12,9 @@ final class AppIDs { /// ID for the dav app. static const dav = 'dav'; + /// ID for the drop_account app. + static const dropAccount = 'drop_account'; + /// ID for the files app. static const files = 'files'; diff --git a/packages/nextcloud/lib/src/api/core.openapi.dart b/packages/nextcloud/lib/src/api/core.openapi.dart index 5416a2f51af..7f62200044a 100644 --- a/packages/nextcloud/lib/src/api/core.openapi.dart +++ b/packages/nextcloud/lib/src/api/core.openapi.dart @@ -7338,6 +7338,120 @@ abstract class DavCapabilities implements $DavCapabilitiesInterface, Built get serializer => _$davCapabilitiesSerializer; } +@BuiltValue(instantiable: false) +abstract interface class $DropAccountCapabilities_DropAccount_DelayInterface { + bool get enabled; + int get hours; +} + +abstract class DropAccountCapabilities_DropAccount_Delay + implements + $DropAccountCapabilities_DropAccount_DelayInterface, + Built { + /// Creates a new DropAccountCapabilities_DropAccount_Delay object using the builder pattern. + factory DropAccountCapabilities_DropAccount_Delay([ + void Function(DropAccountCapabilities_DropAccount_DelayBuilder)? b, + ]) = _$DropAccountCapabilities_DropAccount_Delay; + + // coverage:ignore-start + const DropAccountCapabilities_DropAccount_Delay._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory DropAccountCapabilities_DropAccount_Delay.fromJson(Map json) => + _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for DropAccountCapabilities_DropAccount_Delay. + static Serializer get serializer => + _$dropAccountCapabilitiesDropAccountDelaySerializer; +} + +@BuiltValue(instantiable: false) +abstract interface class $DropAccountCapabilities_DropAccountInterface { + bool get enabled; + @BuiltValueField(wireName: 'api-version') + String get apiVersion; + DropAccountCapabilities_DropAccount_Delay get delay; + String? get details; +} + +abstract class DropAccountCapabilities_DropAccount + implements + $DropAccountCapabilities_DropAccountInterface, + Built { + /// Creates a new DropAccountCapabilities_DropAccount object using the builder pattern. + factory DropAccountCapabilities_DropAccount([void Function(DropAccountCapabilities_DropAccountBuilder)? b]) = + _$DropAccountCapabilities_DropAccount; + + // coverage:ignore-start + const DropAccountCapabilities_DropAccount._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory DropAccountCapabilities_DropAccount.fromJson(Map json) => + _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for DropAccountCapabilities_DropAccount. + static Serializer get serializer => + _$dropAccountCapabilitiesDropAccountSerializer; +} + +@BuiltValue(instantiable: false) +abstract interface class $DropAccountCapabilitiesInterface { + @BuiltValueField(wireName: 'drop-account') + DropAccountCapabilities_DropAccount get dropAccount; +} + +abstract class DropAccountCapabilities + implements $DropAccountCapabilitiesInterface, Built { + /// Creates a new DropAccountCapabilities object using the builder pattern. + factory DropAccountCapabilities([void Function(DropAccountCapabilitiesBuilder)? b]) = _$DropAccountCapabilities; + + // coverage:ignore-start + const DropAccountCapabilities._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory DropAccountCapabilities.fromJson(Map json) => + _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for DropAccountCapabilities. + static Serializer get serializer => _$dropAccountCapabilitiesSerializer; +} + @BuiltValue(instantiable: false) abstract interface class $FilesCapabilities_Files_DirectEditingInterface { String get url; @@ -9285,6 +9399,7 @@ abstract class NotesCapabilities typedef OcsGetCapabilitiesResponseApplicationJson_Ocs_Data_Capabilities = ({ CommentsCapabilities? commentsCapabilities, DavCapabilities? davCapabilities, + DropAccountCapabilities? dropAccountCapabilities, FilesCapabilities? filesCapabilities, FilesSharingCapabilities? filesSharingCapabilities, FilesTrashbinCapabilities? filesTrashbinCapabilities, @@ -12904,13 +13019,13 @@ extension $OcsGetCapabilitiesResponseApplicationJson_Ocs_Data_CapabilitiesExtens /// Serializer for OcsGetCapabilitiesResponseApplicationJson_Ocs_Data_Capabilities. @BuiltValueSerializer(custom: true) static Serializer get serializer => - $3dc1754764311166375258bea55197c8Extension._serializer; + $d7df54b8bef6b092d401eed2bcfbb6f0Extension._serializer; /// Creates a new object from the given [json] data. /// /// Use `toJson` to serialize it back into json. static OcsGetCapabilitiesResponseApplicationJson_Ocs_Data_Capabilities fromJson(Object? json) => - $3dc1754764311166375258bea55197c8Extension._fromJson(json); + $d7df54b8bef6b092d401eed2bcfbb6f0Extension._fromJson(json); } /// Serialization extension for `UnifiedSearchSearchCursor`. @@ -13230,9 +13345,10 @@ class _$06c2e47196a84ebc3718dccf9eb4b29dSerializer implements PrimitiveSerialize } } -typedef _$3dc1754764311166375258bea55197c8 = ({ +typedef _$d7df54b8bef6b092d401eed2bcfbb6f0 = ({ CommentsCapabilities? commentsCapabilities, DavCapabilities? davCapabilities, + DropAccountCapabilities? dropAccountCapabilities, FilesCapabilities? filesCapabilities, FilesSharingCapabilities? filesSharingCapabilities, FilesTrashbinCapabilities? filesTrashbinCapabilities, @@ -13249,10 +13365,11 @@ typedef _$3dc1754764311166375258bea55197c8 = ({ /// @nodoc // ignore: library_private_types_in_public_api -extension $3dc1754764311166375258bea55197c8Extension on _$3dc1754764311166375258bea55197c8 { +extension $d7df54b8bef6b092d401eed2bcfbb6f0Extension on _$d7df54b8bef6b092d401eed2bcfbb6f0 { List get _values => [ commentsCapabilities, davCapabilities, + dropAccountCapabilities, filesCapabilities, filesSharingCapabilities, filesTrashbinCapabilities, @@ -13272,9 +13389,9 @@ extension $3dc1754764311166375258bea55197c8Extension on _$3dc1754764311166375258 /// {@macro Dynamite.validateAnyOf} void validateAnyOf() => _i2.validateAnyOf(_values); - static Serializer<_$3dc1754764311166375258bea55197c8> get _serializer => - const _$3dc1754764311166375258bea55197c8Serializer(); - static _$3dc1754764311166375258bea55197c8 _fromJson(Object? json) => + static Serializer<_$d7df54b8bef6b092d401eed2bcfbb6f0> get _serializer => + const _$d7df54b8bef6b092d401eed2bcfbb6f0Serializer(); + static _$d7df54b8bef6b092d401eed2bcfbb6f0 _fromJson(Object? json) => _$jsonSerializers.deserializeWith(_serializer, json)!; /// Parses this object into a json like map. @@ -13283,19 +13400,19 @@ extension $3dc1754764311166375258bea55197c8Extension on _$3dc1754764311166375258 Object? toJson() => _$jsonSerializers.serializeWith(_serializer, this); } -class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerializer<_$3dc1754764311166375258bea55197c8> { - const _$3dc1754764311166375258bea55197c8Serializer(); +class _$d7df54b8bef6b092d401eed2bcfbb6f0Serializer implements PrimitiveSerializer<_$d7df54b8bef6b092d401eed2bcfbb6f0> { + const _$d7df54b8bef6b092d401eed2bcfbb6f0Serializer(); @override - Iterable get types => const [_$3dc1754764311166375258bea55197c8]; + Iterable get types => const [_$d7df54b8bef6b092d401eed2bcfbb6f0]; @override - String get wireName => r'_$3dc1754764311166375258bea55197c8'; + String get wireName => r'_$d7df54b8bef6b092d401eed2bcfbb6f0'; @override Object serialize( Serializers serializers, - _$3dc1754764311166375258bea55197c8 object, { + _$d7df54b8bef6b092d401eed2bcfbb6f0 object, { FullType specifiedType = FullType.unspecified, }) { dynamic value; @@ -13307,6 +13424,10 @@ class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerialize if (value != null) { return serializers.serialize(value, specifiedType: const FullType(DavCapabilities))!; } + value = object.dropAccountCapabilities; + if (value != null) { + return serializers.serialize(value, specifiedType: const FullType(DropAccountCapabilities))!; + } value = object.filesCapabilities; if (value != null) { return serializers.serialize(value, specifiedType: const FullType(FilesCapabilities))!; @@ -13360,7 +13481,7 @@ class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerialize } @override - _$3dc1754764311166375258bea55197c8 deserialize( + _$d7df54b8bef6b092d401eed2bcfbb6f0 deserialize( Serializers serializers, Object data, { FullType specifiedType = FullType.unspecified, @@ -13375,6 +13496,11 @@ class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerialize davCapabilities = serializers.deserialize(data, specifiedType: const FullType(DavCapabilities))! as DavCapabilities; } catch (_) {} + DropAccountCapabilities? dropAccountCapabilities; + try { + dropAccountCapabilities = serializers.deserialize(data, specifiedType: const FullType(DropAccountCapabilities))! + as DropAccountCapabilities; + } catch (_) {} FilesCapabilities? filesCapabilities; try { filesCapabilities = @@ -13454,6 +13580,7 @@ class _$3dc1754764311166375258bea55197c8Serializer implements PrimitiveSerialize return ( commentsCapabilities: commentsCapabilities, davCapabilities: davCapabilities, + dropAccountCapabilities: dropAccountCapabilities, filesCapabilities: filesCapabilities, filesSharingCapabilities: filesSharingCapabilities, filesTrashbinCapabilities: filesTrashbinCapabilities, @@ -13736,6 +13863,18 @@ final Serializers _$serializers = (Serializers().toBuilder() ..add(DavCapabilities.serializer) ..addBuilderFactory(const FullType(DavCapabilities_Dav), DavCapabilities_DavBuilder.new) ..add(DavCapabilities_Dav.serializer) + ..addBuilderFactory(const FullType(DropAccountCapabilities), DropAccountCapabilitiesBuilder.new) + ..add(DropAccountCapabilities.serializer) + ..addBuilderFactory( + const FullType(DropAccountCapabilities_DropAccount), + DropAccountCapabilities_DropAccountBuilder.new, + ) + ..add(DropAccountCapabilities_DropAccount.serializer) + ..addBuilderFactory( + const FullType(DropAccountCapabilities_DropAccount_Delay), + DropAccountCapabilities_DropAccount_DelayBuilder.new, + ) + ..add(DropAccountCapabilities_DropAccount_Delay.serializer) ..addBuilderFactory(const FullType(FilesCapabilities), FilesCapabilitiesBuilder.new) ..add(FilesCapabilities.serializer) ..addBuilderFactory(const FullType(FilesCapabilities_Files), FilesCapabilities_FilesBuilder.new) @@ -13934,7 +14073,7 @@ final Serializers _$serializers = (Serializers().toBuilder() ..add(NotesCapabilities.serializer) ..addBuilderFactory(const FullType(NotesCapabilities_Notes), NotesCapabilities_NotesBuilder.new) ..add(NotesCapabilities_Notes.serializer) - ..add($3dc1754764311166375258bea55197c8Extension._serializer) + ..add($d7df54b8bef6b092d401eed2bcfbb6f0Extension._serializer) ..add(PreviewGetPreviewByFileIdA.serializer) ..add(PreviewGetPreviewByFileIdForceIcon.serializer) ..add(PreviewGetPreviewByFileIdMimeFallback.serializer) @@ -14330,7 +14469,7 @@ final Serializers _$jsonSerializers = (_$serializers.toBuilder() _$b2c4857c0136baea42828d89c87c757d, _$46564992d3ed3482aa6c1162698aac99, _$06c2e47196a84ebc3718dccf9eb4b29d, - _$3dc1754764311166375258bea55197c8, + _$d7df54b8bef6b092d401eed2bcfbb6f0, }, ), ) diff --git a/packages/nextcloud/lib/src/api/core.openapi.g.dart b/packages/nextcloud/lib/src/api/core.openapi.g.dart index 02d51547d6b..de63d4d9b27 100644 --- a/packages/nextcloud/lib/src/api/core.openapi.g.dart +++ b/packages/nextcloud/lib/src/api/core.openapi.g.dart @@ -415,6 +415,11 @@ Serializer _$commentsCapabilitiesFilesSerializer = _ Serializer _$commentsCapabilitiesSerializer = _$CommentsCapabilitiesSerializer(); Serializer _$davCapabilitiesDavSerializer = _$DavCapabilities_DavSerializer(); Serializer _$davCapabilitiesSerializer = _$DavCapabilitiesSerializer(); +Serializer _$dropAccountCapabilitiesDropAccountDelaySerializer = + _$DropAccountCapabilities_DropAccount_DelaySerializer(); +Serializer _$dropAccountCapabilitiesDropAccountSerializer = + _$DropAccountCapabilities_DropAccountSerializer(); +Serializer _$dropAccountCapabilitiesSerializer = _$DropAccountCapabilitiesSerializer(); Serializer _$filesCapabilitiesFilesDirectEditingSerializer = _$FilesCapabilities_Files_DirectEditingSerializer(); Serializer _$filesCapabilitiesFilesSerializer = _$FilesCapabilities_FilesSerializer(); @@ -3414,6 +3419,153 @@ class _$DavCapabilitiesSerializer implements StructuredSerializer { + @override + final Iterable types = const [ + DropAccountCapabilities_DropAccount_Delay, + _$DropAccountCapabilities_DropAccount_Delay + ]; + @override + final String wireName = 'DropAccountCapabilities_DropAccount_Delay'; + + @override + Iterable serialize(Serializers serializers, DropAccountCapabilities_DropAccount_Delay object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'enabled', + serializers.serialize(object.enabled, specifiedType: const FullType(bool)), + 'hours', + serializers.serialize(object.hours, specifiedType: const FullType(int)), + ]; + + return result; + } + + @override + DropAccountCapabilities_DropAccount_Delay deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = DropAccountCapabilities_DropAccount_DelayBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'enabled': + result.enabled = serializers.deserialize(value, specifiedType: const FullType(bool))! as bool; + break; + case 'hours': + result.hours = serializers.deserialize(value, specifiedType: const FullType(int))! as int; + break; + } + } + + return result.build(); + } +} + +class _$DropAccountCapabilities_DropAccountSerializer + implements StructuredSerializer { + @override + final Iterable types = const [DropAccountCapabilities_DropAccount, _$DropAccountCapabilities_DropAccount]; + @override + final String wireName = 'DropAccountCapabilities_DropAccount'; + + @override + Iterable serialize(Serializers serializers, DropAccountCapabilities_DropAccount object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'enabled', + serializers.serialize(object.enabled, specifiedType: const FullType(bool)), + 'api-version', + serializers.serialize(object.apiVersion, specifiedType: const FullType(String)), + 'delay', + serializers.serialize(object.delay, specifiedType: const FullType(DropAccountCapabilities_DropAccount_Delay)), + ]; + Object? value; + value = object.details; + if (value != null) { + result + ..add('details') + ..add(serializers.serialize(value, specifiedType: const FullType(String))); + } + return result; + } + + @override + DropAccountCapabilities_DropAccount deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = DropAccountCapabilities_DropAccountBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'enabled': + result.enabled = serializers.deserialize(value, specifiedType: const FullType(bool))! as bool; + break; + case 'api-version': + result.apiVersion = serializers.deserialize(value, specifiedType: const FullType(String))! as String; + break; + case 'delay': + result.delay.replace( + serializers.deserialize(value, specifiedType: const FullType(DropAccountCapabilities_DropAccount_Delay))! + as DropAccountCapabilities_DropAccount_Delay); + break; + case 'details': + result.details = serializers.deserialize(value, specifiedType: const FullType(String)) as String?; + break; + } + } + + return result.build(); + } +} + +class _$DropAccountCapabilitiesSerializer implements StructuredSerializer { + @override + final Iterable types = const [DropAccountCapabilities, _$DropAccountCapabilities]; + @override + final String wireName = 'DropAccountCapabilities'; + + @override + Iterable serialize(Serializers serializers, DropAccountCapabilities object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'drop-account', + serializers.serialize(object.dropAccount, specifiedType: const FullType(DropAccountCapabilities_DropAccount)), + ]; + + return result; + } + + @override + DropAccountCapabilities deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = DropAccountCapabilitiesBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'drop-account': + result.dropAccount.replace( + serializers.deserialize(value, specifiedType: const FullType(DropAccountCapabilities_DropAccount))! + as DropAccountCapabilities_DropAccount); + break; + } + } + + return result.build(); + } +} + class _$FilesCapabilities_Files_DirectEditingSerializer implements StructuredSerializer { @override @@ -16474,6 +16626,369 @@ class DavCapabilitiesBuilder } } +abstract mixin class $DropAccountCapabilities_DropAccount_DelayInterfaceBuilder { + void replace($DropAccountCapabilities_DropAccount_DelayInterface other); + void update(void Function($DropAccountCapabilities_DropAccount_DelayInterfaceBuilder) updates); + bool? get enabled; + set enabled(bool? enabled); + + int? get hours; + set hours(int? hours); +} + +class _$DropAccountCapabilities_DropAccount_Delay extends DropAccountCapabilities_DropAccount_Delay { + @override + final bool enabled; + @override + final int hours; + + factory _$DropAccountCapabilities_DropAccount_Delay( + [void Function(DropAccountCapabilities_DropAccount_DelayBuilder)? updates]) => + (DropAccountCapabilities_DropAccount_DelayBuilder()..update(updates))._build(); + + _$DropAccountCapabilities_DropAccount_Delay._({required this.enabled, required this.hours}) : super._() { + BuiltValueNullFieldError.checkNotNull(enabled, r'DropAccountCapabilities_DropAccount_Delay', 'enabled'); + BuiltValueNullFieldError.checkNotNull(hours, r'DropAccountCapabilities_DropAccount_Delay', 'hours'); + } + + @override + DropAccountCapabilities_DropAccount_Delay rebuild( + void Function(DropAccountCapabilities_DropAccount_DelayBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + DropAccountCapabilities_DropAccount_DelayBuilder toBuilder() => + DropAccountCapabilities_DropAccount_DelayBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is DropAccountCapabilities_DropAccount_Delay && enabled == other.enabled && hours == other.hours; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, enabled.hashCode); + _$hash = $jc(_$hash, hours.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'DropAccountCapabilities_DropAccount_Delay') + ..add('enabled', enabled) + ..add('hours', hours)) + .toString(); + } +} + +class DropAccountCapabilities_DropAccount_DelayBuilder + implements + Builder, + $DropAccountCapabilities_DropAccount_DelayInterfaceBuilder { + _$DropAccountCapabilities_DropAccount_Delay? _$v; + + bool? _enabled; + bool? get enabled => _$this._enabled; + set enabled(covariant bool? enabled) => _$this._enabled = enabled; + + int? _hours; + int? get hours => _$this._hours; + set hours(covariant int? hours) => _$this._hours = hours; + + DropAccountCapabilities_DropAccount_DelayBuilder(); + + DropAccountCapabilities_DropAccount_DelayBuilder get _$this { + final $v = _$v; + if ($v != null) { + _enabled = $v.enabled; + _hours = $v.hours; + _$v = null; + } + return this; + } + + @override + void replace(covariant DropAccountCapabilities_DropAccount_Delay other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$DropAccountCapabilities_DropAccount_Delay; + } + + @override + void update(void Function(DropAccountCapabilities_DropAccount_DelayBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + DropAccountCapabilities_DropAccount_Delay build() => _build(); + + _$DropAccountCapabilities_DropAccount_Delay _build() { + final _$result = _$v ?? + _$DropAccountCapabilities_DropAccount_Delay._( + enabled: + BuiltValueNullFieldError.checkNotNull(enabled, r'DropAccountCapabilities_DropAccount_Delay', 'enabled'), + hours: BuiltValueNullFieldError.checkNotNull(hours, r'DropAccountCapabilities_DropAccount_Delay', 'hours')); + replace(_$result); + return _$result; + } +} + +abstract mixin class $DropAccountCapabilities_DropAccountInterfaceBuilder { + void replace($DropAccountCapabilities_DropAccountInterface other); + void update(void Function($DropAccountCapabilities_DropAccountInterfaceBuilder) updates); + bool? get enabled; + set enabled(bool? enabled); + + String? get apiVersion; + set apiVersion(String? apiVersion); + + DropAccountCapabilities_DropAccount_DelayBuilder get delay; + set delay(DropAccountCapabilities_DropAccount_DelayBuilder? delay); + + String? get details; + set details(String? details); +} + +class _$DropAccountCapabilities_DropAccount extends DropAccountCapabilities_DropAccount { + @override + final bool enabled; + @override + final String apiVersion; + @override + final DropAccountCapabilities_DropAccount_Delay delay; + @override + final String? details; + + factory _$DropAccountCapabilities_DropAccount([void Function(DropAccountCapabilities_DropAccountBuilder)? updates]) => + (DropAccountCapabilities_DropAccountBuilder()..update(updates))._build(); + + _$DropAccountCapabilities_DropAccount._( + {required this.enabled, required this.apiVersion, required this.delay, this.details}) + : super._() { + BuiltValueNullFieldError.checkNotNull(enabled, r'DropAccountCapabilities_DropAccount', 'enabled'); + BuiltValueNullFieldError.checkNotNull(apiVersion, r'DropAccountCapabilities_DropAccount', 'apiVersion'); + BuiltValueNullFieldError.checkNotNull(delay, r'DropAccountCapabilities_DropAccount', 'delay'); + } + + @override + DropAccountCapabilities_DropAccount rebuild(void Function(DropAccountCapabilities_DropAccountBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + DropAccountCapabilities_DropAccountBuilder toBuilder() => DropAccountCapabilities_DropAccountBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is DropAccountCapabilities_DropAccount && + enabled == other.enabled && + apiVersion == other.apiVersion && + delay == other.delay && + details == other.details; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, enabled.hashCode); + _$hash = $jc(_$hash, apiVersion.hashCode); + _$hash = $jc(_$hash, delay.hashCode); + _$hash = $jc(_$hash, details.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'DropAccountCapabilities_DropAccount') + ..add('enabled', enabled) + ..add('apiVersion', apiVersion) + ..add('delay', delay) + ..add('details', details)) + .toString(); + } +} + +class DropAccountCapabilities_DropAccountBuilder + implements + Builder, + $DropAccountCapabilities_DropAccountInterfaceBuilder { + _$DropAccountCapabilities_DropAccount? _$v; + + bool? _enabled; + bool? get enabled => _$this._enabled; + set enabled(covariant bool? enabled) => _$this._enabled = enabled; + + String? _apiVersion; + String? get apiVersion => _$this._apiVersion; + set apiVersion(covariant String? apiVersion) => _$this._apiVersion = apiVersion; + + DropAccountCapabilities_DropAccount_DelayBuilder? _delay; + DropAccountCapabilities_DropAccount_DelayBuilder get delay => + _$this._delay ??= DropAccountCapabilities_DropAccount_DelayBuilder(); + set delay(covariant DropAccountCapabilities_DropAccount_DelayBuilder? delay) => _$this._delay = delay; + + String? _details; + String? get details => _$this._details; + set details(covariant String? details) => _$this._details = details; + + DropAccountCapabilities_DropAccountBuilder(); + + DropAccountCapabilities_DropAccountBuilder get _$this { + final $v = _$v; + if ($v != null) { + _enabled = $v.enabled; + _apiVersion = $v.apiVersion; + _delay = $v.delay.toBuilder(); + _details = $v.details; + _$v = null; + } + return this; + } + + @override + void replace(covariant DropAccountCapabilities_DropAccount other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$DropAccountCapabilities_DropAccount; + } + + @override + void update(void Function(DropAccountCapabilities_DropAccountBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + DropAccountCapabilities_DropAccount build() => _build(); + + _$DropAccountCapabilities_DropAccount _build() { + _$DropAccountCapabilities_DropAccount _$result; + try { + _$result = _$v ?? + _$DropAccountCapabilities_DropAccount._( + enabled: + BuiltValueNullFieldError.checkNotNull(enabled, r'DropAccountCapabilities_DropAccount', 'enabled'), + apiVersion: BuiltValueNullFieldError.checkNotNull( + apiVersion, r'DropAccountCapabilities_DropAccount', 'apiVersion'), + delay: delay.build(), + details: details); + } catch (_) { + late String _$failedField; + try { + _$failedField = 'delay'; + delay.build(); + } catch (e) { + throw BuiltValueNestedFieldError(r'DropAccountCapabilities_DropAccount', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +abstract mixin class $DropAccountCapabilitiesInterfaceBuilder { + void replace($DropAccountCapabilitiesInterface other); + void update(void Function($DropAccountCapabilitiesInterfaceBuilder) updates); + DropAccountCapabilities_DropAccountBuilder get dropAccount; + set dropAccount(DropAccountCapabilities_DropAccountBuilder? dropAccount); +} + +class _$DropAccountCapabilities extends DropAccountCapabilities { + @override + final DropAccountCapabilities_DropAccount dropAccount; + + factory _$DropAccountCapabilities([void Function(DropAccountCapabilitiesBuilder)? updates]) => + (DropAccountCapabilitiesBuilder()..update(updates))._build(); + + _$DropAccountCapabilities._({required this.dropAccount}) : super._() { + BuiltValueNullFieldError.checkNotNull(dropAccount, r'DropAccountCapabilities', 'dropAccount'); + } + + @override + DropAccountCapabilities rebuild(void Function(DropAccountCapabilitiesBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + DropAccountCapabilitiesBuilder toBuilder() => DropAccountCapabilitiesBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is DropAccountCapabilities && dropAccount == other.dropAccount; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, dropAccount.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'DropAccountCapabilities')..add('dropAccount', dropAccount)).toString(); + } +} + +class DropAccountCapabilitiesBuilder + implements + Builder, + $DropAccountCapabilitiesInterfaceBuilder { + _$DropAccountCapabilities? _$v; + + DropAccountCapabilities_DropAccountBuilder? _dropAccount; + DropAccountCapabilities_DropAccountBuilder get dropAccount => + _$this._dropAccount ??= DropAccountCapabilities_DropAccountBuilder(); + set dropAccount(covariant DropAccountCapabilities_DropAccountBuilder? dropAccount) => + _$this._dropAccount = dropAccount; + + DropAccountCapabilitiesBuilder(); + + DropAccountCapabilitiesBuilder get _$this { + final $v = _$v; + if ($v != null) { + _dropAccount = $v.dropAccount.toBuilder(); + _$v = null; + } + return this; + } + + @override + void replace(covariant DropAccountCapabilities other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$DropAccountCapabilities; + } + + @override + void update(void Function(DropAccountCapabilitiesBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + DropAccountCapabilities build() => _build(); + + _$DropAccountCapabilities _build() { + _$DropAccountCapabilities _$result; + try { + _$result = _$v ?? _$DropAccountCapabilities._(dropAccount: dropAccount.build()); + } catch (_) { + late String _$failedField; + try { + _$failedField = 'dropAccount'; + dropAccount.build(); + } catch (e) { + throw BuiltValueNestedFieldError(r'DropAccountCapabilities', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + abstract mixin class $FilesCapabilities_Files_DirectEditingInterfaceBuilder { void replace($FilesCapabilities_Files_DirectEditingInterface other); void update(void Function($FilesCapabilities_Files_DirectEditingInterfaceBuilder) updates); diff --git a/packages/nextcloud/lib/src/api/core.openapi.json b/packages/nextcloud/lib/src/api/core.openapi.json index a5719e58c1d..f54aaed6a88 100644 --- a/packages/nextcloud/lib/src/api/core.openapi.json +++ b/packages/nextcloud/lib/src/api/core.openapi.json @@ -673,6 +673,51 @@ } } }, + "DropAccountCapabilities": { + "type": "object", + "required": [ + "drop-account" + ], + "properties": { + "drop-account": { + "type": "object", + "required": [ + "enabled", + "api-version", + "delay", + "details" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "api-version": { + "type": "string" + }, + "delay": { + "type": "object", + "required": [ + "enabled", + "hours" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "hours": { + "type": "integer", + "format": "int64" + } + } + }, + "details": { + "type": "string", + "nullable": true + } + } + } + } + }, "FilesCapabilities": { "type": "object", "required": [ @@ -2470,6 +2515,9 @@ { "$ref": "#/components/schemas/DavCapabilities" }, + { + "$ref": "#/components/schemas/DropAccountCapabilities" + }, { "$ref": "#/components/schemas/FilesCapabilities" }, diff --git a/packages/nextcloud/lib/src/api/drop_account.openapi.dart b/packages/nextcloud/lib/src/api/drop_account.openapi.dart new file mode 100644 index 00000000000..c5f9c5d6bc2 --- /dev/null +++ b/packages/nextcloud/lib/src/api/drop_account.openapi.dart @@ -0,0 +1,159 @@ +// Use of this source code is governed by a agpl license. It can be obtained at `https://spdx.org/licenses/AGPL-3.0-only.html`. + +// OpenAPI client generated by Dynamite. Do not manually edit this file. + +// ignore_for_file: camel_case_extensions, camel_case_types, discarded_futures +// ignore_for_file: no_leading_underscores_for_local_identifiers +// ignore_for_file: public_member_api_docs, unreachable_switch_case + +/// drop_account Version: 0.0.1. +/// +/// An app to allow users to delete their accounts. +/// +/// Use of this source code is governed by a agpl license. +/// It can be obtained at `https://spdx.org/licenses/AGPL-3.0-only.html`. +library; // ignore_for_file: no_leading_underscores_for_library_prefixes + +import 'package:built_value/built_value.dart'; +import 'package:built_value/serializer.dart'; +import 'package:built_value/standard_json_plugin.dart' as _i3; +import 'package:dynamite_runtime/built_value.dart' as _i2; +import 'package:meta/meta.dart' as _i1; + +part 'drop_account.openapi.g.dart'; + +@BuiltValue(instantiable: false) +abstract interface class $Capabilities_DropAccount_DelayInterface { + bool get enabled; + int get hours; +} + +abstract class Capabilities_DropAccount_Delay + implements + $Capabilities_DropAccount_DelayInterface, + Built { + /// Creates a new Capabilities_DropAccount_Delay object using the builder pattern. + factory Capabilities_DropAccount_Delay([void Function(Capabilities_DropAccount_DelayBuilder)? b]) = + _$Capabilities_DropAccount_Delay; + + // coverage:ignore-start + const Capabilities_DropAccount_Delay._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory Capabilities_DropAccount_Delay.fromJson(Map json) => + _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for Capabilities_DropAccount_Delay. + static Serializer get serializer => _$capabilitiesDropAccountDelaySerializer; +} + +@BuiltValue(instantiable: false) +abstract interface class $Capabilities_DropAccountInterface { + bool get enabled; + @BuiltValueField(wireName: 'api-version') + String get apiVersion; + Capabilities_DropAccount_Delay get delay; + String? get details; +} + +abstract class Capabilities_DropAccount + implements $Capabilities_DropAccountInterface, Built { + /// Creates a new Capabilities_DropAccount object using the builder pattern. + factory Capabilities_DropAccount([void Function(Capabilities_DropAccountBuilder)? b]) = _$Capabilities_DropAccount; + + // coverage:ignore-start + const Capabilities_DropAccount._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory Capabilities_DropAccount.fromJson(Map json) => + _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for Capabilities_DropAccount. + static Serializer get serializer => _$capabilitiesDropAccountSerializer; +} + +@BuiltValue(instantiable: false) +abstract interface class $CapabilitiesInterface { + @BuiltValueField(wireName: 'drop-account') + Capabilities_DropAccount get dropAccount; +} + +abstract class Capabilities implements $CapabilitiesInterface, Built { + /// Creates a new Capabilities object using the builder pattern. + factory Capabilities([void Function(CapabilitiesBuilder)? b]) = _$Capabilities; + + // coverage:ignore-start + const Capabilities._(); + // coverage:ignore-end + + /// Creates a new object from the given [json] data. + /// + /// Use [toJson] to serialize it back into json. + // coverage:ignore-start + factory Capabilities.fromJson(Map json) => _$jsonSerializers.deserializeWith(serializer, json)!; + // coverage:ignore-end + + /// Parses this object into a json like map. + /// + /// Use the fromJson factory to revive it again. + // coverage:ignore-start + Map toJson() => _$jsonSerializers.serializeWith(serializer, this)! as Map; + // coverage:ignore-end + + /// Serializer for Capabilities. + static Serializer get serializer => _$capabilitiesSerializer; +} + +// coverage:ignore-start +/// Serializer for all values in this library. +/// +/// Serializes values into the `built_value` wire format. +/// See: [$jsonSerializers] for serializing into json. +@_i1.visibleForTesting +final Serializers $serializers = _$serializers; +final Serializers _$serializers = (Serializers().toBuilder() + ..addBuilderFactory(const FullType(Capabilities), CapabilitiesBuilder.new) + ..add(Capabilities.serializer) + ..addBuilderFactory(const FullType(Capabilities_DropAccount), Capabilities_DropAccountBuilder.new) + ..add(Capabilities_DropAccount.serializer) + ..addBuilderFactory(const FullType(Capabilities_DropAccount_Delay), Capabilities_DropAccount_DelayBuilder.new) + ..add(Capabilities_DropAccount_Delay.serializer)) + .build(); + +/// Serializer for all values in this library. +/// +/// Serializes values into the json. Json serialization is more expensive than the built_value wire format. +/// See: [$serializers] for serializing into the `built_value` wire format. +@_i1.visibleForTesting +final Serializers $jsonSerializers = _$jsonSerializers; +final Serializers _$jsonSerializers = (_$serializers.toBuilder() + ..add(_i2.DynamiteDoubleSerializer()) + ..addPlugin(_i3.StandardJsonPlugin()) + ..addPlugin(const _i2.HeaderPlugin()) + ..addPlugin(const _i2.ContentStringPlugin())) + .build(); +// coverage:ignore-end diff --git a/packages/nextcloud/lib/src/api/drop_account.openapi.g.dart b/packages/nextcloud/lib/src/api/drop_account.openapi.g.dart new file mode 100644 index 00000000000..1f2f8a4a3a6 --- /dev/null +++ b/packages/nextcloud/lib/src/api/drop_account.openapi.g.dart @@ -0,0 +1,503 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'drop_account.openapi.dart'; + +// ************************************************************************** +// BuiltValueGenerator +// ************************************************************************** + +Serializer _$capabilitiesDropAccountDelaySerializer = + _$Capabilities_DropAccount_DelaySerializer(); +Serializer _$capabilitiesDropAccountSerializer = _$Capabilities_DropAccountSerializer(); +Serializer _$capabilitiesSerializer = _$CapabilitiesSerializer(); + +class _$Capabilities_DropAccount_DelaySerializer implements StructuredSerializer { + @override + final Iterable types = const [Capabilities_DropAccount_Delay, _$Capabilities_DropAccount_Delay]; + @override + final String wireName = 'Capabilities_DropAccount_Delay'; + + @override + Iterable serialize(Serializers serializers, Capabilities_DropAccount_Delay object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'enabled', + serializers.serialize(object.enabled, specifiedType: const FullType(bool)), + 'hours', + serializers.serialize(object.hours, specifiedType: const FullType(int)), + ]; + + return result; + } + + @override + Capabilities_DropAccount_Delay deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = Capabilities_DropAccount_DelayBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'enabled': + result.enabled = serializers.deserialize(value, specifiedType: const FullType(bool))! as bool; + break; + case 'hours': + result.hours = serializers.deserialize(value, specifiedType: const FullType(int))! as int; + break; + } + } + + return result.build(); + } +} + +class _$Capabilities_DropAccountSerializer implements StructuredSerializer { + @override + final Iterable types = const [Capabilities_DropAccount, _$Capabilities_DropAccount]; + @override + final String wireName = 'Capabilities_DropAccount'; + + @override + Iterable serialize(Serializers serializers, Capabilities_DropAccount object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'enabled', + serializers.serialize(object.enabled, specifiedType: const FullType(bool)), + 'api-version', + serializers.serialize(object.apiVersion, specifiedType: const FullType(String)), + 'delay', + serializers.serialize(object.delay, specifiedType: const FullType(Capabilities_DropAccount_Delay)), + ]; + Object? value; + value = object.details; + if (value != null) { + result + ..add('details') + ..add(serializers.serialize(value, specifiedType: const FullType(String))); + } + return result; + } + + @override + Capabilities_DropAccount deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = Capabilities_DropAccountBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'enabled': + result.enabled = serializers.deserialize(value, specifiedType: const FullType(bool))! as bool; + break; + case 'api-version': + result.apiVersion = serializers.deserialize(value, specifiedType: const FullType(String))! as String; + break; + case 'delay': + result.delay.replace(serializers.deserialize(value, + specifiedType: const FullType(Capabilities_DropAccount_Delay))! as Capabilities_DropAccount_Delay); + break; + case 'details': + result.details = serializers.deserialize(value, specifiedType: const FullType(String)) as String?; + break; + } + } + + return result.build(); + } +} + +class _$CapabilitiesSerializer implements StructuredSerializer { + @override + final Iterable types = const [Capabilities, _$Capabilities]; + @override + final String wireName = 'Capabilities'; + + @override + Iterable serialize(Serializers serializers, Capabilities object, + {FullType specifiedType = FullType.unspecified}) { + final result = [ + 'drop-account', + serializers.serialize(object.dropAccount, specifiedType: const FullType(Capabilities_DropAccount)), + ]; + + return result; + } + + @override + Capabilities deserialize(Serializers serializers, Iterable serialized, + {FullType specifiedType = FullType.unspecified}) { + final result = CapabilitiesBuilder(); + + final iterator = serialized.iterator; + while (iterator.moveNext()) { + final key = iterator.current! as String; + iterator.moveNext(); + final Object? value = iterator.current; + switch (key) { + case 'drop-account': + result.dropAccount.replace(serializers.deserialize(value, + specifiedType: const FullType(Capabilities_DropAccount))! as Capabilities_DropAccount); + break; + } + } + + return result.build(); + } +} + +abstract mixin class $Capabilities_DropAccount_DelayInterfaceBuilder { + void replace($Capabilities_DropAccount_DelayInterface other); + void update(void Function($Capabilities_DropAccount_DelayInterfaceBuilder) updates); + bool? get enabled; + set enabled(bool? enabled); + + int? get hours; + set hours(int? hours); +} + +class _$Capabilities_DropAccount_Delay extends Capabilities_DropAccount_Delay { + @override + final bool enabled; + @override + final int hours; + + factory _$Capabilities_DropAccount_Delay([void Function(Capabilities_DropAccount_DelayBuilder)? updates]) => + (Capabilities_DropAccount_DelayBuilder()..update(updates))._build(); + + _$Capabilities_DropAccount_Delay._({required this.enabled, required this.hours}) : super._() { + BuiltValueNullFieldError.checkNotNull(enabled, r'Capabilities_DropAccount_Delay', 'enabled'); + BuiltValueNullFieldError.checkNotNull(hours, r'Capabilities_DropAccount_Delay', 'hours'); + } + + @override + Capabilities_DropAccount_Delay rebuild(void Function(Capabilities_DropAccount_DelayBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + Capabilities_DropAccount_DelayBuilder toBuilder() => Capabilities_DropAccount_DelayBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is Capabilities_DropAccount_Delay && enabled == other.enabled && hours == other.hours; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, enabled.hashCode); + _$hash = $jc(_$hash, hours.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'Capabilities_DropAccount_Delay') + ..add('enabled', enabled) + ..add('hours', hours)) + .toString(); + } +} + +class Capabilities_DropAccount_DelayBuilder + implements + Builder, + $Capabilities_DropAccount_DelayInterfaceBuilder { + _$Capabilities_DropAccount_Delay? _$v; + + bool? _enabled; + bool? get enabled => _$this._enabled; + set enabled(covariant bool? enabled) => _$this._enabled = enabled; + + int? _hours; + int? get hours => _$this._hours; + set hours(covariant int? hours) => _$this._hours = hours; + + Capabilities_DropAccount_DelayBuilder(); + + Capabilities_DropAccount_DelayBuilder get _$this { + final $v = _$v; + if ($v != null) { + _enabled = $v.enabled; + _hours = $v.hours; + _$v = null; + } + return this; + } + + @override + void replace(covariant Capabilities_DropAccount_Delay other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$Capabilities_DropAccount_Delay; + } + + @override + void update(void Function(Capabilities_DropAccount_DelayBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + Capabilities_DropAccount_Delay build() => _build(); + + _$Capabilities_DropAccount_Delay _build() { + final _$result = _$v ?? + _$Capabilities_DropAccount_Delay._( + enabled: BuiltValueNullFieldError.checkNotNull(enabled, r'Capabilities_DropAccount_Delay', 'enabled'), + hours: BuiltValueNullFieldError.checkNotNull(hours, r'Capabilities_DropAccount_Delay', 'hours')); + replace(_$result); + return _$result; + } +} + +abstract mixin class $Capabilities_DropAccountInterfaceBuilder { + void replace($Capabilities_DropAccountInterface other); + void update(void Function($Capabilities_DropAccountInterfaceBuilder) updates); + bool? get enabled; + set enabled(bool? enabled); + + String? get apiVersion; + set apiVersion(String? apiVersion); + + Capabilities_DropAccount_DelayBuilder get delay; + set delay(Capabilities_DropAccount_DelayBuilder? delay); + + String? get details; + set details(String? details); +} + +class _$Capabilities_DropAccount extends Capabilities_DropAccount { + @override + final bool enabled; + @override + final String apiVersion; + @override + final Capabilities_DropAccount_Delay delay; + @override + final String? details; + + factory _$Capabilities_DropAccount([void Function(Capabilities_DropAccountBuilder)? updates]) => + (Capabilities_DropAccountBuilder()..update(updates))._build(); + + _$Capabilities_DropAccount._({required this.enabled, required this.apiVersion, required this.delay, this.details}) + : super._() { + BuiltValueNullFieldError.checkNotNull(enabled, r'Capabilities_DropAccount', 'enabled'); + BuiltValueNullFieldError.checkNotNull(apiVersion, r'Capabilities_DropAccount', 'apiVersion'); + BuiltValueNullFieldError.checkNotNull(delay, r'Capabilities_DropAccount', 'delay'); + } + + @override + Capabilities_DropAccount rebuild(void Function(Capabilities_DropAccountBuilder) updates) => + (toBuilder()..update(updates)).build(); + + @override + Capabilities_DropAccountBuilder toBuilder() => Capabilities_DropAccountBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is Capabilities_DropAccount && + enabled == other.enabled && + apiVersion == other.apiVersion && + delay == other.delay && + details == other.details; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, enabled.hashCode); + _$hash = $jc(_$hash, apiVersion.hashCode); + _$hash = $jc(_$hash, delay.hashCode); + _$hash = $jc(_$hash, details.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'Capabilities_DropAccount') + ..add('enabled', enabled) + ..add('apiVersion', apiVersion) + ..add('delay', delay) + ..add('details', details)) + .toString(); + } +} + +class Capabilities_DropAccountBuilder + implements + Builder, + $Capabilities_DropAccountInterfaceBuilder { + _$Capabilities_DropAccount? _$v; + + bool? _enabled; + bool? get enabled => _$this._enabled; + set enabled(covariant bool? enabled) => _$this._enabled = enabled; + + String? _apiVersion; + String? get apiVersion => _$this._apiVersion; + set apiVersion(covariant String? apiVersion) => _$this._apiVersion = apiVersion; + + Capabilities_DropAccount_DelayBuilder? _delay; + Capabilities_DropAccount_DelayBuilder get delay => _$this._delay ??= Capabilities_DropAccount_DelayBuilder(); + set delay(covariant Capabilities_DropAccount_DelayBuilder? delay) => _$this._delay = delay; + + String? _details; + String? get details => _$this._details; + set details(covariant String? details) => _$this._details = details; + + Capabilities_DropAccountBuilder(); + + Capabilities_DropAccountBuilder get _$this { + final $v = _$v; + if ($v != null) { + _enabled = $v.enabled; + _apiVersion = $v.apiVersion; + _delay = $v.delay.toBuilder(); + _details = $v.details; + _$v = null; + } + return this; + } + + @override + void replace(covariant Capabilities_DropAccount other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$Capabilities_DropAccount; + } + + @override + void update(void Function(Capabilities_DropAccountBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + Capabilities_DropAccount build() => _build(); + + _$Capabilities_DropAccount _build() { + _$Capabilities_DropAccount _$result; + try { + _$result = _$v ?? + _$Capabilities_DropAccount._( + enabled: BuiltValueNullFieldError.checkNotNull(enabled, r'Capabilities_DropAccount', 'enabled'), + apiVersion: BuiltValueNullFieldError.checkNotNull(apiVersion, r'Capabilities_DropAccount', 'apiVersion'), + delay: delay.build(), + details: details); + } catch (_) { + late String _$failedField; + try { + _$failedField = 'delay'; + delay.build(); + } catch (e) { + throw BuiltValueNestedFieldError(r'Capabilities_DropAccount', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +abstract mixin class $CapabilitiesInterfaceBuilder { + void replace($CapabilitiesInterface other); + void update(void Function($CapabilitiesInterfaceBuilder) updates); + Capabilities_DropAccountBuilder get dropAccount; + set dropAccount(Capabilities_DropAccountBuilder? dropAccount); +} + +class _$Capabilities extends Capabilities { + @override + final Capabilities_DropAccount dropAccount; + + factory _$Capabilities([void Function(CapabilitiesBuilder)? updates]) => + (CapabilitiesBuilder()..update(updates))._build(); + + _$Capabilities._({required this.dropAccount}) : super._() { + BuiltValueNullFieldError.checkNotNull(dropAccount, r'Capabilities', 'dropAccount'); + } + + @override + Capabilities rebuild(void Function(CapabilitiesBuilder) updates) => (toBuilder()..update(updates)).build(); + + @override + CapabilitiesBuilder toBuilder() => CapabilitiesBuilder()..replace(this); + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is Capabilities && dropAccount == other.dropAccount; + } + + @override + int get hashCode { + var _$hash = 0; + _$hash = $jc(_$hash, dropAccount.hashCode); + _$hash = $jf(_$hash); + return _$hash; + } + + @override + String toString() { + return (newBuiltValueToStringHelper(r'Capabilities')..add('dropAccount', dropAccount)).toString(); + } +} + +class CapabilitiesBuilder implements Builder, $CapabilitiesInterfaceBuilder { + _$Capabilities? _$v; + + Capabilities_DropAccountBuilder? _dropAccount; + Capabilities_DropAccountBuilder get dropAccount => _$this._dropAccount ??= Capabilities_DropAccountBuilder(); + set dropAccount(covariant Capabilities_DropAccountBuilder? dropAccount) => _$this._dropAccount = dropAccount; + + CapabilitiesBuilder(); + + CapabilitiesBuilder get _$this { + final $v = _$v; + if ($v != null) { + _dropAccount = $v.dropAccount.toBuilder(); + _$v = null; + } + return this; + } + + @override + void replace(covariant Capabilities other) { + ArgumentError.checkNotNull(other, 'other'); + _$v = other as _$Capabilities; + } + + @override + void update(void Function(CapabilitiesBuilder)? updates) { + if (updates != null) updates(this); + } + + @override + Capabilities build() => _build(); + + _$Capabilities _build() { + _$Capabilities _$result; + try { + _$result = _$v ?? _$Capabilities._(dropAccount: dropAccount.build()); + } catch (_) { + late String _$failedField; + try { + _$failedField = 'dropAccount'; + dropAccount.build(); + } catch (e) { + throw BuiltValueNestedFieldError(r'Capabilities', _$failedField, e.toString()); + } + rethrow; + } + replace(_$result); + return _$result; + } +} + +// ignore_for_file: deprecated_member_use_from_same_package,type=lint diff --git a/packages/nextcloud/lib/src/api/drop_account.openapi.json b/packages/nextcloud/lib/src/api/drop_account.openapi.json new file mode 100644 index 00000000000..e23ea9a7e15 --- /dev/null +++ b/packages/nextcloud/lib/src/api/drop_account.openapi.json @@ -0,0 +1,73 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "drop_account", + "version": "0.0.1", + "description": "An app to allow users to delete their accounts.", + "license": { + "name": "agpl", + "identifier": "AGPL-3.0-only" + } + }, + "components": { + "securitySchemes": { + "basic_auth": { + "type": "http", + "scheme": "basic" + }, + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "Capabilities": { + "type": "object", + "required": [ + "drop-account" + ], + "properties": { + "drop-account": { + "type": "object", + "required": [ + "enabled", + "api-version", + "delay", + "details" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "api-version": { + "type": "string" + }, + "delay": { + "type": "object", + "required": [ + "enabled", + "hours" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "hours": { + "type": "integer", + "format": "int64" + } + } + }, + "details": { + "type": "string", + "nullable": true + } + } + } + } + } + } + }, + "paths": {}, + "tags": [] +} diff --git a/packages/nextcloud/lib/src/patches/drop_account/0-password-confirmation.json b/packages/nextcloud/lib/src/patches/drop_account/0-password-confirmation.json new file mode 100644 index 00000000000..9a02cfdcd66 --- /dev/null +++ b/packages/nextcloud/lib/src/patches/drop_account/0-password-confirmation.json @@ -0,0 +1,11 @@ +[ + { + "op": "replace", + "path": "/paths", + "value": {} + }, + { + "op": "remove", + "path": "/components/schemas/OCSMeta" + } +] diff --git a/packages/nextcloud/test/core_test.dart b/packages/nextcloud/test/core_test.dart index 87781ea65b9..75fea0163ce 100644 --- a/packages/nextcloud/test/core_test.dart +++ b/packages/nextcloud/test/core_test.dart @@ -66,6 +66,7 @@ void main() { expect(response.body.ocs.data.capabilities.commentsCapabilities, isNotNull); expect(response.body.ocs.data.capabilities.davCapabilities, isNotNull); + expect(response.body.ocs.data.capabilities.dropAccountCapabilities, isNotNull); expect(response.body.ocs.data.capabilities.filesCapabilities, isNotNull); expect(response.body.ocs.data.capabilities.filesSharingCapabilities, isNotNull); expect(response.body.ocs.data.capabilities.filesTrashbinCapabilities, isNotNull); diff --git a/tool/generate-specs.sh b/tool/generate-specs.sh index e0e6e5ae7cd..a8c6a161445 100755 --- a/tool/generate-specs.sh +++ b/tool/generate-specs.sh @@ -57,6 +57,10 @@ done cd external/nextcloud-spreed generate_spec "." "spreed" ) +( + cd external/nextcloud-drop_account + generate_spec "." "drop_account" +) for spec in /tmp/nextcloud-neon/*.openapi.json; do name="$(basename "$spec" | cut -d "." -f 1)" From f3d9966b9bed86ba15990b0164f651c5b5ee6760 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Tue, 27 Feb 2024 15:42:13 +0100 Subject: [PATCH 3/3] feat(neon_framework): Implement deleting accounts on the server Signed-off-by: provokateurin --- packages/neon_framework/lib/l10n/en.arb | 11 ++ .../lib/l10n/localizations.dart | 24 +++ .../lib/l10n/localizations_en.dart | 14 ++ .../lib/src/pages/account_settings.dart | 44 +++-- .../lib/src/widgets/dialog.dart | 138 ++++++++++++++ packages/neon_framework/lib/widgets.dart | 3 +- packages/neon_framework/test/dialog_test.dart | 177 ++++++++++++++++++ 7 files changed, 391 insertions(+), 20 deletions(-) diff --git a/packages/neon_framework/lib/l10n/en.arb b/packages/neon_framework/lib/l10n/en.arb index dd4d8ab2957..b2bbf66cf22 100644 --- a/packages/neon_framework/lib/l10n/en.arb +++ b/packages/neon_framework/lib/l10n/en.arb @@ -157,6 +157,7 @@ "globalOptionsNavigationMode": "Navigation mode", "globalOptionsNavigationModeDrawer": "Drawer", "globalOptionsNavigationModeDrawerAlwaysVisible": "Drawer always visible", + "accountOptionsDeleteOnServer": "Delete account on the server", "accountOptionsRemove": "Remove account", "accountOptionsRemoveConfirm": "Are you sure you want to remove the account {id}?", "@accountOptionsRemoveConfirm": { @@ -166,6 +167,16 @@ } } }, + "accountOptionsRemoveLocal": "Remove the account from the device", + "accountOptionsRemoveRemote": "Request deleting the account on the server", + "accountOptionsRemoveRemoteDelay": "The account will be deleted after {time}", + "@accountOptionsRemoveRemoteDelay": { + "placeholders": { + "time": { + "type": "String" + } + } + }, "accountOptionsCategoryStorageInfo": "Storage info", "accountOptionsQuotaUsedOf": "{used} used of {total} ({relative}%)", "@accountOptionsQuotaUsedOf": { diff --git a/packages/neon_framework/lib/l10n/localizations.dart b/packages/neon_framework/lib/l10n/localizations.dart index 98e85640291..85b7cfb9243 100644 --- a/packages/neon_framework/lib/l10n/localizations.dart +++ b/packages/neon_framework/lib/l10n/localizations.dart @@ -665,6 +665,12 @@ abstract class NeonLocalizations { /// **'Drawer always visible'** String get globalOptionsNavigationModeDrawerAlwaysVisible; + /// No description provided for @accountOptionsDeleteOnServer. + /// + /// In en, this message translates to: + /// **'Delete account on the server'** + String get accountOptionsDeleteOnServer; + /// No description provided for @accountOptionsRemove. /// /// In en, this message translates to: @@ -677,6 +683,24 @@ abstract class NeonLocalizations { /// **'Are you sure you want to remove the account {id}?'** String accountOptionsRemoveConfirm(String id); + /// No description provided for @accountOptionsRemoveLocal. + /// + /// In en, this message translates to: + /// **'Remove the account from the device'** + String get accountOptionsRemoveLocal; + + /// No description provided for @accountOptionsRemoveRemote. + /// + /// In en, this message translates to: + /// **'Request deleting the account on the server'** + String get accountOptionsRemoveRemote; + + /// No description provided for @accountOptionsRemoveRemoteDelay. + /// + /// In en, this message translates to: + /// **'The account will be deleted after {time}'** + String accountOptionsRemoveRemoteDelay(String time); + /// No description provided for @accountOptionsCategoryStorageInfo. /// /// In en, this message translates to: diff --git a/packages/neon_framework/lib/l10n/localizations_en.dart b/packages/neon_framework/lib/l10n/localizations_en.dart index 85dc61735d9..fe00aeb9120 100644 --- a/packages/neon_framework/lib/l10n/localizations_en.dart +++ b/packages/neon_framework/lib/l10n/localizations_en.dart @@ -332,6 +332,9 @@ class NeonLocalizationsEn extends NeonLocalizations { @override String get globalOptionsNavigationModeDrawerAlwaysVisible => 'Drawer always visible'; + @override + String get accountOptionsDeleteOnServer => 'Delete account on the server'; + @override String get accountOptionsRemove => 'Remove account'; @@ -340,6 +343,17 @@ class NeonLocalizationsEn extends NeonLocalizations { return 'Are you sure you want to remove the account $id?'; } + @override + String get accountOptionsRemoveLocal => 'Remove the account from the device'; + + @override + String get accountOptionsRemoveRemote => 'Request deleting the account on the server'; + + @override + String accountOptionsRemoveRemoteDelay(String time) { + return 'The account will be deleted after $time'; + } + @override String get accountOptionsCategoryStorageInfo => 'Storage info'; diff --git a/packages/neon_framework/lib/src/pages/account_settings.dart b/packages/neon_framework/lib/src/pages/account_settings.dart index f7588d26b33..2b5ebd6e34c 100644 --- a/packages/neon_framework/lib/src/pages/account_settings.dart +++ b/packages/neon_framework/lib/src/pages/account_settings.dart @@ -15,6 +15,7 @@ import 'package:neon_framework/src/theme/dialog.dart'; import 'package:neon_framework/src/utils/adaptive.dart'; import 'package:neon_framework/src/widgets/dialog.dart'; import 'package:neon_framework/src/widgets/error.dart'; +import 'package:url_launcher/url_launcher.dart'; /// Account settings page. /// @@ -45,32 +46,37 @@ class AccountSettingsPage extends StatelessWidget { actions: [ IconButton( onPressed: () async { - final decision = await showAdaptiveDialog( + final decision = await showAdaptiveDialog( context: context, - builder: (context) => NeonConfirmationDialog( - icon: const Icon(Icons.logout), - title: NeonLocalizations.of(context).accountOptionsRemove, - content: Text( - NeonLocalizations.of(context).accountOptionsRemoveConfirm(account.humanReadableID), - ), + builder: (context) => NeonAccountDeletionDialog( + account: account, ), ); - if (decision ?? false) { - final isActive = bloc.activeAccount.valueOrNull == account; + switch (decision) { + case null: + break; + case AccountDeletion.remote: + await launchUrl( + account.serverURL.replace( + path: '${account.serverURL.path}/index.php/settings/user/drop_account', + ), + ); + case AccountDeletion.local: + final isActive = bloc.activeAccount.valueOrNull == account; - options.reset(); - bloc.removeAccount(account); + options.reset(); + bloc.removeAccount(account); - if (!context.mounted) { - return; - } + if (!context.mounted) { + return; + } - if (isActive) { - const HomeRoute().go(context); - } else { - Navigator.of(context).pop(); - } + if (isActive) { + const HomeRoute().go(context); + } else { + Navigator.of(context).pop(); + } } }, tooltip: NeonLocalizations.of(context).accountOptionsRemove, diff --git a/packages/neon_framework/lib/src/widgets/dialog.dart b/packages/neon_framework/lib/src/widgets/dialog.dart index 8e6437190c6..14f4c4e0bf8 100644 --- a/packages/neon_framework/lib/src/widgets/dialog.dart +++ b/packages/neon_framework/lib/src/widgets/dialog.dart @@ -8,6 +8,7 @@ import 'package:meta/meta.dart'; import 'package:neon_framework/blocs.dart'; import 'package:neon_framework/src/models/account.dart'; import 'package:neon_framework/src/utils/global_options.dart'; +import 'package:neon_framework/src/utils/relative_time.dart'; import 'package:neon_framework/src/utils/user_status_clear_at.dart'; import 'package:neon_framework/src/widgets/account_tile.dart'; import 'package:neon_framework/src/widgets/error.dart'; @@ -15,6 +16,7 @@ import 'package:neon_framework/src/widgets/linear_progress_indicator.dart'; import 'package:neon_framework/src/widgets/user_status_icon.dart'; import 'package:neon_framework/theme.dart'; import 'package:neon_framework/utils.dart'; +import 'package:nextcloud/core.dart' as core; import 'package:nextcloud/user_status.dart' as user_status; import 'package:url_launcher/url_launcher_string.dart'; @@ -517,6 +519,142 @@ class NeonAccountSelectionDialog extends StatelessWidget { } } +/// The way the account will be deleted. +@internal +enum AccountDeletion { + /// The account is removed from the app. + local, + + /// The account is deleted on the server. + remote, +} + +@internal + +/// Displays a confirmation dialog for deleting the [account]. +/// +/// If the `drop_account` app is enabled the user can also choose to delete the account on the server +/// instead of only logging out the account. +/// +/// Will pop a value of type [AccountDeletion] or null if the user canceled the dialog. +class NeonAccountDeletionDialog extends StatefulWidget { + const NeonAccountDeletionDialog({ + required this.account, + super.key, + }); + + final Account account; + + @override + State createState() => _NeonAccountDeletionDialogState(); +} + +class _NeonAccountDeletionDialogState extends State { + core.DropAccountCapabilities_DropAccount? dropAccountCapabilities; + AccountDeletion value = AccountDeletion.local; + + void update(AccountDeletion value) { + setState(() { + this.value = value; + }); + } + + @override + void initState() { + super.initState(); + + NeonProvider.of(context).getCapabilitiesBlocFor(widget.account).capabilities.listen((result) { + setState(() { + dropAccountCapabilities = result.data?.capabilities.dropAccountCapabilities?.dropAccount; + if (!(dropAccountCapabilities?.enabled ?? false)) { + value = AccountDeletion.local; + } + }); + }); + } + + @override + Widget build(BuildContext context) { + final localizations = NeonLocalizations.of(context); + + const icon = Icon(Icons.logout); + final title = localizations.accountOptionsRemove; + final confirmAction = NeonDialogAction( + isDestructiveAction: true, + onPressed: () { + Navigator.of(context).pop(value); + }, + child: Text( + localizations.actionContinue, + textAlign: TextAlign.end, + ), + ); + final declineAction = NeonDialogAction( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text( + localizations.actionCancel, + textAlign: TextAlign.end, + ), + ); + + final capabilities = dropAccountCapabilities; + if (capabilities == null) { + return NeonConfirmationDialog( + icon: icon, + title: title, + content: Text(localizations.accountOptionsRemoveConfirm(widget.account.humanReadableID)), + confirmAction: confirmAction, + declineAction: declineAction, + ); + } + + Widget? subtitle; + final details = capabilities.details; + if (details != null) { + subtitle = Text(details); + } else if (capabilities.delay.enabled) { + subtitle = Text( + localizations.accountOptionsRemoveRemoteDelay( + Duration(hours: capabilities.delay.hours).formatRelative( + localizations, + includeSign: false, + ), + ), + ); + } + + return NeonDialog( + icon: icon, + title: Text(title), + content: SingleChildScrollView( + child: Column( + children: [ + RadioListTile( + value: AccountDeletion.local, + groupValue: value, + onChanged: (value) => update(value!), + title: Text(localizations.accountOptionsRemoveLocal), + ), + RadioListTile( + value: AccountDeletion.remote, + groupValue: value, + onChanged: capabilities.enabled ? (value) => update(value!) : null, + title: Text(localizations.accountOptionsRemoveRemote), + subtitle: subtitle, + ), + ], + ), + ), + actions: [ + declineAction, + confirmAction, + ], + ); + } +} + /// A [NeonDialog] to inform the user about the UnifiedPush feature of neon. @internal class NeonUnifiedPushDialog extends StatelessWidget { diff --git a/packages/neon_framework/lib/widgets.dart b/packages/neon_framework/lib/widgets.dart index a885884bc04..fac6ab9cf27 100644 --- a/packages/neon_framework/lib/widgets.dart +++ b/packages/neon_framework/lib/widgets.dart @@ -1,5 +1,6 @@ export 'package:neon_framework/src/widgets/custom_background.dart'; -export 'package:neon_framework/src/widgets/dialog.dart' hide NeonAccountSelectionDialog, NeonUnifiedPushDialog; +export 'package:neon_framework/src/widgets/dialog.dart' + hide AccountDeletion, NeonAccountDeletionDialog, NeonAccountSelectionDialog, NeonUnifiedPushDialog; export 'package:neon_framework/src/widgets/error.dart'; export 'package:neon_framework/src/widgets/image.dart' hide NeonImage; export 'package:neon_framework/src/widgets/linear_progress_indicator.dart'; diff --git a/packages/neon_framework/test/dialog_test.dart b/packages/neon_framework/test/dialog_test.dart index 6df26b266e3..f41d4bf52e8 100644 --- a/packages/neon_framework/test/dialog_test.dart +++ b/packages/neon_framework/test/dialog_test.dart @@ -7,6 +7,7 @@ import 'package:neon_framework/l10n/localizations_en.dart'; import 'package:neon_framework/src/widgets/dialog.dart'; import 'package:neon_framework/testing.dart'; import 'package:neon_framework/utils.dart'; +import 'package:nextcloud/core.dart' as core; import 'package:nextcloud/user_status.dart' as user_status; import 'package:rxdart/rxdart.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -365,4 +366,180 @@ void main() { await predefinedStatuses.close(); }); }); + + group('NeonAccountDeletionDialog', () { + core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data buildCapabilities( + core.DropAccountCapabilities? capabilities, + ) => + core.OcsGetCapabilitiesResponseApplicationJson_Ocs_Data( + (b) => b + ..version.update( + (b) => b + ..major = 0 + ..minor = 0 + ..micro = 0 + ..string = '' + ..edition = '' + ..extendedSupport = false, + ) + ..capabilities = ( + // We need to provide at least one capability because anyOf expects at least one schema to match + commentsCapabilities: core.CommentsCapabilities((b) => b..files.update((b) => b..comments = true)), + davCapabilities: null, + dropAccountCapabilities: capabilities, + filesCapabilities: null, + filesSharingCapabilities: null, + filesTrashbinCapabilities: null, + filesVersionsCapabilities: null, + notesCapabilities: null, + notificationsCapabilities: null, + provisioningApiCapabilities: null, + sharebymailCapabilities: null, + spreedPublicCapabilities: null, + themingPublicCapabilities: null, + userStatusCapabilities: null, + weatherStatusCapabilities: null, + ), + ); + + testWidgets('Without drop_account', (tester) async { + final account = MockAccount(); + when(() => account.humanReadableID).thenReturn(''); + + final capabilitiesBloc = MockCapabilitiesBloc(); + when(() => capabilitiesBloc.capabilities).thenAnswer( + (_) => BehaviorSubject.seeded(Result.success(buildCapabilities(null))), + ); + + final accountsBloc = MockAccountsBloc(); + when(() => accountsBloc.getCapabilitiesBlocFor(account)).thenReturn(capabilitiesBloc); + + await tester.pumpWidget(const TestApp(child: Placeholder())); + final BuildContext context = tester.element(find.byType(Placeholder)); + + final future = showDialog( + context: context, + builder: (context) => NeonProvider( + create: (_) => accountsBloc, + child: NeonAccountDeletionDialog( + account: account, + ), + ), + ); + await tester.pumpAndSettle(); + expect(find.byType(NeonConfirmationDialog), findsOne); + + await tester.tap(find.text(NeonLocalizations.of(context).actionContinue)); + expect(await future, AccountDeletion.local); + }); + + group('With drop_account', () { + testWidgets('Disabled', (tester) async { + final account = MockAccount(); + when(() => account.humanReadableID).thenReturn(''); + + final capabilitiesBloc = MockCapabilitiesBloc(); + when(() => capabilitiesBloc.capabilities).thenAnswer( + (_) => BehaviorSubject.seeded( + Result.success( + buildCapabilities( + core.DropAccountCapabilities( + (b) => b + ..dropAccount.update( + (b) => b + ..apiVersion = '' + ..enabled = false + ..details = 'disabled' + ..delay.update( + (b) => b + ..enabled = false + ..hours = 0, + ), + ), + ), + ), + ), + ), + ); + + final accountsBloc = MockAccountsBloc(); + when(() => accountsBloc.getCapabilitiesBlocFor(account)).thenReturn(capabilitiesBloc); + + await tester.pumpWidget(const TestApp(child: Placeholder())); + final BuildContext context = tester.element(find.byType(Placeholder)); + + final future = showDialog( + context: context, + builder: (context) => NeonProvider( + create: (_) => accountsBloc, + child: NeonAccountDeletionDialog( + account: account, + ), + ), + ); + await tester.pumpAndSettle(); + expect(find.byType(NeonConfirmationDialog), findsNothing); + expect(find.byType(RadioListTile), findsExactly(2)); + + expect(find.text('disabled'), findsOne); + await tester.tap(find.text('disabled')); + + await tester.tap(find.text(NeonLocalizations.of(context).actionContinue)); + expect(await future, AccountDeletion.local); + }); + + testWidgets('Delay', (tester) async { + final account = MockAccount(); + when(() => account.humanReadableID).thenReturn(''); + + final capabilitiesBloc = MockCapabilitiesBloc(); + when(() => capabilitiesBloc.capabilities).thenAnswer( + (_) => BehaviorSubject.seeded( + Result.success( + buildCapabilities( + core.DropAccountCapabilities( + (b) => b + ..dropAccount.update( + (b) => b + ..apiVersion = '' + ..enabled = true + ..delay.update( + (b) => b + ..enabled = true + ..hours = 12, + ), + ), + ), + ), + ), + ), + ); + + final accountsBloc = MockAccountsBloc(); + when(() => accountsBloc.getCapabilitiesBlocFor(account)).thenReturn(capabilitiesBloc); + + await tester.pumpWidget(const TestApp(child: Placeholder())); + final BuildContext context = tester.element(find.byType(Placeholder)); + + final future = showDialog( + context: context, + builder: (context) => NeonProvider( + create: (_) => accountsBloc, + child: NeonAccountDeletionDialog( + account: account, + ), + ), + ); + await tester.pumpAndSettle(); + expect(find.byType(NeonConfirmationDialog), findsNothing); + expect(find.byType(RadioListTile), findsExactly(2)); + + expect(find.text(NeonLocalizations.of(context).accountOptionsRemoveRemoteDelay('12 hours')), findsOne); + await tester.tap(find.text(NeonLocalizations.of(context).accountOptionsRemoveRemoteDelay('12 hours'))); + + await tester.tap(find.text(NeonLocalizations.of(context).actionContinue)); + expect(await future, AccountDeletion.remote); + }); + }); + }); }