diff --git a/.github/workflows/hidrive-next-build.yml b/.github/workflows/hidrive-next-build.yml new file mode 100644 index 0000000000000..83c83097ca63e --- /dev/null +++ b/.github/workflows/hidrive-next-build.yml @@ -0,0 +1,186 @@ +name: HiDrive Next Build + +# SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors +# SPDX-FileCopyrightText: 2024 STRATO AG +# SPDX-License-Identifier: AGPL-3.0-or-later + +# The HiDrive Next source is packaged as a container image. +# This is a workaround because releases can not be created without tags +# and we want to be able to create snapshots from branches. + +on: + pull_request: + paths: + - '.github/workflows/**' + - 'src/**' + - 'custom-npms/**' + - 'apps/**' + - 'apps/**/appinfo/info.xml' + - 'apps-custom/**' + - 'package.json' + - 'package-lock.json' + - 'themes/**' + - 'tsconfig.json' + - '**.js' + - '**.ts' + - '**.vue' + push: + branches: + - main + - master + - stable* + - ionos-dev + - ionos-dev30 + +env: + TARGET_PACKAGE_NAME: hidrive-next.zip + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +permissions: + contents: read + +jobs: + hidrive-next-build: + runs-on: self-hosted + + permissions: + contents: read + packages: write + + name: hidrive-next-build + steps: + - name: Checkout server + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 + with: + submodules: true + + - name: Set up node with version from package.json's engines + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version-file: "package.json" + + - name: Install Dependencies + run: sudo apt-get update && sudo apt-get install -y make zip unzip + + - name: Print dependencies versions + run: make --version && node --version && npm --version + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 #v2.31.1 + with: + tools: composer:v2 + extensions: gd, zip, curl, xml, xmlrpc, mbstring, sqlite, xdebug, pgsql, intl, imagick, gmp, apcu, bcmath, redis, soap, imap, opcache + env: + runner: self-hosted + + - name: Print PHP install + run: php -i && php -m + + - name: Build Nextcloud + run: make -f IONOS/Makefile build_nextcloud FONTAWESOME_PACKAGE_TOKEN=${{ secrets.FONTAWESOME_PACKAGE_TOKEN }} + + - name: Install dependencies & build simplesettings app + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: make -f IONOS/Makefile build_dep_simplesettings_app + + - name: Install dependencies & build viewer app + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: make -f IONOS/Makefile build_dep_viewer_app + + - name: Install dependencies & build user_oidc app + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: make -f IONOS/Makefile build_dep_user_oidc_app + + - name: Install dependencies for external apps nc_ionos_processes + run: make -f IONOS/Makefile build_dep_nc_ionos_processes_app + + - name: Build Custom CSS + run: make -f IONOS/Makefile build_dep_theming_app + + - name: Install dependencies & build IONOS theme custom elements + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: make -f IONOS/Makefile build_dep_ionos_theme + + - name: Add config partials + run: make -f IONOS/Makefile add_config_partials + + - name: Zip dependencies + run: make -f IONOS/Makefile zip_dependencies TARGET_PACKAGE_NAME=${{ env.TARGET_PACKAGE_NAME }} + + - name: Upload artifact result for job hidrive-next-build + uses: actions/upload-artifact@v4 + with: + name: hidrive_next_build_zip + path: ${{ env.TARGET_PACKAGE_NAME }} + + - name: Show changes on failure + if: failure() + run: | + git status + git --no-pager diff + exit 1 # make it red to grab attention + + hidirve-next-artifact-to-ghcr_io: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + name: Push artifact to ghcr.io + needs: hidrive-next-build + + steps: + - name: Download artifact zip + uses: actions/download-artifact@v4 + with: + name: hidrive_next_build_zip + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + + - name: Create Dockerfile + run: | + cat >Dockerfile << EOF + FROM busybox as builder + COPY ./${{ env.TARGET_PACKAGE_NAME }} / + WORKDIR /builder + RUN unzip /${{ env.TARGET_PACKAGE_NAME }} -d /builder + + FROM scratch + WORKDIR /app + VOLUME /app + COPY --from=builder /builder /app + EOF + + - name: Build and push Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + - name: Show changes on failure + if: failure() + run: | + exit 1 # make it red to grab attention diff --git a/.gitignore b/.gitignore index 5b747559a8224..8ace611660533 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,11 @@ /apps/files_external/3rdparty/irodsphp/prods/tutorials /apps/files_external/3rdparty/irodsphp/prods/test* /apps/files_external/tests/config.*.php +# IONOS: this should not be upsteamed! +!/apps-external/viewer +!/apps-external/user_oidc +!/apps-external/serverinfo +!/apps-custom/* # apps modules /apps/*/node_modules diff --git a/.gitmodules b/.gitmodules index 61195b5d6fd81..c58f281eec412 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,45 @@ [submodule "3rdparty"] path = 3rdparty url = https://github.com/nextcloud/3rdparty.git +[submodule "IONOS"] + path = IONOS + url = git@github.com:IONOS-Productivity/easystorage-config.git +[submodule "apps-external/extract"] + path = apps-external/extract + url = https://github.com/PaulLereverend/NextcloudExtract +[submodule "apps-external/viewer"] + path = apps-external/viewer + url = git@github.com:IONOS-Productivity/nc-viewer.git +[submodule "apps-custom/simplesettings"] + path = apps-custom/simplesettings + url = git@github.com:IONOS-Productivity/nc-simplesettings.git +[submodule "apps-external/user_oidc"] + path = apps-external/user_oidc + url = https://github.com/nextcloud/user_oidc.git +[submodule "apps-custom/googleanalytics"] + path = apps-custom/googleanalytics + url = git@github.com:IONOS-Productivity/nc-googleanalytics.git +[submodule "themes/nc-ionos-theme"] + path = themes/nc-ionos-theme + url = git@github.com:IONOS-Productivity/nc-ionos-theme.git +[submodule "apps-custom/nc_theming"] + path = apps-custom/nc_theming + url = git@github.com:IONOS-Productivity/nc-theming.git +[submodule "custom-npms/nc-vue-material-design-icons"] + path = custom-npms/nc-vue-material-design-icons + url = git@github.com:IONOS-Productivity/nc-vue-material-design-icons.git +[submodule "custom-npms/nc-mdi-svg"] + path = custom-npms/nc-mdi-svg + url = git@github.com:IONOS-Productivity/nc-MaterialDesign-SVG.git +[submodule "custom-npms/nc-mdi-js"] + path = custom-npms/nc-mdi-js + url = git@github.com:IONOS-Productivity/nc-MaterialDesign-JS.git +[submodule "custom-npms/nc-nextcloud-vue"] + path = custom-npms/nc-nextcloud-vue + url = git@github.com:IONOS-Productivity/nc-nextcloud-vue.git +[submodule "apps-custom/nc_ionos_processes"] + path = apps-custom/nc_ionos_processes + url = git@github.com:IONOS-Productivity/nc_ionos_processes.git +[submodule "apps-external/serverinfo"] + path = apps-external/serverinfo + url = git@github.com:nextcloud/serverinfo.git diff --git a/IONOS b/IONOS new file mode 160000 index 0000000000000..9bef88bd02b4c --- /dev/null +++ b/IONOS @@ -0,0 +1 @@ +Subproject commit 9bef88bd02b4c3ff068211b55a88823e40158dcd diff --git a/apps-custom/.gitkeep b/apps-custom/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/apps-custom/googleanalytics b/apps-custom/googleanalytics new file mode 160000 index 0000000000000..d81ec0fa8127b --- /dev/null +++ b/apps-custom/googleanalytics @@ -0,0 +1 @@ +Subproject commit d81ec0fa8127ba6473ba2ccb246d6e1958d7ad69 diff --git a/apps-custom/nc_ionos_processes b/apps-custom/nc_ionos_processes new file mode 160000 index 0000000000000..5ee4b69ebed39 --- /dev/null +++ b/apps-custom/nc_ionos_processes @@ -0,0 +1 @@ +Subproject commit 5ee4b69ebed39714358f29e42f63dd76831682b3 diff --git a/apps-custom/nc_theming b/apps-custom/nc_theming new file mode 160000 index 0000000000000..ea926303e81ea --- /dev/null +++ b/apps-custom/nc_theming @@ -0,0 +1 @@ +Subproject commit ea926303e81ea72e4249c1a1dbe5b198af55d065 diff --git a/apps-custom/simplesettings b/apps-custom/simplesettings new file mode 160000 index 0000000000000..87b3b5196cef7 --- /dev/null +++ b/apps-custom/simplesettings @@ -0,0 +1 @@ +Subproject commit 87b3b5196cef7df580ff244e04cb873066d28360 diff --git a/apps-external/.gitkeep b/apps-external/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/apps-external/serverinfo b/apps-external/serverinfo new file mode 160000 index 0000000000000..fef0b0ecbac78 --- /dev/null +++ b/apps-external/serverinfo @@ -0,0 +1 @@ +Subproject commit fef0b0ecbac78ad03e1094b948c59ca6dafcdfb5 diff --git a/apps-external/user_oidc b/apps-external/user_oidc new file mode 160000 index 0000000000000..40e18224c1232 --- /dev/null +++ b/apps-external/user_oidc @@ -0,0 +1 @@ +Subproject commit 40e18224c1232f6164eef02f8a32809aef49ed19 diff --git a/apps-external/viewer b/apps-external/viewer new file mode 160000 index 0000000000000..fa0873849cd7b --- /dev/null +++ b/apps-external/viewer @@ -0,0 +1 @@ +Subproject commit fa0873849cd7bdacd5e0794e18854baac0c11770 diff --git a/apps/files/lib/Service/UserConfig.php b/apps/files/lib/Service/UserConfig.php index c233996579379..a7c0e62894262 100644 --- a/apps/files/lib/Service/UserConfig.php +++ b/apps/files/lib/Service/UserConfig.php @@ -6,6 +6,7 @@ namespace OCA\Files\Service; use OCA\Files\AppInfo\Application; +use OCP\AppFramework\Services\IAppConfig; use OCP\IConfig; use OCP\IUser; use OCP\IUserSession; @@ -53,7 +54,7 @@ class UserConfig { protected IConfig $config; protected ?IUser $user = null; - public function __construct(IConfig $config, IUserSession $userSession) { + public function __construct(IConfig $config, IUserSession $userSession, protected IAppConfig $appConfig) { $this->config = $config; $this->user = $userSession->getUser(); } @@ -115,7 +116,12 @@ public function setConfig(string $key, $value): void { throw new \InvalidArgumentException('Unknown config key'); } - if (!in_array($value, $this->getAllowedConfigValues($key))) { + $isBoolValue = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + if ($isBoolValue !== null) { + $value = $isBoolValue; + } + + if (!in_array($value, $this->getAllowedConfigValues($key), true)) { throw new \InvalidArgumentException('Invalid config value'); } @@ -138,8 +144,12 @@ public function getConfigs(): array { $userId = $this->user->getUID(); $userConfigs = array_map(function (string $key) use ($userId) { - $value = $this->config->getUserValue($userId, Application::APP_ID, $key, $this->getDefaultConfigValue($key)); - // If the default is expected to be a boolean, we need to cast the value + $value = $this->config->getUserValue($userId, Application::APP_ID, $key, null); + // If the default value is expected to be a boolean, we need to cast the value + if ($value === null) { + $value = $this->appConfig->getAppValueBool($key, $this->getDefaultConfigValue($key)); + } + if (is_bool($this->getDefaultConfigValue($key)) && is_string($value)) { return $value === '1'; } diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index f706ced9cf0e6..2aaab8da727dd 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -566,15 +566,11 @@ export default defineComponent({ width: var(--icon-preview-size); height: var(--icon-preview-size); } - - // Slightly increase the size of the folder icon + // Slightly decrease the size of the folder icon &.folder-icon, - &.folder-open-icon { - margin: -3px; - svg { - width: calc(var(--icon-preview-size) + 6px); - height: calc(var(--icon-preview-size) + 6px); - } + &.folder-open-icon svg { + width: calc(var(--icon-preview-size) - 6px); + height: calc(var(--icon-preview-size) - 6px); } } diff --git a/apps/files/src/components/SidebarQuota.vue b/apps/files/src/components/SidebarQuota.vue new file mode 100644 index 0000000000000..b7127d7a904af --- /dev/null +++ b/apps/files/src/components/SidebarQuota.vue @@ -0,0 +1,161 @@ + + + + + + + diff --git a/apps/files/src/views/Navigation.vue b/apps/files/src/views/Navigation.vue index 9570cb1be6680..2b8475c927283 100644 --- a/apps/files/src/views/Navigation.vue +++ b/apps/files/src/views/Navigation.vue @@ -25,7 +25,7 @@