Compare commits

...

149 Commits

Author SHA1 Message Date
69bfd56ff6 chore(master): release 0.11.0 2025-11-24 20:10:53 +02:00
8476b772e3 fix(l10n): unify same messages with different placeholders 2025-11-24 18:44:16 +02:00
Nextcloud bot
c43a0a0f89 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-11-24 16:16:48 +00:00
3c7236f956 fix(l10n): unusable pluralization 2025-11-24 15:43:55 +02:00
Nextcloud bot
fcf40da4aa fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-11-24 12:54:52 +00:00
71efe00265 chore: fix isSystemRole func type assertion 2025-11-24 11:18:35 +02:00
843f81a087 fix(l10n): translation source string issues 2025-11-24 10:36:57 +02:00
Nextcloud bot
f0f06cef25 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-11-24 06:48:51 +00:00
248c875319 fix(AdminDashboard): improve contributors sorting 2025-11-23 23:25:21 +02:00
8b973c3ad5 feat(AdminRoleEdit): allow checking/unchecking multiple categories 2025-11-23 23:18:46 +02:00
f4530ae2a3 fix(Categories): admin should always see all categories 2025-11-23 23:18:04 +02:00
3ed74eea8f feat(Category Admin): refresh categories/headers in sidebar afer modifying 2025-11-23 23:00:03 +02:00
49ad2c9810 chore(master): release 0.10.1 2025-11-23 14:07:45 +02:00
09f6ea4a3b fix(Seed): don't seed admin category permission 2025-11-23 14:03:48 +02:00
e795ec2667 fix(Seed): improve seed idempotency 2025-11-23 13:55:35 +02:00
be51e8a1a5 chore(master): release 0.10.0 2025-11-23 02:11:43 +02:00
53875b1eef fix(AdminDashboard): exclude thread posts from post count 2025-11-23 02:08:03 +02:00
0f9d5ea9a5 fix: modal actions spacing 2025-11-23 02:07:30 +02:00
4708d8cf87 chore: exclude gen/ changes from php test trigger 2025-11-23 02:07:03 +02:00
20a15b42d9 chore(test): swap phpunit local/docker 2025-11-23 00:17:15 +02:00
7a1853935e chore: run php tests on commit 2025-11-22 23:48:42 +02:00
04ec7ffcf8 test: add/update role & permission tests 2025-11-22 23:47:53 +02:00
c9a76e5cd9 feat(Roles): admin always has full permissions 2025-11-22 23:37:05 +02:00
94787052ef refactor(Role): improve role logic in UI 2025-11-22 23:07:19 +02:00
e20bfdadab refactor(Roles): update UserRoleController & SetRole command to use UserRoleService 2025-11-22 23:05:02 +02:00
328b37be6e fix(Roles): prevent deleting system roles on backend 2025-11-22 23:03:58 +02:00
c7f84d4a18 fix(UserEventListener): add User role to newly created users 2025-11-22 23:03:33 +02:00
d09987600b chore(master): release 0.9.2 2025-11-22 22:03:04 +02:00
dcdcde31ed chore: allow blank issue templates 2025-11-22 21:53:14 +02:00
f66169288e build: reduce test workflow count 2025-11-22 21:50:27 +02:00
7a17dbc524 docs: update README.md 2025-11-22 21:44:09 +02:00
c1443014b5 build: update phpunit workflows 2025-11-22 21:44:02 +02:00
4c2e47d86b build: update phpunit workflows 2025-11-22 21:38:46 +02:00
8408402148 fix(l10n): plural tokens + text alignment strings 2025-11-22 21:18:58 +02:00
3d113f1f31 fix(l10n): update translation source strings 2025-11-22 20:59:43 +02:00
48b7679e3b chore: remove unused file 2025-11-22 20:58:36 +02:00
5f0317b153 build: update php test versions matrix 2025-11-22 03:39:45 +02:00
56dc0049b8 build: include all composer.lock files 2025-11-22 03:37:32 +02:00
7519088e2b build: update php test version matrix 2025-11-22 03:34:22 +02:00
0f3be447fa build: add phpunit-pgsql task 2025-11-22 03:33:02 +02:00
f73d902962 build: update phpunit workflow min php version 2025-11-22 03:29:08 +02:00
4a9ae9bfc6 build: update phpunit workflow min php version 2025-11-22 03:27:00 +02:00
37012590a1 build: update test workflow 2025-11-22 03:21:12 +02:00
00b80b817d build: include composer.lock 2025-11-22 03:20:56 +02:00
3472e95065 docs: update README.md badges 2025-11-22 03:15:11 +02:00
7fde88a158 build: add phpunit-mysql workflow 2025-11-22 02:49:44 +02:00
5ebeb56636 test: add missing tests 2025-11-22 02:29:36 +02:00
a66bcd4612 fix(PostController): exclude first posts from post_count fields 2025-11-22 02:29:14 +02:00
36d8ecd5bb test: fix failing tests 2025-11-22 02:01:31 +02:00
257a12dfc4 fix: post counts in threads/categories 2025-11-22 01:55:06 +02:00
b67813fa34 fix(SeedHelper): subscribe author to welcome thread 2025-11-22 01:39:05 +02:00
d6c6626bad fix(l10n): bbcode help dialog strings 2025-11-22 00:51:26 +02:00
9837fc4683 chore(master): release 0.9.1 2025-11-22 00:42:58 +02:00
a3b0582d2c fix(l10n): fix welcome post & bbcode example strings 2025-11-22 00:39:46 +02:00
53c50f5297 chore(master): release 0.9.0 2025-11-22 00:19:58 +02:00
4e867cdf0a fix(RepairSeeds): output logs 2025-11-22 00:17:17 +02:00
7c5bf4a82b feat: 404 pages 2025-11-22 00:13:34 +02:00
cf28213bac Revert "build: update Release Please user"
This reverts commit 6647378e29.
2025-11-22 00:02:07 +02:00
8ecddc032f fix(Notifications): test-notifier command 2025-11-21 23:58:36 +02:00
6647378e29 build: update Release Please user 2025-11-21 23:58:36 +02:00
0f71247cfa chore(master): release 0.8.2 2025-11-21 23:43:17 +02:00
83b7c3392e fix(l10n): update string with literal name 2025-11-21 23:36:55 +02:00
49c12011fa fix(l10n): update bbcode-including strings 2025-11-21 23:34:18 +02:00
d53724407b fix(l10n): Update pluralization strings 2025-11-21 23:23:02 +02:00
be51645ba4 docs: update README.md 2025-11-21 23:22:47 +02:00
f3b5fa3273 refactor: user, post and thread enrichment service instead of static methods 2025-11-21 22:55:15 +02:00
c46c96021e build(test): update local test makefile 2025-11-21 22:55:15 +02:00
caf05dae9d chore(test): improve local testing 2025-11-21 22:13:45 +02:00
e071f79300 chore(test): update phpunit.xml 2025-11-21 21:46:39 +02:00
b90ab6151f test: repair tests 2025-11-21 21:40:30 +02:00
e22bf1de83 docs: update store doc links 2025-11-21 21:40:16 +02:00
e0521cadd3 docs: update README.md 2025-11-21 20:39:49 +02:00
e2fd6383d3 fix(Seeds): update seed output & add repair command 2025-11-21 20:39:48 +02:00
d9cb3a6d9b fix(Seeds): log seed statuses in console 2025-11-21 20:39:47 +02:00
34fa0dbec1 chore: update bug report issue template 2025-11-21 19:35:21 +02:00
749c30c2f2 fix: initial seed 2025-11-21 19:31:03 +02:00
53c1b980a9 fix(AdminCategoryList): pluralization string 2025-11-21 19:31:03 +02:00
7c521bcbe4 docs: update README.md 2025-11-21 15:08:37 +02:00
Nextcloud bot
387be93d3a fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-11-21 08:31:30 +00:00
b2bf402e20 chore(master): release 0.8.1 2025-11-21 09:41:46 +02:00
c6d757bee6 fix: migration 2025-11-21 09:40:04 +02:00
35c0fa7e1d chore(master): release 0.8.0 2025-11-21 02:30:26 +02:00
b93c45adc7 feat(CategoryView): use fixed-width page 2025-11-21 02:23:29 +02:00
a3f77e23c5 chore(deps): update dependencies 2025-11-21 02:18:37 +02:00
461fd68c14 build: type check during build/dev 2025-11-21 02:14:14 +02:00
bc3892e9a2 feat(AdminDashboard): add recent contributors view 2025-11-21 02:09:08 +02:00
ba552a2c01 feat: rebuild-all-stats and rebuild-thread-stats commands 2025-11-21 01:57:11 +02:00
b38f7d31fa chore: update .l10nignore 2025-11-21 01:50:42 +02:00
7de5cc56ef fix(AdminUserList): edit role dialog select width 2025-11-21 01:50:14 +02:00
85f2b4c667 feat: unify action buttons ui/design 2025-11-21 01:23:09 +02:00
3af9c9ce68 fix: search results ui 2025-11-21 01:07:06 +02:00
88cb7f5aa9 feat: add role colors + improve user data structure/enrichment 2025-11-21 01:00:45 +02:00
90459368b1 fix: use l10n for db seeds 2025-11-20 21:11:41 +02:00
1ca534c90f docs: update screenshot url 2025-11-20 15:13:47 +02:00
8ba4efb92c chore(master): release 0.7.0 2025-11-20 14:24:48 +02:00
d6d4694ce0 fix: build excluded files 2025-11-20 14:22:04 +02:00
84edf8ecbe feat: weekly task now calculates category/thread post counts 2025-11-20 11:18:41 +02:00
96a42525d3 feat: add forum:set-role occ command 2025-11-20 11:07:03 +02:00
84fe339fc0 chore(master): release 0.6.0 2025-11-20 10:25:54 +02:00
ce6b334dd3 build: clean up asset loaders 2025-11-20 10:14:15 +02:00
92418cc543 build: improve asset chunk logic 2025-11-20 04:37:46 +02:00
2753ecfefb build: improve asset/script loading 2025-11-20 04:37:17 +02:00
53130ca10a chore: update scaffolds 2025-11-20 04:35:38 +02:00
e97302b861 build: fix build errors 2025-11-20 01:58:19 +02:00
c8ca4f9168 feat(AdminCategoryEdit): pre-populate role dropdowns with default roles 2025-11-20 01:52:05 +02:00
c16e804d16 fix(AdminUserList): empty state display condition 2025-11-20 01:46:57 +02:00
22f9b78b1b fix(AdminCategoryList): list spacing 2025-11-20 01:46:40 +02:00
432c31f6e2 feat(AdminTable): improve users/role tables design 2025-11-20 01:41:46 +02:00
46367aa0d8 docs: update screenshot 2025-11-19 23:40:57 +02:00
f4fe09fae3 chore(master): release 0.5.0 2025-11-19 20:36:07 +02:00
5c66f44da5 fix(AdminCategoryList): allow deleting empty categories/headers 2025-11-19 20:27:11 +02:00
363e04b4e9 feat(AdminCategoryEdit): auto-populate slug on create 2025-11-19 20:08:46 +02:00
1fd59c1f04 fix: improve admin role assignment to users 2025-11-19 19:43:25 +02:00
5391d8fffe chore(master): release 0.4.0 2025-11-19 09:32:37 +02:00
b0bfbbccdf feat(BBCodeEditor): add attachment disclaimer 2025-11-19 02:54:07 +02:00
9525ebfb97 fix(ThreadCard): mobile responsiveness 2025-11-19 02:54:07 +02:00
67e9fb9f8c fix(ProfileView): mobile responsiveness 2025-11-19 02:54:06 +02:00
a36da9f882 feat(AppNavigation): save collapse state to local storage 2025-11-19 02:54:06 +02:00
c0762158d7 fix: mobile responsiveness 2025-11-19 02:54:06 +02:00
479cdbbba5 refactor: clean up AppNavigation active logic 2025-11-19 02:54:05 +02:00
255a5cf53d feat(BBCodeToolbar): add emoji picker button 2025-11-19 02:54:05 +02:00
feeefa2926 feat(PostReactions): use Nextcloud emoji picker 2025-11-19 02:54:03 +02:00
f49561ccca chore(master): release 0.3.0 2025-11-18 10:31:32 +02:00
e59a6f4dc7 feat: add skeleton component + update categories header ui 2025-11-18 10:26:51 +02:00
9719f518e2 feat: load forum title/subtitle from public endpoint 2025-11-18 10:26:50 +02:00
2d10b461c0 feat: add page header component 2025-11-18 10:26:50 +02:00
2264289b56 refactor: move AppToolbar position to PageWrapper slot 2025-11-18 02:44:59 +02:00
3ef545dcc9 refactor: add PageWrapper component 2025-11-18 02:21:08 +02:00
fb905f8d15 docs: add release to README.md 2025-11-18 02:13:19 +02:00
278f1b3cc4 feat: user preferences page & auto thread subs pref 2025-11-18 01:38:57 +02:00
5ee8a16aa1 fix: user stats post is_first_post counts 2025-11-17 18:22:41 +02:00
a1671baf2d chore(master): release 0.2.1 2025-11-17 18:15:40 +02:00
71ee133ac6 fix: unread counts for deleted posts 2025-11-17 18:13:19 +02:00
1add8db287 fix: thread card hover styles 2025-11-17 17:52:34 +02:00
e1e3ede1d8 chore(master): release 0.2.0 2025-11-17 10:09:24 +02:00
9833e51997 fix: admin/mod post permissions 2025-11-17 10:01:42 +02:00
664ee53670 fix: user avatar container size 2025-11-17 09:45:40 +02:00
7a80c19613 chore: fix ts errors 2025-11-17 03:18:49 +02:00
8cc34d9d7a feat: update thread card user info display 2025-11-17 03:16:01 +02:00
364226fdc8 fix: create user stats for existing users 2025-11-17 03:10:09 +02:00
11aa3af887 feat: unify user info component 2025-11-17 03:05:55 +02:00
0de120f2bf feat: rebuild user stats task & command 2025-11-17 02:42:06 +02:00
e590f73fc0 fix: user stats table 2025-11-17 02:41:54 +02:00
4ca6388923 feat: add emoji picker close icon 2025-11-17 01:48:25 +02:00
cdecdce9d1 fix: emoji picker position 2025-11-17 01:44:53 +02:00
bf59b47b2a build: exclude openapi from precommit formatting 2025-11-17 01:32:49 +02:00
2fbe180d5e feat: thread subscriptions & notifications 2025-11-17 01:27:17 +02:00
d16288f237 fix: default support category sort order 2025-11-16 23:15:24 +02:00
6ba8034b75 fix: autoload 2025-11-16 16:35:45 +02:00
230 changed files with 20990 additions and 5394 deletions

