Add dynamic sizing of recipe
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-active {
|
||||
--ncc-type-scale: 1;
|
||||
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 20;
|
||||
@@ -49,9 +51,9 @@
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-recipe h1 {
|
||||
margin: 0 220px 26px 0;
|
||||
margin: 0 220px calc(26px * var(--ncc-type-scale)) 0;
|
||||
color: #fff6d8;
|
||||
font-size: 82px;
|
||||
font-size: calc(82px * var(--ncc-type-scale));
|
||||
line-height: 1.08;
|
||||
}
|
||||
|
||||
@@ -59,8 +61,8 @@
|
||||
display: flex;
|
||||
gap: 10px 22px;
|
||||
align-items: baseline;
|
||||
margin: 0 0 36px;
|
||||
font-size: 36px;
|
||||
margin: 0 0 calc(36px * var(--ncc-type-scale));
|
||||
font-size: calc(36px * var(--ncc-type-scale));
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-meta dt {
|
||||
@@ -79,21 +81,21 @@
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-columns h2 {
|
||||
margin: 0 0 18px;
|
||||
margin: 0 0 calc(18px * var(--ncc-type-scale));
|
||||
color: #d6b96b;
|
||||
font-size: 56px;
|
||||
font-size: calc(56px * var(--ncc-type-scale));
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-columns ul,
|
||||
.MMM-NextcloudCookbook .ncc-columns ol {
|
||||
margin: 0;
|
||||
padding-left: 1.25em;
|
||||
font-size: 50px;
|
||||
font-size: calc(50px * var(--ncc-type-scale));
|
||||
line-height: 1.36;
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-columns li {
|
||||
margin-bottom: 18px;
|
||||
margin-bottom: calc(18px * var(--ncc-type-scale));
|
||||
}
|
||||
|
||||
.MMM-NextcloudCookbook .ncc-error {
|
||||
|
||||
@@ -12,6 +12,7 @@ Module.register("MMM-NextcloudCookbook", {
|
||||
start() {
|
||||
this.state = { active: false, recipe: null, error: null };
|
||||
this.hiddenModules = false;
|
||||
window.addEventListener("resize", () => this.scheduleRecipeFit());
|
||||
this.sendSocketNotification("CONFIG", this.config);
|
||||
},
|
||||
|
||||
@@ -30,6 +31,45 @@ Module.register("MMM-NextcloudCookbook", {
|
||||
this.updateDom(this.config.animationSpeed);
|
||||
},
|
||||
|
||||
notificationReceived(notification) {
|
||||
if (notification === "MODULE_DOM_UPDATED") this.scheduleRecipeFit();
|
||||
},
|
||||
|
||||
scheduleRecipeFit() {
|
||||
window.requestAnimationFrame(() => this.fitRecipe());
|
||||
},
|
||||
|
||||
fitRecipe() {
|
||||
const root = document.getElementById(this.identifier)?.querySelector(".ncc-active");
|
||||
const recipe = root?.querySelector(".ncc-recipe");
|
||||
if (!root || !recipe) return;
|
||||
|
||||
const style = window.getComputedStyle(root);
|
||||
const availableHeight = root.clientHeight
|
||||
- Number.parseFloat(style.paddingTop)
|
||||
- Number.parseFloat(style.paddingBottom);
|
||||
const availableWidth = root.clientWidth
|
||||
- Number.parseFloat(style.paddingLeft)
|
||||
- Number.parseFloat(style.paddingRight);
|
||||
let minimum = 0.45;
|
||||
let maximum = 2;
|
||||
let best = minimum;
|
||||
|
||||
for (let attempt = 0; attempt < 12; attempt++) {
|
||||
const scale = (minimum + maximum) / 2;
|
||||
root.style.setProperty("--ncc-type-scale", scale);
|
||||
const fits = recipe.scrollHeight <= availableHeight
|
||||
&& recipe.scrollWidth <= availableWidth;
|
||||
if (fits) {
|
||||
best = scale;
|
||||
minimum = scale;
|
||||
} else {
|
||||
maximum = scale;
|
||||
}
|
||||
}
|
||||
root.style.setProperty("--ncc-type-scale", best.toFixed(3));
|
||||
},
|
||||
|
||||
setRecipeMode(active) {
|
||||
if (active && !this.hiddenModules) {
|
||||
MM.getModules().exceptModule(this).enumerate((module) => {
|
||||
|
||||
@@ -98,6 +98,50 @@ References:
|
||||
- [Cookbook API documentation](https://nextcloud.github.io/cookbook/dev/api/0.1.0/index.html)
|
||||
- [Cookbook user documentation](https://nextcloud.github.io/cookbook/user/)
|
||||
|
||||
## Future architecture: recipe sources and consumers
|
||||
|
||||
The current module both retrieves recipes and presents the full-screen recipe
|
||||
mode. A future version should separate those responsibilities using
|
||||
MagicMirror's notification system as a shared recipe data stream:
|
||||
|
||||
```text
|
||||
MMM-NextcloudCookbook ─┐
|
||||
MMM-Paprika ───────────┼── recipe data notifications ──> MMM-RecipeMode
|
||||
MMM-Mealime ───────────┘
|
||||
```
|
||||
|
||||
In that model:
|
||||
|
||||
- `MMM-NextcloudCookbook` is a source adapter. It reads recipes from Nextcloud
|
||||
Cookbook and publishes normalized recipe records.
|
||||
- `MMM-RecipeMode` is a consumer. It provides recipe selection, the phone
|
||||
control page, portion scaling, QR code, and full-screen cooking display.
|
||||
- Other source modules can publish recipes from Paprika, Mealime, local files,
|
||||
or other services without duplicating the presentation code.
|
||||
- Additional consumers can use the same recipe data for meal planning, search,
|
||||
shopping lists, dashboards, or other displays.
|
||||
|
||||
The shared notification contract should eventually define source-qualified
|
||||
stable recipe IDs, basic list metadata, complete recipe records, refresh and
|
||||
error states, and optional source capabilities. The normalized record should
|
||||
retain schema.org Recipe fields where practical. Exact notification names and
|
||||
payload schemas should be designed when a second source or consumer is
|
||||
implemented, rather than treating the current module's private HTTP API as the
|
||||
cross-module contract.
|
||||
|
||||
This separation is a future feature. The current combined behavior should
|
||||
remain functional until `MMM-RecipeMode` can replace its presentation and
|
||||
control responsibilities.
|
||||
|
||||
### Future presentation option: preserve selected modules
|
||||
|
||||
Recipe mode currently hides every other MagicMirror module. A future
|
||||
`MMM-RecipeMode` configuration should accept an allowlist of modules to leave
|
||||
visible while cooking. For example, a user could preserve a calendar at the top
|
||||
of the display while the recipe occupies the remaining area. The option should
|
||||
support module names and, where multiple instances exist, specific instance
|
||||
identifiers. Hiding all other modules should remain the default.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user