Repository navigation
Conversation
|
No actionable comments were generated in the recent review.
|
There was a problem hiding this comment.
Actionable comments posted: 3

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
4a27f9b2-33f4-4906-abfc-96a59d019522
Files ignored due to path filters: 1-
package-lock.jsonis excluded by!**/package-lock.json
Files selected for processing: 7-
l10n/de.jsl10n/de.jsonl10n/de_DE.jsl10n/de_DE.jsonpackage.jsonsrc/components/AppControls/AppControls.vuesrc/components/RecipeView/RecipeView.vue
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
-
| const renderedText = (selector: string) => | ||
| Array.from(document.querySelectorAll<HTMLElement>(selector)) | ||
| .map((element) => element.innerText.trim()) | ||
| .filter(Boolean); |
There was a problem hiding this comment.
🔎 Supported by static analysis
-
Script executed:
rg -n 'normalizeMarkdown|Loading|exportRecipeAsPdf|renderedText' src/components/RecipeView/RecipeView.vue sed -n '720,800p' src/components/RecipeView/RecipeView.vue
Repository: nextcloud/cookbook
Length of output: 4395
Script executed:
set -o pipefail printf '%s\n' '--- template and export trigger references ---' rg -n -F -e 'exportRecipePdf' -e 'parsedDescription' -e 'parsedIngredients' -e 'parsedInstructions' -e 'parsedTools' -e 'isLoading' src/components/RecipeView/RecipeView.vue printf '%s\n' '--- template start ---' sed -n '1,180p' src/components/RecipeView/RecipeView.vue printf '%s\n' '--- watcher and export lifecycle ---' sed -n '900,995p' src/components/RecipeView/RecipeView.vue sed -n '1010,1080p' src/components/RecipeView/RecipeView.vue
Repository: nextcloud/cookbook
Length of output: 15298
Script executed:
set -o pipefail printf '%s\n' '--- setup and loading transitions ---' sed -n '560,675p' src/components/RecipeView/RecipeView.vue printf '%s\n' '--- export event emitters and controls ---' rg -n -F --glob '*.vue' --glob '*.ts' --glob '*.js' -e 'exportRecipePdf' -e 'Export as PDF' -e 'PDF' src printf '%s\n' '--- nearby control component usage ---' sed -n '180,380p' src/components/RecipeView/RecipeView.vue
Repository: nextcloud/cookbook
Length of output: 14477
Script executed:
set -o pipefail printf '%s\n' '--- AppControls export control ---' sed -n '130,190p' src/components/AppControls/AppControls.vue sed -n '300,340p' src/components/AppControls/AppControls.vue printf '%s\n' '--- AppControls setup and parent usage ---' sed -n '1,130p' src/components/AppControls/AppControls.vue rg -n -F --glob '*.vue' --glob '*.ts' -e '<AppControls' -e 'loadingRecipe' -e 'setLoadingRecipe' -e 'setRecipe' src
Repository: nextcloud/cookbook
Length of output: 12019
Script executed:
set -o pipefail printf '%s\n' '--- normalizeMarkdown binding ---' rg -n -F --glob '*.ts' --glob '*.js' --glob '*.vue' -e 'function normalizeMarkdown' -e 'const normalizeMarkdown' -e 'export default normalizeMarkdown' -e 'title-rename' . printf '%s\n' '--- export content selectors ---' sed -n '835,915p' src/components/RecipeView/RecipeView.vue printf '%s\n' '--- rendered child components ---' rg -n -F -e 'class="ingredient"' -e 'class="instruction"' -e 'class="markdown-tool"' src/components
Repository: nextcloud/cookbook
Length of output: 3401
Script executed:
set -o pipefail printf '%s\n' '--- candidate title-rename files ---' rg --files -g '*title*rename*' -g '*rename*' src apps . 2>/dev/null | head -80 printf '%s\n' '--- alias configuration and module references ---' rg -n -F --glob '*.{js,ts,json,vue}' -e 'title-rename' -e 'cookbook/js' webpack.config.js vite.config.* package.json tsconfig.json src 2>/dev/null || true
Repository: nextcloud/cookbook
Length of output: 3344
Script executed:
set -o pipefail sed -n '1,220p' src/js/title-rename.js
Repository: nextcloud/cookbook
Length of output: 2514
Wait for recipe text before exporting it.
For recipe text containing #r/<id> links, normalizeMarkdown waits for recipe API requests. The export action is already enabled when the recipe view is active. If the user exports before those requests finish, exportRecipeAsPdf reads Loading… from the rendered elements and saves the placeholder text while reporting success. Keep the export action unavailable until normalization finishes, or export the resolved recipe values directly.
| if (nutrition.length) { | ||
| addSection(t('cookbook', 'Nutrition Information')); | ||
| for (const item of nutrition) { | ||
| addText(item.replace(/\s+/g, ': ')); |
There was a problem hiding this comment.
🔎 Supported by static analysis
-
Script executed:
sed -n '850,875p' src/components/RecipeView/RecipeView.vue cat src/components/RecipeView/RecipeNutritionInfoItem.vueRepository: nextcloud/cookbook
Length of output: 1762
Script executed:
nl -ba src/components/RecipeView/RecipeView.vue | sed -n '180,280p;850,875p' printf '\n--- RecipeNutritionInfoItem.vue ---\n' nl -ba src/components/RecipeView/RecipeNutritionInfoItem.vue printf '\n--- nutrition component usages ---\n' rg -n -F -- 'RecipeNutritionInfoItem' src/components/RecipeView
Repository: nextcloud/cookbook
Length of output: 8632
Preserve spaces inside nutrition values.
Each .nutrition-items > li contains a title <div> and a data <div>. For Energy and 100 kcal, innerText yields Energy\n100 kcal. Replacing every whitespace run produces Energy: 100: kcal. Replace only the title/data line break.
Suggested fix
-
--- "a/src/components/RecipeView/RecipeView.vue" +++ "b/src/components/RecipeView/RecipeView.vue" @@ -863,7 +863,7 @@ if (nutrition.length) { addSection(t('cookbook', 'Nutrition Information')); for (const item of nutrition) { - addText(item.replace(/\s+/g, ': ')); + addText(item.replace(/\s*\n\s*/g, ': ')); } }
Committable suggestion
-
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.Suggested changeaddText(item.replace(/\s+/g, ': ')); addText(item.replace(/\s*\n\s*/g, ': '));
| .filter((element) => { | ||
| const child = element.firstElementChild; | ||
| return !( | ||
| element.children.length === 1 && | ||
| child && | ||
| /^H[1-6]$/.test(child.tagName) | ||
| ); | ||
| }) |
There was a problem hiding this comment.
Keep instruction headings in the PDF.
When an instruction is a standalone Markdown heading, this filter removes its text. The PDF then loses section names such as “Dough” and “Filling,” which can make the remaining steps ambiguous. Render headings as unnumbered section labels instead of discarding them. The instruction component renders each instruction through VueShowdown. (raw.githubusercontent.com)
|
Hello @DerWossi, first, thanks for taking the time. I am just on mobile, so I cannot effectively check your main contribution (the big function block). However I have a few comments, you might want to address them in a quick manner. Otherwise, we can address this in a dedicated step:
Anything else after real review |
|
Thanks @christianlupus for your fast and appreciated answer!
I will move the new function in a seperate module to keep the original code clean. I should have thought of it right away... Maybe i need to open a new PR then? I don't have much experience with it yet. br |
|
No problem, just keep commiting to this PR's branch. It will be appended and squashed in the end. Don't worry too much about it (unless you accidentally committed private data). |
There was a problem hiding this comment.
Actionable comments posted: 2

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
aff5a790-f468-4242-a5c4-7441db46d3ac
Files selected for processing: 3-
src/components/RecipeView/RecipeView.vuesrc/js/recipePdfExport.tssrc/tests/unit/recipePdfExport.test.js
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
-
| ensureSpace(LINE_HEIGHT); | ||
| pdf.text(line, MARGIN, cursor); | ||
| cursor += LINE_HEIGHT; |
There was a problem hiding this comment.
Increase the line spacing for wrapped titles.
When a long recipe name wraps, addText places its 20-point lines only 5 mm apart. The lines can overlap in the saved PDF. Calculate the baseline step from fontSize, and use that step for both ensureSpace and cursor. jsPDF measures font size in points, while this document uses millimetres for positions. (parallax.github.io)
Topic and Scope
Clear PDF export for recipes. Usefull for sharing with friends without Nextcloud and loving printed paper ;-)
Print2PDF doesn't meet this requirement because it's too detailed. Also, it's not intuitive to find if you're a "simple" user.
Concerns/issues
Unicode restriction in the PDF.
This could apply to Arabic or Japanese recipe texts and emojis, for example. A Unicode font would be required for full Unicode support.
Formal requirements
There are some formal requirements that should be satisfied. Please mark those by checking the corresponding box.
I uses Copilot for coding and testing