View File

@@ -94,25 +94,125 @@ body:
description: Which browser are you using? (if applicable)
placeholder: e.g., Firefox 120, Chrome 119, Safari 17
- type: textarea
id: logs
- type: markdown
attributes:
label: Relevant Logs
value: |
## 📋 Debugging Information
The following information helps us investigate and fix issues quickly. Please provide as much detail as possible.
- type: textarea
id: migration-status
attributes:
label: Migration Status
description: |
Please paste any relevant logs from:
- Nextcloud log (Settings → Logging)
- Browser console (F12 → Console tab)
- PHP error logs
**How to check migration status:**
This shows which database migrations have been executed for the Forum app.
**For Docker installations:**
```bash
docker exec --user www-data -i nextcloud-aio-nextcloud php occ migrations:status forum
```
**For standard installations:**
```bash
php occ migrations:status forum
```
Or from the Nextcloud directory:
```bash
sudo -u www-data php occ migrations:status forum
```
**Note:** If you suspect data is missing (roles, categories, etc.), try running the repair command:
```bash
php occ forum:repair-seeds
```
See the [Administration section](https://github.com/chenasraf/nextcloud-forum#administration) in the README for more details.
placeholder: Paste the migration status output here...
render: shell
- type: textarea
id: nextcloud-logs
attributes:
label: Nextcloud Server Logs
description: |
**How to get server logs:**
Look for errors related to the Forum app (last 20-50 lines recommended).
**Via Web UI:**
- Go to Nextcloud Settings → Administration → Logging (or `/settings/admin/logging`)
- Look for entries containing "forum"
**For Docker installations:**
```bash
docker exec --user www-data -i nextcloud-aio-nextcloud tail -100 /var/www/html/data/nextcloud.log | grep -i forum
```
**For standard installations:**
```bash
tail -100 /path/to/nextcloud/data/nextcloud.log | grep -i forum
```
Or from the Nextcloud directory:
```bash
sudo -u www-data tail -100 data/nextcloud.log | grep -i forum
```
placeholder: Paste Nextcloud server logs here...
render: shell
- type: textarea
id: browser-console
attributes:
label: Browser Console Errors
description: |
**How to check browser console:**
1. Open the page where the issue occurs
2. Press **F12** (or right-click → Inspect → Console tab)
3. Look for red error messages
4. Copy any errors related to the Forum app
**Tip:** You can right-click on an error and select "Copy message" or "Copy stack trace"
placeholder: Paste browser console errors here...
render: javascript
- type: textarea
id: network-errors
attributes:
label: Network Request Errors
description: |
**How to check network requests:**
1. Open the page where the issue occurs
2. Press **F12** → Go to the **Network** tab
3. Reproduce the issue
4. Look for failed requests (shown in red or with 4xx/5xx status codes)
5. Click on the failed request
6. Copy the following information:
- **Request URL** (e.g., `/apps/forum/api/...`)
- **Status Code** (e.g., 500, 404, 403)
- **Response** tab content (the error message/data returned)
**Example format:**
```
Request: POST /apps/forum/api/threads
Status: 500 Internal Server Error
Response: {"error": "Database connection failed"}
```
placeholder: Paste network error details here...
render: shell
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem
description: |
If applicable, add screenshots to help explain your problem.
You can drag and drop images directly into this field.
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context about the problem here
description: Add any other context about the problem here (e.g., recent changes, specific configuration, workarounds attempted)

View File

@@ -1,4 +1,4 @@
blank_issues_enabled: false
blank_issues_enabled: true
contact_links:
- name: Nextcloud Community Forum
url: https://help.nextcloud.com

201
.github/workflows/phpunit-mysql.yml vendored Normal file
View File

@@ -0,0 +1,201 @@
# This workflow is provided via the organization template repository
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
#
# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: PHPUnit MySQL
on: pull_request
permissions:
contents: read
concurrency:
group: phpunit-mysql-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout app
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
- name: Get supported server versions
id: versions
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
- name: Build test matrix
id: set-matrix
run: |
# Get server branches from version matrix
BRANCHES='${{ steps.versions.outputs.branches }}'
# Build minimal matrix: min Nextcloud with PHP 8.2, max Nextcloud with PHP 8.3
MATRIX=$(jq -nc \
--argjson branches "$BRANCHES" \
'{include: [{"php-versions": "8.2", "mysql-versions": "8.4", "server-versions": $branches[0]}, {"php-versions": "8.3", "mysql-versions": "8.4", "server-versions": $branches[-1]}]}'
)
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
echo "Generated matrix: $MATRIX"
changes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
src: ${{ steps.changes.outputs.src}}
steps:
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
continue-on-error: true
with:
filters: |
src:
- '.github/workflows/**'
- 'appinfo/**'
- 'lib/**'
- 'templates/**'
- 'tests/**'
- 'vendor/**'
- 'vendor-bin/**'
- '.php-cs-fixer.dist.php'
- 'composer.json'
- 'composer.lock'
phpunit-mysql:
runs-on: ubuntu-latest
needs: [changes, matrix]
if: needs.changes.outputs.src != 'false'
strategy:
matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
name: MySQL ${{ matrix.mysql-versions }} PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
services:
mysql:
image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest
ports:
- 4444:3306/tcp
env:
MYSQL_ROOT_PASSWORD: rootpassword
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
steps:
- name: Checkout app
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
path: app-checkout
- name: Detect app ID from appinfo/info.xml
run: |
APP_ID=$(grep -oP '(?<=<id>)[^<]+' app-checkout/appinfo/info.xml | head -1)
echo "APP_NAME=$APP_ID" >> $GITHUB_ENV
echo "Detected app ID: $APP_ID"
- name: Checkout server
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
submodules: true
repository: nextcloud/server
ref: ${{ matrix.server-versions }}
- name: Checkout app
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@0f7f1d08e3e32076e51cae65eb0b0c871405b16e # v2.34.1
with:
php-version: ${{ matrix.php-versions }}
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, mysql, pdo_mysql
coverage: none
ini-file: development
# Temporary workaround for missing pcntl_* in PHP 8.3
ini-values: disable_functions=
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Enable ONLY_FULL_GROUP_BY MySQL option
run: |
echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
echo 'SELECT @@sql_mode;' | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
- name: Check composer file existence
id: check_composer
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
with:
files: apps/${{ env.APP_NAME }}/composer.json
- name: Set up dependencies
# Only run if phpunit config file exists
if: steps.check_composer.outputs.files_exists == 'true'
working-directory: apps/${{ env.APP_NAME }}
run: |
composer remove nextcloud/ocp --dev --no-scripts
composer i
- name: Set up Nextcloud
env:
DB_PORT: 4444
run: |
mkdir data
./occ maintenance:install --verbose --database=mysql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
./occ app:enable --force ${{ env.APP_NAME }}
- name: Check PHPUnit script is defined
id: check_phpunit
continue-on-error: true
working-directory: apps/${{ env.APP_NAME }}
run: |
composer run --list | grep '^ test:unit ' | wc -l | grep 1
- name: PHPUnit
# Only run if phpunit config file exists
if: steps.check_phpunit.outcome == 'success'
working-directory: apps/${{ env.APP_NAME }}
run: composer run test:unit
- name: Print logs
if: always()
run: |
cat data/nextcloud.log
- name: Skipped
# Fail the action when unit tests are not specified
if: steps.check_phpunit.outcome == 'failure'
run: |
echo 'PHPUnit tests are not specified in composer.json scripts'
exit 1
summary:
permissions:
contents: none
runs-on: ubuntu-latest
needs: [changes, phpunit-mysql]
if: always()
name: phpunit-mysql-summary
steps:
- name: Summary status
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-mysql.result != 'success' }}; then exit 1; fi

