Skip to content

Fix compatibility with Nextcloud 33#259

Open
stephancordes wants to merge 41 commits intonextcloud:mainfrom
stephancordes:main
Open

Fix compatibility with Nextcloud 33#259
stephancordes wants to merge 41 commits intonextcloud:mainfrom
stephancordes:main

Conversation

@stephancordes
Copy link
Copy Markdown

Changes

  • Updated appinfo/info.xml max-version to 33
  • Updated @nextcloud/* dependencies in package.json
  • Migrated file actions to registerFileAction() API (NC 28+)
  • Migrated new file menu to addNewFileMenuEntry() API (NC 28+)

Tested on

  • Nextcloud 33
  • Rocky Linux / Plesk
  • PHP 8.5

Fixes #191

Cloude Code did most of the work

@AndyScherzinger
Copy link
Copy Markdown
Member

#243

Should address the 33 compatibility issues already and @miaulalala also did a v34 compatibility PR already.

Is his PR still needed @stephancordes? Also seems to be Claude gone nuts in terms of commits 😕

@AndyScherzinger AndyScherzinger added bug Something isn't working enhancement New feature or request labels Apr 11, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Files MindMap Nextcloud app for compatibility up to Nextcloud 33 by aligning frontend build/configuration, adding MIME/extension handling, and refreshing localization strings used by the newer file actions / new-file menu integrations.

Changes:

  • Adjust Vite build configuration and add generated public bundle output.
  • Add/extend file-type handling metadata (KM extension + Nextcloud mimetype mapping).
  • Update server-side save behavior and refresh many i18n strings (including new “Saved as …”/conversion prompts).

Reviewed changes

Copilot reviewed 213 out of 219 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vite.config.ts Tweaks Vite build behavior (preserve output dir, raise chunk warning limit) and removes Vue dedupe config.
src/plugins/km.js Adds extensions: ['km'] metadata for KM plugin.
src/tests/plugins/freemind.spec.js Removes legacy global setup from FreeMind plugin tests.
package.json Bumps app package version and updates Nextcloud-related JS dependencies.
lib/Controller/PublicFileHandlingController.php Adjusts public-share save conflict check to only run when mtime is non-empty.
lib/Controller/FileHandlingController.php Normalizes load path joining and adjusts save conflict check to only run when mtime is non-empty; removes path leakage in generic error response.
l10n/zh_TW.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/zh_TW.js Updates strings (new “Saved as …”/conversion prompts).
l10n/zh_HK.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/zh_HK.js Updates strings (new “Saved as …”/conversion prompts).
l10n/zh_CN.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/zh_CN.js Updates strings (new “Saved as …”/conversion prompts).
l10n/vi.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/vi.js Updates strings (new “Saved as …”/conversion prompts).
l10n/uz.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/uz.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ur_PK.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ur_PK.js Updates strings (new “Saved as …”/conversion prompts).
l10n/uk.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/uk.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ug.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ug.js Updates strings (new “Saved as …”/conversion prompts).
l10n/tr.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/tr.js Updates strings (new “Saved as …”/conversion prompts).
l10n/tk.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/tk.js Updates strings (new “Saved as …”/conversion prompts).
l10n/th.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/th.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ta.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ta.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sw.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sw.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sv.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sv.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sr@latin.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sr@latin.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sr.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sr.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sq.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sq.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sl.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sl.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sk.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sk.js Updates strings (new “Saved as …”/conversion prompts).
l10n/sc.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/sc.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ru.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ru.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ro.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ro.js Updates strings (new “Saved as …”/conversion prompts).
l10n/pt_PT.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/pt_PT.js Updates strings (new “Saved as …”/conversion prompts).
l10n/pt_BR.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/pt_BR.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ps.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ps.js Updates strings (new “Saved as …”/conversion prompts).
l10n/pl.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/pl.js Updates strings (new “Saved as …”/conversion prompts).
l10n/oc.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/oc.js Updates strings (new “Saved as …”/conversion prompts).
l10n/nn_NO.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/nn_NO.js Updates strings (new “Saved as …”/conversion prompts).
l10n/nl.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/nl.js Updates strings (new “Saved as …”/conversion prompts).
l10n/nb.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/nb.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ms_MY.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ms_MY.js Updates strings (new “Saved as …”/conversion prompts).
l10n/mn.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/mn.js Updates strings (new “Saved as …”/conversion prompts).
l10n/mk.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/mk.js Updates strings (new “Saved as …”/conversion prompts).
l10n/lv.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/lv.js Updates strings (new “Saved as …”/conversion prompts).
l10n/lt_LT.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/lt_LT.js Updates strings (new “Saved as …”/conversion prompts).
l10n/lo.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/lo.js Updates strings (new “Saved as …”/conversion prompts).
l10n/lb.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/lb.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ko.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ko.js Updates strings (new “Saved as …”/conversion prompts).
l10n/kn.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/kn.js Updates strings (new “Saved as …”/conversion prompts).
l10n/km.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/km.js Updates strings (new “Saved as …”/conversion prompts).
l10n/kab.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/kab.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ka.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ka.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ka_GE.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ka_GE.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ja.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ja.js Updates strings (new “Saved as …”/conversion prompts).
l10n/it.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/it.js Updates strings (new “Saved as …”/conversion prompts).
l10n/is.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/is.js Updates strings (new “Saved as …”/conversion prompts).
l10n/id.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/id.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ia.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ia.js Updates strings (new “Saved as …”/conversion prompts).
l10n/hy.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/hy.js Updates strings (new “Saved as …”/conversion prompts).
l10n/hu.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/hu.js Updates strings (new “Saved as …”/conversion prompts).
l10n/hr.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/hr.js Updates strings (new “Saved as …”/conversion prompts).
l10n/he.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/he.js Updates strings (new “Saved as …”/conversion prompts).
l10n/gl.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/gl.js Updates strings (new “Saved as …”/conversion prompts).
l10n/gd.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/gd.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ga.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ga.js Updates strings (new “Saved as …”/conversion prompts).
l10n/fr.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/fr.js Updates strings (new “Saved as …”/conversion prompts).
l10n/fi.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/fi.js Updates strings (new “Saved as …”/conversion prompts).
l10n/fa.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/fa.js Updates strings (new “Saved as …”/conversion prompts).
l10n/eu.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/eu.js Updates strings (new “Saved as …”/conversion prompts).
l10n/et_EE.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/et_EE.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_UY.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_UY.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_SV.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_SV.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_PY.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_PY.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_PR.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_PR.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_PE.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_PE.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_PA.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_PA.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_NI.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_NI.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_MX.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_MX.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_HN.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_HN.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_GT.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_GT.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_EC.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_EC.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_DO.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_DO.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_CR.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_CR.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_CO.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_CO.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_CL.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_CL.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_AR.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_AR.js Updates strings (new “Saved as …”/conversion prompts).
l10n/es_419.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/es_419.js Updates strings (new “Saved as …”/conversion prompts).
l10n/eo.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/eo.js Updates strings (new “Saved as …”/conversion prompts).
l10n/en_GB.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/en_GB.js Updates strings (new “Saved as …”/conversion prompts).
l10n/el.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/el.js Updates strings (new “Saved as …”/conversion prompts).
l10n/de.js Updates strings (new “Saved as …”/conversion prompts).
l10n/de_DE.js Updates strings (new “Saved as …”/conversion prompts).
l10n/da.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/da.js Updates strings (new “Saved as …”/conversion prompts).
l10n/cy_GB.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/cy_GB.js Updates strings (new “Saved as …”/conversion prompts).
l10n/cs.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/cs.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ca.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ca.js Updates strings (new “Saved as …”/conversion prompts).
l10n/bs.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/bs.js Updates strings (new “Saved as …”/conversion prompts).
l10n/br.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/br.js Updates strings (new “Saved as …”/conversion prompts).
l10n/bn_BD.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/bn_BD.js Updates strings (new “Saved as …”/conversion prompts).
l10n/bg.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/bg.js Updates strings (new “Saved as …”/conversion prompts).
l10n/be.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/be.js Updates strings (new “Saved as …”/conversion prompts).
l10n/az.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/az.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ast.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ast.js Updates strings (new “Saved as …”/conversion prompts).
l10n/ar.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/ar.js Updates strings (new “Saved as …”/conversion prompts).
l10n/af.json Updates strings (new “Saved as …”/conversion prompts) and normalizes JSON formatting.
l10n/af.js Updates strings (new “Saved as …”/conversion prompts).
js/files_mindmap-public.mjs Adds/updates built JS bundle for public-view handling.
appinfo/mimetypemapping.json Adds extension→mimetype mapping for .km files.
appinfo/info.xml Bumps app version metadata.
.gitignore Stops ignoring js/ and adds .claude/.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

stephancordes pushed a commit to stephancordes/files_mindmap that referenced this pull request Apr 11, 2026
Previously, an empty/missing mtime bypassed the optimistic-lock check
entirely (Copilot review on nextcloud#259), allowing clients to silently overwrite
concurrent changes. Now both FileHandlingController and
PublicFileHandlingController reject save requests without mtime with
HTTP 400 before the conflict check runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AndyScherzinger
Copy link
Copy Markdown
Member

In the end @stephancordes you'll have to do a rebase to get rid of the merge conflict, see https://github.com/nextcloud/files_mindmap/pull/259/conflicts for the dependencies. Can be done at any time of course

@AndyScherzinger
Copy link
Copy Markdown
Member

AndyScherzinger commented Apr 11, 2026

Also please add the sign-off, see https://github.com/nextcloud/files_mindmap/pull/259/checks?check_run_id=70903816397 or add it as a comment in the PR description.


To add your Signed-off-by line to every commit in this branch:

  1. Ensure you have a local copy of your branch by checking out the pull request locally via command line.
  2. In your local branch, run: git rebase HEAD~39 --signoff
  3. Force push your changes to overwrite the branch: git push --force-with-lease origin main

Thanks in advance ❤️

stephancordes and others added 19 commits April 11, 2026 11:44
…e build config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…ities

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…n type

- Import addNewFileMenuEntry from @nextcloud/files (v4) alongside legacy
- registerNewFileMenuPlugin() now uses the v4 API for version >= 33 so the
  "New mind map" entry appears in the Files new-file menu on NC 33+
- Change DefaultType.HIDDEN to DefaultType.DEFAULT so clicking a .km file
  triggers the file action and opens the viewer
- Rebuild JS bundles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…de()

- setFile() now reads file.path ?? file.filename so NC 28+ Viewer's Node
  objects are handled correctly (path was always undefined → wrong dir)
- Replace OCA.FilesMindMap.hide() calls in viewer.js with optional chaining
  so load failures no longer crash when hide() is not defined

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…back for new files

- freemind.js: replace bare FilesMindMap.Util.xml2json() (ReferenceError in
  ES module scope) with imported util.xml2json()
- mindmap.js load(): when server returns unsupported mime (e.g. octet-stream
  for a freshly created empty .km file), fall back to extension-based mime
  detection against registered plugins

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…te global mock

- mindmap.spec.js: add two setFile tests for NC 28+ Node objects (path
  instead of filename) and one load() test for octet-stream mime fallback
- freemind.spec.js: remove the global.FilesMindMap = { Util: util } workaround
  now that freemind.js imports util directly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
- save(): guard against null plugin when mime is unknown (TypeError crash)
- load(): extend extension fallback to use plugin.extensions array
- freemind.js: add extensions: ['mm'] for octet-stream fallback matching
- Application.php: register .mm -> application/x-freemind mime type
- registerNewFileMenuPlugin: separate translatable name from .km extension
  so translated filenames always get the correct extension appended
- l10n: rename 'New mind map.km' key to 'New mind map' in 50 translation
  files and strip accidental .km suffixes from translated values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
$message = $path accidentally replaced the l10n error string with the
raw file path, hiding the real error from the user on unexpected
exceptions during save.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Nextcloud apps are deployed by copying files directly — no build step
on the server. Keeping the bundles in git ensures the deployed code
always matches the source and prevents stale-bundle issues like the
ones fixed in this branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…NC 33

- Fix mtime conflict check to skip when mtime is empty (prevented saving)
- Fix new file source URL encoding to preserve .km extension
- Set _file.mime immediately in setFile() from Viewer Node object
- Add extensions: ['km'] to km plugin for explicit extension fallback
- Remove dedupe: ['vue'] from vite config to fix Vue 2/3 build conflict
- Add appinfo/mimetypemapping.json for belt-and-suspenders MIME hint
- Rebuild JS bundles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
- Construct WebDAV URL via generateRemoteUrl instead of context.encodedSource
  to reliably preserve .km extension regardless of NC files context object
- Add console.debug to log PUT URL for debugging
- Add Ctrl+S keydown handler in MindMap.vue (parent frame) so browser
  does not intercept the shortcut when focus is outside the iframe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
- viewer.php: minder-editor-container top: 0 → 40px so menu bar is visible
- viewer.js: Ctrl+S uses capture-phase listener to intercept before KityMinder
- mindmap.js: .mm files are saved as new .km via WebDAV PUT instead of failing
- FileHandlingController: rtrim() prevents double-slash in load path (fixes
  "file not found" immediately after new file creation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
stephancordes and others added 20 commits April 11, 2026 11:44
… menu z-index

- setFile(): decodeURIComponent() on file.path/basename so %20 is not
  double-encoded when building API URLs via generateUrl()
- viewer.js: auto-convert .mm to .km on open (trigger save immediately
  after load when supportedWrite is false but file is writable)
- viewer.php: give #menu-header z-index:1000 + white background + explicit
  height so it stays visible above KityMinder editor elements

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…-convert works

Removing data.writeable = false when encode === null — it was incorrectly
marking .mm files as read-only, hiding the autosave div and preventing the
auto-convert-to-.km code from triggering. writeable now reflects actual
server-side file permissions; supportedWrite reflects format capability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…uble-encoding

- setFile(): prefer backwards-compat file.filename (human-readable, not
  URL-encoded) that NC 33 Viewer provides, fall back to decodeURIComponent(file.path)
  for NC 28+ Node-only objects. Wraps decodeURIComponent in try-catch so a
  malformed URI never crashes the open flow.
- save(): update _file.fullName when converting .mm → .km so the new path
  is consistent for downstream use.
- viewer.js: after successful .mm → .km auto-convert, re-open the Viewer with
  the new .km path so NC's title bar shows the correct filename.
- tests: update priority expectation (filename > path) and add new tests for
  URL-encoded path decoding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
- Use Overwrite: F on the initial WebDAV PUT so an existing .km file is
  never silently overwritten.
- On HTTP 412 (file exists) show a confirm() dialog asking the user
  whether to overwrite '{name}.km' with the content from '{name}.mm'.
  Cancelling shows a 'Conversion cancelled' message and stops the flow.
- Replace the generic 'File Saved' message with a descriptive toast
  (8 s) and save-button label so users know exactly where their data went:
  '"{name}" was created — your changes are saved there. The original
  .mm file is unchanged.'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…sion

When the initial Overwrite:F PUT returns 412:
- confirm() asks the user whether to overwrite.
- "No": HEAD-probe baseName (1).km, (2).km, … to find the first free
  slot, then prompt() pre-filled with that suggestion (without extension)
  so the user can accept or change the name.
- Empty/cancel prompt → 'Conversion cancelled'.
- The alternative-name PUT also uses Overwrite:F; a second 412 shows
  an error so the user can pick yet another name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…slate all 96 languages

- exec(): decodeURIComponent(node.path) before OCA.Viewer.openWith() — fixes %20
  preventing files with spaces in their name from opening (node.path from
  @nextcloud/files v4 is URL-encoded; Viewer can't find the file otherwise)
- registerNewFileMenuPlugin(): same decode for newly created file's path
- save() .mm→.km branch: replace Overwrite:F + 412 approach with HEAD-request
  before PUT — NC does not reliably return 412 for PUT on existing files, so
  the confirm dialog never appeared and files were silently overwritten
- saveAsAlternative(): HEAD-check the user-chosen alternative name too
- l10n: add 6 new translation strings (Saved as, was created, already exists ×2,
  enter filename, conversion cancelled) to all 96 .js and .json language files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
… for new files

- viewer.js: add _saveInProgress flag to save() — blocks the autosave timer and
  manual triggers from starting a second save while a confirm/prompt dialog is
  open or an async PUT is in flight; prevents double dialogs and double PUTs
- viewer.js: remove OCA.Viewer.openWith() call after .mm→.km conversion — the
  re-open wrote to browser history (viewer reopened on F5) and if NC couldn't
  resolve the new .km path in its file list it re-opened the .mm, triggering
  a second auto-convert cycle with all its dialogs
- mindmap.js: pass displayname:fileName to File constructor so the file list
  shows the decoded human-readable name immediately (not %20) without an F5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
- fix: delay openWith() by 500 ms after creating a new file so Vue's
  reactive fileList update completes before the Viewer component
  mounts and calls setFile(); without the delay the Viewer found no
  matching file in its list and failed silently until F5

- feat: collapsible toolbar header (▲/▼ toggle button on the right)
  hides AutoSave/Save/Export controls and gives the mind-map canvas
  the freed space; auto-collapsed on first visit on narrow screens
  (≤ 600 px); state persisted in localStorage; 0.15 s CSS transition

- bump version 0.0.40 → 0.0.41

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…nd-open crash

- MindMap.vue: hide .modal-header on mount (restore on destroy) so iframe
  fills full viewport; iframe CSS changed to height:100vh / margin-top:0
- templates/viewer.php: add ✕ close button (always visible); collapsed
  toolbar height raised to 32px
- src/viewer.js: wire #close-button click to MindMap.close()
- src/mindmap.js: null guard in setFile() prevents TypeError crash when
  Viewer passes undefined on second open attempt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…irefox dy fix

- MindMap.vue: inject <style> tag with !important instead of direct .style.display;
  hides both .modal-header and .modal-container__close (the absolute-positioned
  NC Viewer close button outside the title bar). Fixes double-X on desktop and
  modal header still showing in Firefox mobile.
- src/mindmap.js: replace window.confirm() with a custom <dialog> for the
  .mm→.km overwrite question, offering 3 labelled buttons: Overwrite /
  Choose different name / Cancel. l10n strings added to de + de_DE.
- src/viewer.js: patch SVGTextElement.prototype.setAttribute in Firefox to
  drop `dy` writes; kity's getBBox()-based dy calculation produces wrong
  offsets in Firefox (logical vs. ink bounds), dy=0 is correct there.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Translates the three new dialog button strings introduced in 0.0.43
into all existing language files (.json + .js).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…ommented out

Toggle button, collapsed-state CSS, and localStorage init script are all
commented out in templates/viewer.php — not deleted, so they can be
re-enabled later. Close button (✕) remains as the sole right-side control.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
…Observer

Three-layer strategy to reliably hide .modal-header and .modal-container__close:
1. CSS <style> tag (fast; covers pointer-events:none)
2. el.style.setProperty('display','none','important') — inline !important beats
   Vue-scoped selectors like .modal-header[data-v-xxxxx] that have higher
   specificity (0,2,0) than our stylesheet rule (0,1,0) when both use !important
3. MutationObserver re-applies layer 2 whenever NC Vue re-renders those elements

Fixes: NC '...' floating over Exportieren dropdown; toolbar buttons unreachable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
#header-controls had overflow:hidden which clipped the dropdown opening
downward. Changed to overflow:visible and added z-index:2000 on
.dropdown-menu to ensure it appears above the KityMinder canvas.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
OCA.FilesMindMap.hide() was never defined — the optional call hide?.()
from the iframe silently returned undefined. The new method clicks
.modal-container__close programmatically; the button is display:none
!important but still in the DOM, and element.click() bypasses CSS
visibility to fire the Vue handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
Previously, an empty/missing mtime bypassed the optimistic-lock check
entirely (Copilot review on nextcloud#259), allowing clients to silently overwrite
concurrent changes. Now both FileHandlingController and
PublicFileHandlingController reject save requests without mtime with
HTTP 400 before the conflict check runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: stephancordes <stephan@cordes.site>
stephancordes added 2 commits April 11, 2026 11:47
Signed-off-by: stephancordes <stephan@cordes.site>
Signed-off-by: stephancordes <stephan@cordes.site>
@stephancordes
Copy link
Copy Markdown
Author

The PR should now show no conflicts:

  • appinfo/info.xml — merged cleanly (our 0.0.47 + upstream's updated author)
  • package-lock.json — regenerated cleanly
  • appstore-build-publish.yml — removed (not needed in fork)

@AndyScherzinger
Copy link
Copy Markdown
Member

appstore-build-publish.yml — removed (not needed in fork)

@stephancordes Yeah well, when opening a PR you are deleting it upstream... so no, you can't delete it claude ;)

package-lock.json — regenerated cleanly

It has a huge amount of changes which I would not expect but I am not an expert on it, so @miaulalala might know better

appinfo/info.xml — merged cleanly (our 0.0.47 + upstream's updated author)

Should actually stick to 0.0.34 simply due to the fact that 0.0.33 has been the last release, so there is no need to constantly bump the version number in the meta data due to changes since the bump would happen at release time

@stephancordes
Copy link
Copy Markdown
Author

@AndyScherzinger
what kind of changes are needed on my sied? (This is my first Git repository. It was originally intended to be private only. But it would have been a shame not to share the work.)

@AndyScherzinger
Copy link
Copy Markdown
Member

@stephancordes See
https://github.com/nextcloud/files_mindmap/actions/runs/24281838946/job/70914143016?pr=259#step:6:41
https://github.com/nextcloud/files_mindmap/actions/runs/24281838953/job/70914151975?pr=259#step:6:40

npm error npm cican only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file withnpm install before continuing.

So currently not all checks can be executed. So this would need to get fixed first. After that we can have a look and get it merged later. for a first, new release we would leave this out, to keep changes at a minimum, in case we need to search for issues with that minimal release it is easier if the change set is smaller.

Could you cover the above and add it to your branch? Thanks in adavance

@miaulalala
Copy link
Copy Markdown
Collaborator

Additionally, all l10n files can go - they are maintained via transifex.

@stephancordes
Copy link
Copy Markdown
Author

Yes, i will do both tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NC 28 compatibility

4 participants