216
.github/workflows/phpunit-pgsql.yml vendored Normal file
View File

@@ -0,0 +1,216 @@
# This workflow is provided via the organization template repository
#
# https://github.com/nextcloud/.github
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
#
# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: PHPUnit PostgreSQL
on: pull_request
permissions:
contents: read
concurrency:
group: phpunit-pgsql-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout app
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
- name: Get supported server versions
id: versions
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
- name: Build test matrix
id: set-matrix
run: |
# Get server branches from version matrix
BRANCHES='${{ steps.versions.outputs.branches }}'
# Build minimal matrix: only latest Nextcloud with PHP 8.3
MATRIX=$(jq -nc \
--argjson branches "$BRANCHES" \
'{include: [{"php-versions": "8.3", "server-versions": $branches[-1]}]}'
)
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
echo "Generated matrix: $MATRIX"
changes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
src: ${{ steps.changes.outputs.src }}
steps:
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: changes
continue-on-error: true
with:
filters: |
src:
- '.github/workflows/**'
- 'appinfo/**'
- 'lib/**'
- 'templates/**'
- 'tests/**'
- 'vendor/**'
- 'vendor-bin/**'
- '.php-cs-fixer.dist.php'
- 'composer.json'
- 'composer.lock'
phpunit-pgsql:
runs-on: ubuntu-latest
needs: [changes, matrix]
if: needs.changes.outputs.src != 'false'
strategy:
matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
name: PostgreSQL PHP ${{ matrix.php-versions }} Nextcloud ${{ matrix.server-versions }}
services:
postgres:
image: ghcr.io/nextcloud/continuous-integration-postgres-16:latest # zizmor: ignore[unpinned-images]
ports:
- 4444:5432/tcp
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: rootpassword
POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
steps:
- name: Checkout app
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
path: app-checkout
- name: Detect app ID from appinfo/info.xml
run: |
APP_ID=$(grep -oP '(?<=<id>)[^<]+' app-checkout/appinfo/info.xml | head -1)
echo "APP_NAME=$APP_ID" >> $GITHUB_ENV
echo "Detected app ID: $APP_ID"
- name: Checkout server
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
submodules: true
repository: nextcloud/server
ref: ${{ matrix.server-versions }}
- name: Checkout app
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
persist-credentials: false
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2.35.5
with:
php-version: ${{ matrix.php-versions }}
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, pgsql, pdo_pgsql
coverage: none
ini-file: development
# Temporary workaround for missing pcntl_* in PHP 8.3
ini-values: disable_functions=
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check composer file existence
id: check_composer
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
with:
files: apps/${{ env.APP_NAME }}/composer.json
- name: Set up dependencies
# Only run if phpunit config file exists
if: steps.check_composer.outputs.files_exists == 'true'
working-directory: apps/${{ env.APP_NAME }}
run: |
composer remove nextcloud/ocp --dev --no-scripts
composer i
- name: Set up Nextcloud
env:
DB_PORT: 4444
run: |
mkdir data
./occ maintenance:install --verbose --database=pgsql --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
./occ app:enable --force ${{ env.APP_NAME }}
- name: Check PHPUnit script is defined
id: check_phpunit
continue-on-error: true
working-directory: apps/${{ env.APP_NAME }}
run: |
composer run --list | grep '^ test:unit ' | wc -l | grep 1
- name: PHPUnit
# Only run if phpunit config file exists
if: steps.check_phpunit.outcome == 'success'
working-directory: apps/${{ env.APP_NAME }}
run: composer run test:unit
- name: Check PHPUnit integration script is defined
id: check_integration
continue-on-error: true
working-directory: apps/${{ env.APP_NAME }}
run: |
composer run --list | grep '^ test:integration ' | wc -l | grep 1
- name: Run Nextcloud
# Only run if phpunit integration config file exists
if: steps.check_integration.outcome == 'success'
run: php -S localhost:8080 &
- name: PHPUnit integration
# Only run if phpunit integration config file exists
if: steps.check_integration.outcome == 'success'
working-directory: apps/${{ env.APP_NAME }}
run: composer run test:integration
- name: Print logs
if: always()
run: |
cat data/nextcloud.log
- name: Skipped
# Fail the action when neither unit nor integration tests ran
if: steps.check_phpunit.outcome == 'failure' && steps.check_integration.outcome == 'failure'
run: |
echo 'Neither PHPUnit nor PHPUnit integration tests are specified in composer.json scripts'
exit 1
summary:
permissions:
contents: none
runs-on: ubuntu-latest
needs: [changes, phpunit-pgsql]
if: always()
name: phpunit-pgsql-summary
steps:
- name: Summary status
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-pgsql.result != 'success' }}; then exit 1; fi

2
.gitignore vendored
View File

@@ -12,10 +12,10 @@
/js
/css
.DS_Store
composer.lock
build/
tsconfig.app.tsbuildinfo
.env
.env.keys
.envrc
tests/.phpunit.result.cache
stats.html

View File

@@ -1,2 +1,3 @@
dist/
vendor/
gen/

View File

@@ -1,6 +1,17 @@
module.exports = {
'*.{ts,vue}': ['eslint --fix'],
'*.{scss,vue,ts,md,json}': ['prettier --write'],
'*.php': [() => 'make php-cs-fixer'],
'*.{scss,vue,ts,md}': ['prettier --write'],
'*.json': (files) => {
const filtered = files.filter(file => !file.includes('openapi.json'))
return filtered.length > 0 ? `prettier --write ${filtered.join(' ')}` : []
},
'*.php': (files) => {
const nonGenFiles = files.filter(file => !file.includes('/gen/'))
const commands = []
if (nonGenFiles.length > 0) {
commands.push('make php-cs-fixer', 'make test')
}
return commands
},
'*Controller.php': [() => 'make openapi', () => 'git add openapi.json'],
}

View File

@@ -1 +1 @@
{".":"0.1.7"}
{".":"0.11.0"}

View File

@@ -1,5 +1,221 @@
# Changelog
## [0.11.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.10.1...v0.11.0) (2025-11-24)
### Features
* **AdminRoleEdit:** allow checking/unchecking multiple categories ([8b973c3](https://github.com/chenasraf/nextcloud-forum/commit/8b973c3ad5349bb91b4039b86edd4416f136fc7b))
* **Category Admin:** refresh categories/headers in sidebar afer modifying ([3ed74ee](https://github.com/chenasraf/nextcloud-forum/commit/3ed74eea8f85d062e8a95749d8b487ee42066c2f))
### Bug Fixes
* **AdminDashboard:** improve contributors sorting ([248c875](https://github.com/chenasraf/nextcloud-forum/commit/248c8753198b801c71ad94ede35d06b0bbd4aed1))
* **Categories:** admin should always see all categories ([f4530ae](https://github.com/chenasraf/nextcloud-forum/commit/f4530ae2a3c01ba2d1f36c3c9e32ead2502580d0))
* **l10n:** translation source string issues ([843f81a](https://github.com/chenasraf/nextcloud-forum/commit/843f81a08725b3109067b6f1f3ad2f538209ee26))
* **l10n:** unify same messages with different placeholders ([8476b77](https://github.com/chenasraf/nextcloud-forum/commit/8476b772e305c9893b4d796c0dc3e9df1151fe09))
* **l10n:** unusable pluralization ([3c7236f](https://github.com/chenasraf/nextcloud-forum/commit/3c7236f956736e5e249e72344ed2c973a6e65540))
* **l10n:** Update translations from Transifex ([c43a0a0](https://github.com/chenasraf/nextcloud-forum/commit/c43a0a0f893378eb430e94209396d51f7c7fd830))
* **l10n:** Update translations from Transifex ([fcf40da](https://github.com/chenasraf/nextcloud-forum/commit/fcf40da4aaed59d0a6d6ee58f039c73f4c5eba98))
* **l10n:** Update translations from Transifex ([f0f06ce](https://github.com/chenasraf/nextcloud-forum/commit/f0f06cef258fc658e935d3375bbe92d8000b6d33))
## [0.10.1](https://github.com/chenasraf/nextcloud-forum/compare/v0.10.0...v0.10.1) (2025-11-23)
### Bug Fixes
* **Seed:** don't seed admin category permission ([09f6ea4](https://github.com/chenasraf/nextcloud-forum/commit/09f6ea4a3b56bdf723f7b90a204a2450d1b4137e))
* **Seed:** improve seed idempotency ([e795ec2](https://github.com/chenasraf/nextcloud-forum/commit/e795ec266736f413c71ebd3f9f3c9081e86cf082))
## [0.10.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.9.2...v0.10.0) (2025-11-23)
### Features
* **Roles:** admin always has full permissions ([c9a76e5](https://github.com/chenasraf/nextcloud-forum/commit/c9a76e5cd97df0c82bb79825799eeba7ce66086e))
### Bug Fixes
* **AdminDashboard:** exclude thread posts from post count ([53875b1](https://github.com/chenasraf/nextcloud-forum/commit/53875b1eefaddcbe8c4024c98834e44c3a01aeb0))
* modal actions spacing ([0f9d5ea](https://github.com/chenasraf/nextcloud-forum/commit/0f9d5ea9a5a99dda9bb351ed98d91ae880ddf64f))
* **Roles:** prevent deleting system roles on backend ([328b37b](https://github.com/chenasraf/nextcloud-forum/commit/328b37be6eec2b0001517ef74779565457de7213))
* **UserEventListener:** add User role to newly created users ([c7f84d4](https://github.com/chenasraf/nextcloud-forum/commit/c7f84d4a186ab7832d5fa96c2143bef30ddf3a85))
## [0.9.2](https://github.com/chenasraf/nextcloud-forum/compare/v0.9.1...v0.9.2) (2025-11-22)
### Bug Fixes
* **l10n:** bbcode help dialog strings ([d6c6626](https://github.com/chenasraf/nextcloud-forum/commit/d6c6626badf90636aae4f59fbe4765a5f786f5ab))
* **l10n:** plural tokens + text alignment strings ([8408402](https://github.com/chenasraf/nextcloud-forum/commit/8408402148c9935b50df1f75915cffba7d76b043))
* **l10n:** update translation source strings ([3d113f1](https://github.com/chenasraf/nextcloud-forum/commit/3d113f1f31887b7849753d07712a548392f574d6))
* post counts in threads/categories ([257a12d](https://github.com/chenasraf/nextcloud-forum/commit/257a12dfc43d7784d7e63ab79a8545d80022251e))
* **PostController:** exclude first posts from post_count fields ([a66bcd4](https://github.com/chenasraf/nextcloud-forum/commit/a66bcd4612a1889624e608e9e0207d7e09fc32df))
* **SeedHelper:** subscribe author to welcome thread ([b67813f](https://github.com/chenasraf/nextcloud-forum/commit/b67813fa34746de8f999b16e609c6ee7a9458e9b))
## [0.9.1](https://github.com/chenasraf/nextcloud-forum/compare/v0.9.0...v0.9.1) (2025-11-21)
### Bug Fixes
* **l10n:** fix welcome post & bbcode example strings ([a3b0582](https://github.com/chenasraf/nextcloud-forum/commit/a3b0582d2cce2c22cd5070f3c335a732c25c5e67))
## [0.9.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.8.2...v0.9.0) (2025-11-21)
### Features
* 404 pages ([7c5bf4a](https://github.com/chenasraf/nextcloud-forum/commit/7c5bf4a82b88c3dc64604f73aa66b9742b0f2ee8))
### Bug Fixes
* **Notifications:** test-notifier command ([8ecddc0](https://github.com/chenasraf/nextcloud-forum/commit/8ecddc032f11eae72ba6a12447313d87b2d01570))
* **RepairSeeds:** output logs ([4e867cd](https://github.com/chenasraf/nextcloud-forum/commit/4e867cdf0a91c9d246b87cd2c829a37bbbeefd56))
## [0.8.2](https://github.com/chenasraf/nextcloud-forum/compare/v0.8.1...v0.8.2) (2025-11-21)
### Bug Fixes
* **AdminCategoryList:** pluralization string ([53c1b98](https://github.com/chenasraf/nextcloud-forum/commit/53c1b980a960cf9a27cee68b4da6d4560b426b9c))
* initial seed ([749c30c](https://github.com/chenasraf/nextcloud-forum/commit/749c30c2f276813e19dfa91a81bc12573429c784))
* **l10n:** update bbcode-including strings ([49c1201](https://github.com/chenasraf/nextcloud-forum/commit/49c12011fa4e5dd08f905b3d921f434b9adfc244))
* **l10n:** Update pluralization strings ([d537244](https://github.com/chenasraf/nextcloud-forum/commit/d53724407bd709993c6036b27fd17ced5c82d926))
* **l10n:** update string with literal name ([83b7c33](https://github.com/chenasraf/nextcloud-forum/commit/83b7c3392e8c328391430c3b1945a77ecc6b1a33))
* **l10n:** Update translations from Transifex ([387be93](https://github.com/chenasraf/nextcloud-forum/commit/387be93d3ad5c744fcaca7bb6073293431727e35))
* **Seeds:** log seed statuses in console ([d9cb3a6](https://github.com/chenasraf/nextcloud-forum/commit/d9cb3a6d9b715fe59f383323c3ab30424b25b430))
* **Seeds:** update seed output & add repair command ([e2fd638](https://github.com/chenasraf/nextcloud-forum/commit/e2fd6383d31609076981c38ccf9062a5d505cb19))
## [0.8.1](https://github.com/chenasraf/nextcloud-forum/compare/v0.8.0...v0.8.1) (2025-11-21)
### Bug Fixes
* migration ([c6d757b](https://github.com/chenasraf/nextcloud-forum/commit/c6d757bee606280061a3ba359d3137b95838f444))
## [0.8.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.7.0...v0.8.0) (2025-11-21)
### Features
* add role colors + improve user data structure/enrichment ([88cb7f5](https://github.com/chenasraf/nextcloud-forum/commit/88cb7f5aa946fae974344622e194f0ef23392913))
* **AdminDashboard:** add recent contributors view ([bc3892e](https://github.com/chenasraf/nextcloud-forum/commit/bc3892e9a2a2c47520973dfeaf810d2d32366a1c))
* **CategoryView:** use fixed-width page ([b93c45a](https://github.com/chenasraf/nextcloud-forum/commit/b93c45adc78377c7e9971446c8c03b749bc523fc))
* rebuild-all-stats and rebuild-thread-stats commands ([ba552a2](https://github.com/chenasraf/nextcloud-forum/commit/ba552a2c01783de7161b5b6d16fdd7c4081a8b28))
* unify action buttons ui/design ([85f2b4c](https://github.com/chenasraf/nextcloud-forum/commit/85f2b4c66794c7f6b622406954fd57cf88bba371))
### Bug Fixes
* **AdminUserList:** edit role dialog select width ([7de5cc5](https://github.com/chenasraf/nextcloud-forum/commit/7de5cc56efee39a892ca200da7f52a7727b8cd00))
* search results ui ([3af9c9c](https://github.com/chenasraf/nextcloud-forum/commit/3af9c9ce68bc7966b94d89fb6a32f163ad4aaadc))
* use l10n for db seeds ([9045936](https://github.com/chenasraf/nextcloud-forum/commit/90459368b1b6a4536ba75d139422019f0e836676))
## [0.7.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.6.0...v0.7.0) (2025-11-20)
### Features
* add forum:set-role occ command ([96a4252](https://github.com/chenasraf/nextcloud-forum/commit/96a42525d342ca0e791ea20b224838fc395f906c))
* weekly task now calculates category/thread post counts ([84edf8e](https://github.com/chenasraf/nextcloud-forum/commit/84edf8ecbe3512d948960948299d378fae4b2c91))
### Bug Fixes
* build excluded files ([d6d4694](https://github.com/chenasraf/nextcloud-forum/commit/d6d4694ce0cc64c0c220bb834bcec15ec107e343))
## [0.6.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.5.0...v0.6.0) (2025-11-20)
### Features
* **AdminCategoryEdit:** pre-populate role dropdowns with default roles ([c8ca4f9](https://github.com/chenasraf/nextcloud-forum/commit/c8ca4f9168d597d1f6281a9fab794052b6f9a33b))
* **AdminTable:** improve users/role tables design ([432c31f](https://github.com/chenasraf/nextcloud-forum/commit/432c31f6e2c71c1b18216f59a31e69d34223baff))
### Bug Fixes
* **AdminCategoryList:** list spacing ([22f9b78](https://github.com/chenasraf/nextcloud-forum/commit/22f9b78b1be0b9787a5d8ea0bf648630d086c7f6))
* **AdminUserList:** empty state display condition ([c16e804](https://github.com/chenasraf/nextcloud-forum/commit/c16e804d16480936f9f38903989e90aeecc4cd5b))
## [0.5.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.4.0...v0.5.0) (2025-11-19)
### Features
* **AdminCategoryEdit:** auto-populate slug on create ([363e04b](https://github.com/chenasraf/nextcloud-forum/commit/363e04b4e93f896648fa2d58d4d5718cc924236c))
### Bug Fixes
* **AdminCategoryList:** allow deleting empty categories/headers ([5c66f44](https://github.com/chenasraf/nextcloud-forum/commit/5c66f44da520fce0d35f384e13452f8cae1427ab))
* improve admin role assignment to users ([1fd59c1](https://github.com/chenasraf/nextcloud-forum/commit/1fd59c1f0462e02aa49703191365a9d564f5c8e9))
## [0.4.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.3.0...v0.4.0) (2025-11-19)
### Features
* **AppNavigation:** save collapse state to local storage ([a36da9f](https://github.com/chenasraf/nextcloud-forum/commit/a36da9f8822aa6b091e34d82cce8b56a86547b39))
* **BBCodeEditor:** add attachment disclaimer ([b0bfbbc](https://github.com/chenasraf/nextcloud-forum/commit/b0bfbbccdf04bd92d374ed31e404c9fadc23f51b))
* **BBCodeToolbar:** add emoji picker button ([255a5cf](https://github.com/chenasraf/nextcloud-forum/commit/255a5cf53dcce38c9356b30713a76e95592abe44))
* **PostReactions:** use Nextcloud emoji picker ([feeefa2](https://github.com/chenasraf/nextcloud-forum/commit/feeefa2926589cbd0c62053f1700c9bfb6bca545))
### Bug Fixes
* mobile responsiveness ([c076215](https://github.com/chenasraf/nextcloud-forum/commit/c0762158d75e6eebf0ac77a512218cf7b4119a97))
* **ProfileView:** mobile responsiveness ([67e9fb9](https://github.com/chenasraf/nextcloud-forum/commit/67e9fb9f8cdb9d1ada660b1d90e8de5aa35051de))
* **ThreadCard:** mobile responsiveness ([9525ebf](https://github.com/chenasraf/nextcloud-forum/commit/9525ebfb9705e66281898af7fcb733ba1ae8208c))
## [0.3.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.2.1...v0.3.0) (2025-11-18)
### Features
* add page header component ([2d10b46](https://github.com/chenasraf/nextcloud-forum/commit/2d10b461c018160d63ed6e63479e1488ba8da38e))
* add skeleton component + update categories header ui ([e59a6f4](https://github.com/chenasraf/nextcloud-forum/commit/e59a6f4dc7b60ad0b370b801d541f0007d1896c3))
* load forum title/subtitle from public endpoint ([9719f51](https://github.com/chenasraf/nextcloud-forum/commit/9719f518e2b1a9dced781431a6b0d4123aef952c))
* user preferences page & auto thread subs pref ([278f1b3](https://github.com/chenasraf/nextcloud-forum/commit/278f1b3cc48b6d2e74c383dec34015e3e3cd1e81))
### Bug Fixes
* user stats post is_first_post counts ([5ee8a16](https://github.com/chenasraf/nextcloud-forum/commit/5ee8a16aa13510c7b6a6b48238bc156c27045e7b))
## [0.2.1](https://github.com/chenasraf/nextcloud-forum/compare/v0.2.0...v0.2.1) (2025-11-17)
### Bug Fixes
* thread card hover styles ([1add8db](https://github.com/chenasraf/nextcloud-forum/commit/1add8db28775d2d13d8b2eb9428a90eb99b32ae8))
* unread counts for deleted posts ([71ee133](https://github.com/chenasraf/nextcloud-forum/commit/71ee133ac6b59f9005918594f7e668031b8224fa))
## [0.2.0](https://github.com/chenasraf/nextcloud-forum/compare/v0.1.7...v0.2.0) (2025-11-17)
### Features
* add emoji picker close icon ([4ca6388](https://github.com/chenasraf/nextcloud-forum/commit/4ca6388923299751a251f56785c2b29dc2dd75dd))
* rebuild user stats task & command ([0de120f](https://github.com/chenasraf/nextcloud-forum/commit/0de120f2bf88bd377aa13a760f29f1b46ece98e9))
* thread subscriptions & notifications ([2fbe180](https://github.com/chenasraf/nextcloud-forum/commit/2fbe180d5e8a6e6fdd02b3506896f9355d6bef22))
* unify user info component ([11aa3af](https://github.com/chenasraf/nextcloud-forum/commit/11aa3af887f17c3236ff8abcc8ef1d3b15ee03c2))
* update thread card user info display ([8cc34d9](https://github.com/chenasraf/nextcloud-forum/commit/8cc34d9d7a0711d43b938b9fd686a8ea682160cf))
### Bug Fixes
* admin/mod post permissions ([9833e51](https://github.com/chenasraf/nextcloud-forum/commit/9833e519973da5ff059ef0346333bdc96d73c072))
* autoload ([6ba8034](https://github.com/chenasraf/nextcloud-forum/commit/6ba8034b7535d1c449e8b75d5645398f948b7941))
* create user stats for existing users ([364226f](https://github.com/chenasraf/nextcloud-forum/commit/364226fdc84713162b1b59d3ec17455177a7ba81))
* default support category sort order ([d16288f](https://github.com/chenasraf/nextcloud-forum/commit/d16288f237e07ad7d3a5726029de39c7bee7b8da))
* emoji picker position ([cdecdce](https://github.com/chenasraf/nextcloud-forum/commit/cdecdce9d18828e227be0994b9ccf065eba9c831))
* user avatar container size ([664ee53](https://github.com/chenasraf/nextcloud-forum/commit/664ee536705bd2d8fab64470a2a2600ab30e3d26))
* user stats table ([e590f73](https://github.com/chenasraf/nextcloud-forum/commit/e590f73fc02f32c6d0f908e895441f4405240ec7))
## [0.1.7](https://github.com/chenasraf/nextcloud-forum/compare/v0.1.6...v0.1.7) (2025-11-16)

View File

@@ -42,6 +42,10 @@ composer_bin := $(if $(composer),$(composer),php $(composer_phar))
pnpm_wrapper=$(build_tools_directory)/pnpm.sh
pnpm_cmd=$(if $(pnpm),$(pnpm),$(pnpm_wrapper))
# Optional: Set path to Nextcloud installation for local testing
# Can be overridden by environment variable: NEXTCLOUD_ROOT=/path make test
NEXTCLOUD_ROOT ?=
# Default target: install deps & build JS (and PHP if composer.json exists)
all: build
@@ -188,7 +192,8 @@ appstore:
--exclude="bower.json" \
--exclude="karma.*" \
--exclude="protractor\.*" \
--exclude=".*" \
--exclude="/gen" \
--exclude="/.*" \
--exclude="dist/js/.*" \
--exclude="/src" \
--exclude="rename-template.sh" \
@@ -197,11 +202,38 @@ appstore:
tar czf $(appstore_package_name).tar.gz $(app_name)
# test:
# - Run PHP unit tests (standard + optional integration config)
# - Run PHP unit tests locally with a configured Nextcloud installation
# - Requires: A fully configured and installed Nextcloud instance with database
# - Auto-detects Nextcloud installation or uses NEXTCLOUD_ROOT (Makefile var or env var)
# - RECOMMENDED: Use 'make test-docker' instead (works in any environment)
.PHONY: test
test: composer
$(CURDIR)/vendor/phpunit/phpunit/phpunit -c tests/phpunit.xml
( test ! -f tests/phpunit.integration.xml ) || $(CURDIR)/vendor/phpunit/phpunit/phpunit -c tests/phpunit.integration.xml
@NC_ROOT="$(NEXTCLOUD_ROOT)"; \
if [ -n "$$NC_ROOT" ]; then \
NC_ROOT=$$(echo "$$NC_ROOT" | sed "s|^\\\~|$$HOME|" | sed "s|^~|$$HOME|"); \
fi; \
if [ -z "$$NC_ROOT" ]; then \
if [ -d "$(CURDIR)/../../../tests/bootstrap.php" ]; then \
NC_ROOT="$(CURDIR)/../../.."; \
fi; \
fi; \
if [ -z "$$NC_ROOT" ]; then \
echo "\x1b[33mCould not find Nextcloud installation.\x1b[0m"; \
echo ""; \
echo "Local testing requires a fully configured Nextcloud instance."; \
echo ""; \
echo "Options:"; \
echo " 1. Use Docker tests (recommended): \x1b[32mmake test-docker\x1b[0m"; \
echo " 2. Set NEXTCLOUD_ROOT in Makefile (line 47) or as env var:"; \
echo " \x1b[32mNEXTCLOUD_ROOT=/path/to/nextcloud make test\x1b[0m"; \
echo ""; \
exit 1; \
fi; \
echo "\x1b[32mUsing Nextcloud root: $$NC_ROOT\x1b[0m"; \
NEXTCLOUD_ROOT="$$NC_ROOT" $(CURDIR)/vendor/phpunit/phpunit/phpunit -c tests/phpunit.xml; \
if [ -f tests/phpunit.integration.xml ]; then \
NEXTCLOUD_ROOT="$$NC_ROOT" $(CURDIR)/vendor/phpunit/phpunit/phpunit -c tests/phpunit.integration.xml; \
fi
# test-docker:
# - Run PHP unit tests inside a Nextcloud Docker container
@@ -233,7 +265,7 @@ test-docker:
exit 1; \
fi; \
echo "\x1b[33mRunning tests in container $$CONTAINER_ID for app $$APP_DIR\x1b[0m"; \
docker exec $$CONTAINER_ID phpunit -c apps-shared/$$APP_DIR/tests/phpunit.xml
docker exec $$CONTAINER_ID phpunit -c apps-shared/$$APP_DIR/tests/phpunit.docker.xml
# lint:
# - Lint JS via pnpm and PHP via composer script "lint"

127
README.md
View File

@@ -5,6 +5,10 @@ SPDX-License-Identifier: CC0-1.0
# Nextcloud Forum
[![GitHub Release](https://img.shields.io/github/v/release/chenasraf/nextcloud-forum?color=blue)](https://github.com/chenasraf/nextcloud-forum/releases/latest)
[![PHPUnit MySQL](https://github.com/chenasraf/nextcloud-forum/actions/workflows/phpunit-mysql.yml/badge.svg)](https://github.com/chenasraf/nextcloud-forum/actions/workflows/phpunit-mysql.yml)
[![PHPUnit PostgreSQL](https://github.com/chenasraf/nextcloud-forum/actions/workflows/phpunit-pgsql.yml/badge.svg)](https://github.com/chenasraf/nextcloud-forum/actions/workflows/phpunit-pgsql.yml)
A full-featured forum application for Nextcloud, allowing users to create discussion categories,
threads, and posts within their Nextcloud instance.
@@ -14,8 +18,8 @@ threads, and posts within their Nextcloud instance.
**This app is in early stages of development.** While functional, you may encounter bugs or
incomplete features. Please report any issues on
[GitHub](https://github.com/chenasraf/nextcloud-forum/issues) and consider backing up your data
regularly.
[GitHub](https://github.com/chenasraf/nextcloud-forum/issues/new/choose) and consider backing up
your data regularly.
## Features
@@ -29,6 +33,11 @@ regularly.
- **Search**: Full-text search across threads and posts
- **Modern UI**: Built with Vue 3 and Nextcloud Vue components
## Documentation
For detailed usage instructions, administration guides, and more, visit the
[Forum Wiki](https://github.com/chenasraf/nextcloud-forum/wiki).
## Installation
### From the Nextcloud App Store
@@ -51,6 +60,16 @@ tar xfv forum-vX.X.X.tar.gz
php occ app:enable forum
```
## Administration
### OCC Commands
The Forum app provides several OCC commands for administration and maintenance, including commands
for repairing installations, rebuilding statistics, and managing user roles.
For a complete list of available commands, usage examples, and detailed documentation, see the
[OCC Commands Wiki page](https://github.com/chenasraf/nextcloud-forum/wiki/OCC-Commands).
## Contributing
I am developing this app on my free time, so any support, whether code, issues, or just stars is
@@ -86,55 +105,17 @@ Most development processes are automated:
While automation handles most workflows, the following commands are available for local development
and debugging:
#### Build the App
```bash
make
```
Installs dependencies and compiles frontend/backend assets.
#### Run Tests
```bash
make test
```
Runs unit and integration tests (if available).
#### Format & Lint
```bash
make format # Auto-fix code style
make lint # Check code quality
```
#### Generate OpenAPI Docs
```bash
make openapi
```
Output is saved to `build/openapi/openapi.json`.
#### Packaging for Release
```bash
make appstore # Production build for Nextcloud app store
make source # Full source package
make distclean # Clean build artifacts and dependencies
```
#### Sign Releases
After uploading the archive to GitHub:
```bash
make sign
```
Downloads the `.tar.gz` release, verifies it, and prints a SHA-512 signature using your key at
`~/.nextcloud/certificates/forum.key`.
| Command | Description | Notes |
| ---------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `make` | Installs dependencies and compiles frontend/backend assets | |
| `make test` | Runs unit and integration tests | |
| `make format` | Auto-fix code style | |
| `make lint` | Check code quality | |
| `make openapi` | Generate OpenAPI documentation | Output saved to `openapi.json` |
| `make appstore` | Production build for Nextcloud app store | |
| `make source` | Create full source package | |
| `make distclean` | Clean build artifacts and dependencies | |
| `make sign` | Sign release archive with SHA-512 signature | Run after uploading `.tar.gz` to GitHub. Uses `~/.nextcloud/certificates/forum.key` |
---
@@ -173,50 +154,6 @@ it for you. It also injects:
You dont pass a name for migrations.
#### Examples
Create a Vue component:
```bash
pnpm gen component UserListItem
# → src/components/UserListItem.vue
```
Create a Vue page:
```bash
pnpm gen view Settings
# → src/views/Settings.vue
```
Create an API controller:
```bash
pnpm gen api Users
# → lib/Controller/UsersController.php
```
Create a service:
```bash
pnpm gen service MyService
# → lib/Service/MyService.php
```
Create a queued job:
```bash
pnpm gen task-queued UpdateUsers
# → lib/Cron/UpdateUsers.php
```
Create a migration (no name):
```bash
pnpm gen migration
# → lib/Migration/Version{NEXT}.php (with injected {version} and {dt})
```
## Resources
### Nextcloud Development

11
appinfo/console.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
// SPDX-License-Identifier: AGPL-3.0-or-later
use OCA\Forum\Command\TestNotifier;
/** @var Symfony\Component\Console\Application $application */
$application->add(\OC::$server->get(TestNotifier::class));

View File

@@ -8,12 +8,12 @@
<name>Forum</name>
<summary>A community-driven forum built right into your Nextcloud instance</summary>
<description><![CDATA[
Create discussions, share ideas, and collaborate with your community directly in Nextcloud.
Create discussions, share ideas and collaborate with your community directly in Nextcloud.
**⚠️ Early Development Notice:**
This app is in early stages of development. While functional, you may encounter bugs or incomplete features. Please report any issues on GitHub and consider backing up your data regularly.
**Key Features:**
**Key features:**
- **Thread-based Discussions** - Create and reply to organized discussion threads
- **Category Organization** - Structure your forum with customizable categories and headers
- **Rich Text Formatting** - Use BBCode for formatting posts with bold, italic, links, images, code blocks and more
@@ -23,10 +23,10 @@ This app is in early stages of development. While functional, you may encounter
- **Search** - Find discussions quickly with built-in search
- **User Profiles** - View user post history and statistics
- **Role-Based Permissions** - Control access and moderation with flexible roles
- **Admin Tools** - Manage categories, roles, BBCodes, and forum settings
- **Moderation Tools** - Pin, lock, and manage threads and posts
- **Admin Tools** - Manage categories, roles, BBCodes and forum settings
- **Moderation Tools** - Pin, lock and manage threads and posts
**Perfect For:**
**Perfect for:**
- Team discussions and collaboration
- Community forums
- Support channels
@@ -36,25 +36,36 @@ This app is in early stages of development. While functional, you may encounter
The forum integrates seamlessly with your Nextcloud instance, using your existing users and groups for authentication and access control.
]]></description>
<version>0.1.7</version>
<version>0.11.0</version>
<licence>agpl</licence>
<author mail="contact@casraf.dev" homepage="https://casraf.dev">Chen Asraf</author>
<namespace>Forum</namespace>
<documentation>
<user>https://github.com/chenasraf/nextcloud-forum/blob/master/README.md</user>
<admin>https://github.com/chenasraf/nextcloud-forum#installation</admin>
<user>https://github.com/chenasraf/nextcloud-forum/wiki/Users</user>
<admin>https://github.com/chenasraf/nextcloud-forum/wiki/Administration</admin>
<developer>https://github.com/chenasraf/nextcloud-forum#development</developer>
</documentation>
<category>social</category>
<website>https://github.com/chenasraf/nextcloud-forum</website>
<bugs>https://github.com/chenasraf/nextcloud-forum/issues</bugs>
<repository>https://github.com/chenasraf/nextcloud-forum</repository>
<screenshot>https://raw.githubusercontent.com/chenasraf/nextcloud-forum/refs/heads/master/screenshots/screenshot-01.png</screenshot>
<screenshot>https://raw.githubusercontent.com/chenasraf/nextcloud-forum/master/screenshots/screenshot-01.png</screenshot>
<donation>https://ko-fi.com/casraf</donation>
<donation type="paypal"><![CDATA[https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TSH3C3ABGQM22&currency_code=ILS&source=url]]></donation>
<dependencies>
<nextcloud min-version="29" max-version="33"/>
</dependencies>
<background-jobs>
<job>OCA\Forum\Cron\RebuildStatsTask</job>
</background-jobs>
<commands>
<command>OCA\Forum\Command\RebuildAllStats</command>
<command>OCA\Forum\Command\RebuildThreadStats</command>
<command>OCA\Forum\Command\RebuildUserStats</command>
<command>OCA\Forum\Command\RepairSeeds</command>
<command>OCA\Forum\Command\SetRole</command>
<command>OCA\Forum\Command\TestNotifier</command>
</commands>
<navigations>
<navigation role="all">
<name>Forum</name>

3039
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
composer/autoload.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
// SPDX-FileCopyrightText: Chen Asraf <contact@casraf.dev>
// SPDX-License-Identifier: AGPL-3.0-or-later
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';

View File

@@ -24,7 +24,7 @@ class {{pascalCase name}} extends Command {
*/
protected function configure(): void {
parent::configure();
$this->setName('jukebox:{{kebabCase name}}');
$this->setName('forum:{{kebabCase name}}');
}
/**

View File

@@ -1,22 +1,19 @@
<template>
<div>{{ startCase name }}</div>
</template>
<script>
// import NcComponentExample from '@nextcloud/vue/dist/Components/NcComponentExample.js'
<script lang="ts">
import { defineComopnent, type PropType } from 'vue'
// import NcComponentExample from '@nextcloud/vue/components/NcComponentExample'
//
// import IconExample from 'vue-material-design-icons/Example.vue'
// import IconExample from '@icons/Example.vue'
export default {
export default defineComponent({
name: '{{pascalCase name}}',
components: {
//
},
}
})
</script>
<style scoped lang="scss"></style>

View File

@@ -1,24 +1,23 @@
<template>
<div class="jukebox-{{ kebabCase name }}">{{ startCase name }} Page</div>
<div class="forum-{{ kebabCase name }}">{{ startCase name }} Page</div>
</template>
<script>
<script lang="ts">
import { defineComopnent, type PropType } from 'vue'
// import NcComponentExample from '@nextcloud/vue/components/NcComponentExample'
//
// import IconExample from 'vue-material-design-icons/Example.vue'
// import IconExample from '@icons/Example.vue'
export default {
export default defineComponent({
name: '{{pascalCase name}}Page',
components: {
//
},
}
})
</script>
<style scoped lang="scss">
/*
#jukebox-{{ kebabCase name }} {
#forum-{{ kebabCase name }} {
/* Your styles here */
}
*/
</style>

6
l10n/hr.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;");

4
l10n/hr.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
}

6
l10n/hu.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "Azonosító"
},
"nplurals=2; plural=(n != 1);");

4
l10n/hu.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "Azonosító"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

6
l10n/id.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=1; plural=0;");

4
l10n/id.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=1; plural=0;"
}

6
l10n/is.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");

4
l10n/is.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
}

6
l10n/it.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");

4
l10n/it.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}

6
l10n/ja.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=1; plural=0;");

4
l10n/ja.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=1; plural=0;"
}

6
l10n/ka.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=2; plural=(n!=1);");

4
l10n/ka.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n!=1);"
}

6
l10n/ka_GE.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=2; plural=(n!=1);");

4
l10n/ka_GE.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n!=1);"
}

7
l10n/ko.js Normal file
View File

@@ -0,0 +1,7 @@
OC.L10N.register(
"forum",
{
"ID" : "ID",
"Loading users …" : "사용자 불러오는 중 ..."
},
"nplurals=1; plural=0;");

5
l10n/ko.json Normal file
View File

@@ -0,0 +1,5 @@
{ "translations": {
"ID" : "ID",
"Loading users …" : "사용자 불러오는 중 ..."
},"pluralForm" :"nplurals=1; plural=0;"
}

7
l10n/lo.js Normal file
View File

@@ -0,0 +1,7 @@
OC.L10N.register(
"forum",
{
"Tag" : "Tag",
"ID" : "ໄອດີ"
},
"nplurals=1; plural=0;");

5
l10n/lo.json Normal file
View File

@@ -0,0 +1,5 @@
{ "translations": {
"Tag" : "Tag",
"ID" : "ໄອດີ"
},"pluralForm" :"nplurals=1; plural=0;"
}

9
l10n/lt_LT.js Normal file
View File

@@ -0,0 +1,9 @@
OC.L10N.register(
"forum",
{
"Preferences" : "Nuostatos",
"Tag" : "Žymė",
"ID" : "ID",
"Loading users …" : "Įkeliami naudotojai…"
},
"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);");

7
l10n/lt_LT.json Normal file
View File

@@ -0,0 +1,7 @@
{ "translations": {
"Preferences" : "Nuostatos",
"Tag" : "Žymė",
"ID" : "ID",
"Loading users …" : "Įkeliami naudotojai…"
},"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"
}

7
l10n/lv.js Normal file
View File

@@ -0,0 +1,7 @@
OC.L10N.register(
"forum",
{
"Save" : "Saglabāt",
"Tag" : "Birkas"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);");

5
l10n/lv.json Normal file
View File

@@ -0,0 +1,5 @@
{ "translations": {
"Save" : "Saglabāt",
"Tag" : "Birkas"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
}

8
l10n/mk.js Normal file
View File

@@ -0,0 +1,8 @@
OC.L10N.register(
"forum",
{
"Preferences" : "Перформанси",
"ID" : "ID",
"Loading users …" : "Вчитување корисници ..."
},
"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;");

6
l10n/mk.json Normal file
View File

@@ -0,0 +1,6 @@
{ "translations": {
"Preferences" : "Перформанси",
"ID" : "ID",
"Loading users …" : "Вчитување корисници ..."
},"pluralForm" :"nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;"
}

6
l10n/mn.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"ID" : "ID"
},
"nplurals=2; plural=(n != 1);");

4
l10n/mn.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

8
l10n/nb.js Normal file
View File

@@ -0,0 +1,8 @@
OC.L10N.register(
"forum",
{
"Preferences" : "Innstillinger",
"ID" : "ID",
"Loading users …" : "Laster brukere..."
},
"nplurals=2; plural=(n != 1);");

6
l10n/nb.json Normal file
View File

@@ -0,0 +1,6 @@
{ "translations": {
"Preferences" : "Innstillinger",
"ID" : "ID",
"Loading users …" : "Laster brukere..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

11
l10n/nl.js Normal file
View File

@@ -0,0 +1,11 @@
OC.L10N.register(
"forum",
{
"Save" : "Opslaan",
"Preferences" : "Voorkeuren",
"Tag" : "Label",
"Move down" : "Lager zetten",
"ID" : "ID",
"Loading users …" : "Laden gebruikers ..."
},
"nplurals=2; plural=(n != 1);");

9
l10n/nl.json Normal file
View File

@@ -0,0 +1,9 @@
{ "translations": {
"Save" : "Opslaan",
"Preferences" : "Voorkeuren",
"Tag" : "Label",
"Move down" : "Lager zetten",
"ID" : "ID",
"Loading users …" : "Laden gebruikers ..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

7
l10n/nn_NO.js Normal file
View File

@@ -0,0 +1,7 @@
OC.L10N.register(
"forum",
{
"Save" : "Lagre",
"ID" : "ID"
},
"nplurals=2; plural=(n != 1);");

5
l10n/nn_NO.json Normal file
View File

@@ -0,0 +1,5 @@
{ "translations": {
"Save" : "Lagre",
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

7
l10n/oc.js Normal file
View File

@@ -0,0 +1,7 @@
OC.L10N.register(
"forum",
{
"Save" : "Enregistrar",
"ID" : "ID"
},
"nplurals=2; plural=(n > 1);");

5
l10n/oc.json Normal file
View File

@@ -0,0 +1,5 @@
{ "translations": {
"Save" : "Enregistrar",
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}

11
l10n/pl.js Normal file
View File

@@ -0,0 +1,11 @@
OC.L10N.register(
"forum",
{
"Save" : "Zapisz",
"Preferences" : "Preferencje",
"Tag" : "Etykieta",
"Move down" : "Przenieś niżej",
"ID" : "ID",
"Loading users …" : "Wczytywanie użytkowników ..."
},
"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");

9
l10n/pl.json Normal file
View File

@@ -0,0 +1,9 @@
{ "translations": {
"Save" : "Zapisz",
"Preferences" : "Preferencje",
"Tag" : "Etykieta",
"Move down" : "Przenieś niżej",
"ID" : "ID",
"Loading users …" : "Wczytywanie użytkowników ..."
},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
}

6
l10n/ps.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"Save" : "ساتل"
},
"nplurals=2; plural=(n != 1);");

4
l10n/ps.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"Save" : "ساتل"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

13
l10n/pt_BR.js Normal file
View File

@@ -0,0 +1,13 @@
OC.L10N.register(
"forum",
{
"Save" : "Salvar",
"React with {emoji}" : "Reagir com {emoji}",
"Preferences" : "Preferências",
"This action cannot be undone." : "Esta ação não pode ser desfeita.",
"Tag" : "Etiqueta",
"Move down" : "Mover para baixo",
"ID" : "ID",
"Loading users …" : "Carregando usuários …"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");

11
l10n/pt_BR.json Normal file
View File

@@ -0,0 +1,11 @@
{ "translations": {
"Save" : "Salvar",
"React with {emoji}" : "Reagir com {emoji}",
"Preferences" : "Preferências",
"This action cannot be undone." : "Esta ação não pode ser desfeita.",
"Tag" : "Etiqueta",
"Move down" : "Mover para baixo",
"ID" : "ID",
"Loading users …" : "Carregando usuários …"
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}

10
l10n/pt_PT.js Normal file
View File

@@ -0,0 +1,10 @@
OC.L10N.register(
"forum",
{
"Save" : "Guardar",
"Preferences" : "Preferências",
"Tag" : "Etiqueta",
"Move down" : "Mover para baixo",
"ID" : "Id."
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;");

8
l10n/pt_PT.json Normal file
View File

@@ -0,0 +1,8 @@
{ "translations": {
"Save" : "Guardar",
"Preferences" : "Preferências",
"Tag" : "Etiqueta",
"Move down" : "Mover para baixo",
"ID" : "Id."
},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
}

10
l10n/ro.js Normal file
View File

@@ -0,0 +1,10 @@
OC.L10N.register(
"forum",
{
"Save" : "Salvează",
"React with {emoji}" : "Reacționează cu {emoji}",
"Preferences" : "Preferințe",
"Move down" : "Mută în jos",
"ID" : "ID"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));");

8
l10n/ro.json Normal file
View File

@@ -0,0 +1,8 @@
{ "translations": {
"Save" : "Salvează",
"React with {emoji}" : "Reacționează cu {emoji}",
"Preferences" : "Preferințe",
"Move down" : "Mută în jos",
"ID" : "ID"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
}

14
l10n/ru.js Normal file
View File

@@ -0,0 +1,14 @@
OC.L10N.register(
"forum",
{
"Unread" : "Непрочитанное",
"Save" : "Сохранить",
"React with {emoji}" : "Отреагируйте с {emoji}",
"Preferences" : "Свойства",
"Tag" : "Метка",
"Move down" : "Переместить ниже",
"ID" : "ID",
"Loading users …" : "Загрузка пользователей…",
"Deleted" : "Удалено"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);");

12
l10n/ru.json Normal file
View File

@@ -0,0 +1,12 @@
{ "translations": {
"Unread" : "Непрочитанное",
"Save" : "Сохранить",
"React with {emoji}" : "Отреагируйте с {emoji}",
"Preferences" : "Свойства",
"Tag" : "Метка",
"Move down" : "Переместить ниже",
"ID" : "ID",
"Loading users …" : "Загрузка пользователей…",
"Deleted" : "Удалено"
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
}

9
l10n/sc.js Normal file
View File

@@ -0,0 +1,9 @@
OC.L10N.register(
"forum",
{
"Save" : "Sarva",
"Preferences" : "Preferèntzias",
"Move down" : "Tràmuda fache a bàsciu",
"ID" : "ID"
},
"nplurals=2; plural=(n != 1);");

7
l10n/sc.json Normal file
View File

@@ -0,0 +1,7 @@
{ "translations": {
"Save" : "Sarva",
"Preferences" : "Preferèntzias",
"Move down" : "Tràmuda fache a bàsciu",
"ID" : "ID"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

12
l10n/sk.js Normal file
View File

@@ -0,0 +1,12 @@
OC.L10N.register(
"forum",
{
"Save" : "Uložiť",
"React with {emoji}" : "Reagovať s {emoji}",
"Preferences" : "Nastavenia",
"Tag" : "Štítok",
"Move down" : "Presunúť dole",
"ID" : "ID",
"Loading users …" : "Načítavanie užívateľov ..."
},
"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);");

10
l10n/sk.json Normal file
View File

@@ -0,0 +1,10 @@
{ "translations": {
"Save" : "Uložiť",
"React with {emoji}" : "Reagovať s {emoji}",
"Preferences" : "Nastavenia",
"Tag" : "Štítok",
"Move down" : "Presunúť dole",
"ID" : "ID",
"Loading users …" : "Načítavanie užívateľov ..."
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
}

14
l10n/sl.js Normal file
View File

@@ -0,0 +1,14 @@
OC.L10N.register(
"forum",
{
"Unread" : "Neprebrano",
"Save" : "Shrani",
"React with {emoji}" : "Odzovi se z {emoji}",
"Preferences" : "Nastavitve",
"Tag" : "Oznaka",
"Move down" : "Premakni navzdol",
"ID" : "ID",
"Loading users …" : "Poteka nalaganje uporabnikov ...",
"Deleted" : "Izbrisano"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);");

12
l10n/sl.json Normal file
View File

@@ -0,0 +1,12 @@
{ "translations": {
"Unread" : "Neprebrano",
"Save" : "Shrani",
"React with {emoji}" : "Odzovi se z {emoji}",
"Preferences" : "Nastavitve",
"Tag" : "Oznaka",
"Move down" : "Premakni navzdol",
"ID" : "ID",
"Loading users …" : "Poteka nalaganje uporabnikov ...",
"Deleted" : "Izbrisano"
},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
}

9
l10n/sq.js Normal file
View File

@@ -0,0 +1,9 @@
OC.L10N.register(
"forum",
{
"Save" : "Ruaje",
"Preferences" : "Preferencat",
"ID" : "ID",
"Deleted" : "E fshirë"
},
"nplurals=2; plural=(n != 1);");

7
l10n/sq.json Normal file
View File

@@ -0,0 +1,7 @@
{ "translations": {
"Save" : "Ruaje",
"Preferences" : "Preferencat",
"ID" : "ID",
"Deleted" : "E fshirë"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

15
l10n/sr.js Normal file
View File

@@ -0,0 +1,15 @@
OC.L10N.register(
"forum",
{
"Unread" : "Непрочитано",
"Save" : "Сачувај",
"React with {emoji}" : "Реагуј са {emoji}",
"Preferences" : "Поставке",
"This action cannot be undone." : "Ова радња не може да се поништи.",
"Tag" : "Ознака",
"Move down" : "Помери надоле",
"ID" : "ID",
"Loading users …" : "Учитавају се корисници...",
"Deleted" : "Обрисано"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");

13
l10n/sr.json Normal file
View File

@@ -0,0 +1,13 @@
{ "translations": {
"Unread" : "Непрочитано",
"Save" : "Сачувај",
"React with {emoji}" : "Реагуј са {emoji}",
"Preferences" : "Поставке",
"This action cannot be undone." : "Ова радња не може да се поништи.",
"Tag" : "Ознака",
"Move down" : "Помери надоле",
"ID" : "ID",
"Loading users …" : "Учитавају се корисници...",
"Deleted" : "Обрисано"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
}

8
l10n/sr@latin.js Normal file
View File

@@ -0,0 +1,8 @@
OC.L10N.register(
"forum",
{
"Save" : "Sačuvaj",
"Preferences" : "Postavke",
"Deleted" : "Obrisano"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");

6
l10n/sr@latin.json Normal file
View File

@@ -0,0 +1,6 @@
{ "translations": {
"Save" : "Sačuvaj",
"Preferences" : "Postavke",
"Deleted" : "Obrisano"
},"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
}

14
l10n/sv.js Normal file
View File

@@ -0,0 +1,14 @@
OC.L10N.register(
"forum",
{
"Unread" : "Oläst",
"Save" : "Spara",
"React with {emoji}" : "Reagera med {emoji}",
"Preferences" : "Inställningar",
"Tag" : "Tagg",
"Move down" : "Flytta ner",
"ID" : "ID",
"Loading users …" : "Laddar användare …",
"Deleted" : "Borttagen"
},
"nplurals=2; plural=(n != 1);");

12
l10n/sv.json Normal file
View File

@@ -0,0 +1,12 @@
{ "translations": {
"Unread" : "Oläst",
"Save" : "Spara",
"React with {emoji}" : "Reagera med {emoji}",
"Preferences" : "Inställningar",
"Tag" : "Tagg",
"Move down" : "Flytta ner",
"ID" : "ID",
"Loading users …" : "Laddar användare …",
"Deleted" : "Borttagen"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

13
l10n/sw.js Normal file
View File

@@ -0,0 +1,13 @@
OC.L10N.register(
"forum",
{
"Unread" : "Haijasomwa",
"Save" : "Hifadhi",
"React with {emoji}" : "Jibu kwa {emoji}",
"Preferences" : "Vitu vya upendeleo",
"This action cannot be undone." : "Kitendo hiki hakiwezi kutenduliwa.",
"Move down" : "Hamia chini",
"ID" : "Kitambulisho",
"Deleted" : "Vilivyofutwa"
},
"nplurals=2; plural=(n != 1);");

11
l10n/sw.json Normal file
View File

@@ -0,0 +1,11 @@
{ "translations": {
"Unread" : "Haijasomwa",
"Save" : "Hifadhi",
"React with {emoji}" : "Jibu kwa {emoji}",
"Preferences" : "Vitu vya upendeleo",
"This action cannot be undone." : "Kitendo hiki hakiwezi kutenduliwa.",
"Move down" : "Hamia chini",
"ID" : "Kitambulisho",
"Deleted" : "Vilivyofutwa"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

6
l10n/ta.js Normal file
View File

@@ -0,0 +1,6 @@
OC.L10N.register(
"forum",
{
"Save" : "சேமிக்க "
},
"nplurals=2; plural=(n != 1);");

4
l10n/ta.json Normal file
View File

@@ -0,0 +1,4 @@
{ "translations": {
"Save" : "சேமிக்க "
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

9
l10n/th.js Normal file
View File

@@ -0,0 +1,9 @@
OC.L10N.register(
"forum",
{
"Save" : "บันทึก",
"Preferences" : "การกำหนดลักษณะ",
"ID" : "ID",
"Deleted" : "ลบแล้ว"
},
"nplurals=1; plural=0;");

7
l10n/th.json Normal file
View File

@@ -0,0 +1,7 @@
{ "translations": {
"Save" : "บันทึก",
"Preferences" : "การกำหนดลักษณะ",
"ID" : "ID",
"Deleted" : "ลบแล้ว"
},"pluralForm" :"nplurals=1; plural=0;"
}

8
l10n/tk.js Normal file
View File

@@ -0,0 +1,8 @@
OC.L10N.register(
"forum",
{
"Save" : "Saklamak",
"Preferences" : "Saýlamalar",
"Deleted" : "Öçürildi"
},
"nplurals=2; plural=(n != 1);");

6
l10n/tk.json Normal file
View File

@@ -0,0 +1,6 @@
{ "translations": {
"Save" : "Saklamak",
"Preferences" : "Saýlamalar",
"Deleted" : "Öçürildi"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

16
l10n/tr.js Normal file
View File

@@ -0,0 +1,16 @@
OC.L10N.register(
"forum",
{
"Unread" : "Okunmamış",
"Save" : "Kaydet",
"React with {emoji}" : "{emoji} ile tepki ver",
"Preferences" : "Tercihler",
"This action cannot be undone." : "Bu işlem geri alınamaz.",
"Tag" : "Etiket",
"Move down" : "Aşağı taşı",
"Failed to save settings" : "Ayarlar kaydedilemedi",
"ID" : "Kimlik",
"Loading users …" : "Kullanıcılar yükleniyor…",
"Deleted" : "Silinmiş"
},
"nplurals=2; plural=(n > 1);");

14
l10n/tr.json Normal file
View File

@@ -0,0 +1,14 @@
{ "translations": {
"Unread" : "Okunmamış",
"Save" : "Kaydet",
"React with {emoji}" : "{emoji} ile tepki ver",
"Preferences" : "Tercihler",
"This action cannot be undone." : "Bu işlem geri alınamaz.",
"Tag" : "Etiket",
"Move down" : "Aşağı taşı",
"Failed to save settings" : "Ayarlar kaydedilemedi",
"ID" : "Kimlik",
"Loading users …" : "Kullanıcılar yükleniyor…",
"Deleted" : "Silinmiş"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}

16
l10n/ug.js Normal file
View File

@@ -0,0 +1,16 @@
OC.L10N.register(
"forum",
{
"Unread" : "ئوقۇمىغان",
"Save" : "ساقلاش",
"React with {emoji}" : "{emoji} with بىلەن ئىنكاس قايتۇرۇڭ",
"Preferences" : "مايىللىق",
"Tag" : "خەتكۈچ",
"Move down" : "تۆۋەنگە يۆتكەڭ",
"Failed to save settings" : "تەڭشەكلەرنى ساقلىيالمىدى",
"Reset" : "ئەسلىگە قايتۇرۇش",
"ID" : "كىملىك",
"Loading users …" : "ئىشلەتكۈچىلەر يۈكلەۋاتىدۇ…",
"Deleted" : "ئۆچۈرۈلدى"
},
"nplurals=2; plural=(n != 1);");

14
l10n/ug.json Normal file
View File

@@ -0,0 +1,14 @@
{ "translations": {
"Unread" : "ئوقۇمىغان",
"Save" : "ساقلاش",
"React with {emoji}" : "{emoji} with بىلەن ئىنكاس قايتۇرۇڭ",
"Preferences" : "مايىللىق",
"Tag" : "خەتكۈچ",
"Move down" : "تۆۋەنگە يۆتكەڭ",
"Failed to save settings" : "تەڭشەكلەرنى ساقلىيالمىدى",
"Reset" : "ئەسلىگە قايتۇرۇش",
"ID" : "كىملىك",
"Loading users …" : "ئىشلەتكۈچىلەر يۈكلەۋاتىدۇ…",
"Deleted" : "ئۆچۈرۈلدى"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

17
l10n/uk.js Normal file
View File

@@ -0,0 +1,17 @@
OC.L10N.register(
"forum",
{
"Unread" : "Непрочитане",
"Save" : "Зберегти",
"React with {emoji}" : "Відреагувати з {emoji}",
"Preferences" : "Налаштування",
"This action cannot be undone." : "Цю дію не можна скасувати.",
"Tag" : "Тег",
"Move down" : "Пересунути вниз",
"Failed to save settings" : "Неможливо зберегти налаштування",
"Reset" : "Відхилити зміни",
"ID" : "ID",
"Loading users …" : "Завантаження користувачів ...",
"Deleted" : "Вилучено"
},
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);");

15
l10n/uk.json Normal file
View File

@@ -0,0 +1,15 @@
{ "translations": {
"Unread" : "Непрочитане",
"Save" : "Зберегти",
"React with {emoji}" : "Відреагувати з {emoji}",
"Preferences" : "Налаштування",
"This action cannot be undone." : "Цю дію не можна скасувати.",
"Tag" : "Тег",
"Move down" : "Пересунути вниз",
"Failed to save settings" : "Неможливо зберегти налаштування",
"Reset" : "Відхилити зміни",
"ID" : "ID",
"Loading users …" : "Завантаження користувачів ...",
"Deleted" : "Вилучено"
},"pluralForm" :"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
}

8
l10n/ur_PK.js Normal file
View File

@@ -0,0 +1,8 @@
OC.L10N.register(
"forum",
{
"Save" : "حفظ",
"Reset" : "ری سیٹ",
"Deleted" : "حذف شدہ "
},
"nplurals=2; plural=(n != 1);");

6
l10n/ur_PK.json Normal file
View File

@@ -0,0 +1,6 @@
{ "translations": {
"Save" : "حفظ",
"Reset" : "ری سیٹ",
"Deleted" : "حذف شدہ "
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

10
l10n/uz.js Normal file
View File

@@ -0,0 +1,10 @@
OC.L10N.register(
"forum",
{
"Save" : "Saqlash",
"Preferences" : "Afzalliklar",
"Failed to save settings" : "Sozlamalarni saqlab bo'lmadi",
"Reset" : "Qayta tiklash",
"Deleted" : "O`chirilgan"
},
"nplurals=1; plural=0;");

8
l10n/uz.json Normal file
View File

@@ -0,0 +1,8 @@
{ "translations": {
"Save" : "Saqlash",
"Preferences" : "Afzalliklar",
"Failed to save settings" : "Sozlamalarni saqlab bo'lmadi",
"Reset" : "Qayta tiklash",
"Deleted" : "O`chirilgan"
},"pluralForm" :"nplurals=1; plural=0;"
}

13
l10n/vi.js Normal file
View File

@@ -0,0 +1,13 @@
OC.L10N.register(
"forum",
{
"Save" : "Lưu",
"Preferences" : "Cài đặt",
"Move down" : "Di chuyển xuống",
"Failed to save settings" : "Lưu cấu hình thất bại",
"Reset" : "Đặt lại",
"ID" : "ID",
"Loading users …" : "Đang tải người dùng…",
"Deleted" : "Đã xoá"
},
"nplurals=1; plural=0;");

11
l10n/vi.json Normal file
View File

@@ -0,0 +1,11 @@
{ "translations": {
"Save" : "Lưu",
"Preferences" : "Cài đặt",
"Move down" : "Di chuyển xuống",
"Failed to save settings" : "Lưu cấu hình thất bại",
"Reset" : "Đặt lại",
"ID" : "ID",
"Loading users …" : "Đang tải người dùng…",
"Deleted" : "Đã xoá"
},"pluralForm" :"nplurals=1; plural=0;"
}

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