From 2f5913e46ce1fcd908e2fdb203848a1ee027607e Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 30 May 2026 15:56:52 +0000 Subject: [PATCH 1/5] chore: sync updates.xml 01.01.00 from main [skip ci] --- updates.xml | 88 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/updates.xml b/updates.xml index 9d21229..03112ed 100644 --- a/updates.xml +++ b/updates.xml @@ -1,27 +1,103 @@ Module - MokoJoomHero - Module - MokoJoomHero development build. + Module - MokoJoomHero dev build. mod_mokojoomhero module site - 01.00.18-dev + 01.01.00-dev 2026-05-30 - https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/development + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/development - https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/development/mod_mokojoomhero-01.00.18-dev.zip + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/development/mod_mokojoomhero-01.01.00-dev.zip - a629c54e31bcb6761d709a1b3c384c788172694365922dfad1b737fe502cf6c2 + f07dbfd79e507c3fb250cc34618940ef226bf58053b96b8d893cd9d33237717e dev https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/CHANGELOG.md Moko Consulting https://mokoconsulting.tech + + + + Module - MokoJoomHero + Module - MokoJoomHero alpha build. + mod_mokojoomhero + module + site + 01.01.00-alpha + 2026-05-30 + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/alpha + + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/alpha/mod_mokojoomhero-01.01.00-alpha.zip + + f07dbfd79e507c3fb250cc34618940ef226bf58053b96b8d893cd9d33237717e + alpha + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/CHANGELOG.md + Moko Consulting + https://mokoconsulting.tech + + + + Module - MokoJoomHero + Module - MokoJoomHero beta build. + mod_mokojoomhero + module + site + 01.01.00-beta + 2026-05-30 + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/beta + + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/beta/mod_mokojoomhero-01.01.00-beta.zip + + f07dbfd79e507c3fb250cc34618940ef226bf58053b96b8d893cd9d33237717e + beta + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/CHANGELOG.md + Moko Consulting + https://mokoconsulting.tech + + + + Module - MokoJoomHero + Module - MokoJoomHero rc build. + mod_mokojoomhero + module + site + 01.01.00-rc + 2026-05-30 + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/release-candidate + + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/release-candidate/mod_mokojoomhero-01.01.00-rc.zip + + f07dbfd79e507c3fb250cc34618940ef226bf58053b96b8d893cd9d33237717e + rc + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/CHANGELOG.md + Moko Consulting + https://mokoconsulting.tech + + + + Module - MokoJoomHero + Module - MokoJoomHero stable build. + mod_mokojoomhero + module + site + 01.01.00 + 2026-05-30 + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/tag/stable + + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/releases/download/stable/mod_mokojoomhero-01.01.00.zip + + f07dbfd79e507c3fb250cc34618940ef226bf58053b96b8d893cd9d33237717e + stable + https://git.mokoconsulting.tech/MokoConsulting/MokoJoomHero/raw/branch/main/CHANGELOG.md + Moko Consulting + https://mokoconsulting.tech -- 2.52.0 From 5362f370beda645c04ceac042f3df7c54f466295 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 10:58:59 -0500 Subject: [PATCH 2/5] docs: update changelog for 01.01.00 release Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76eb05a..7e9204a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ Version format: `XX.YY.ZZ` (zero-padded semver). ## [Unreleased] +## [01.01.00] - 2026-05-30 + +### Fixed +- WebAsset registration: added `#style`/`#script` suffixes to preset dependencies (was causing `UnsatisfiedDependencyException`) +- Asset URI resolution: use `extension/filename` pattern instead of `extension/folder/filename` (Joomla auto-inserts `css/`/`js/` folders) +- iframe video cover: split CSS into `` (`object-fit: cover`) and `` (oversize + centre-crop) rules since `object-fit` doesn't apply to iframes +- Card link styling: exclude `.btn` elements from `color: inherit` so buttons retain their own styles + +### Added +- Module title renders inside the hero card as ``, respecting Joomla's Show Title toggle +- IntersectionObserver pauses/resumes videos when the hero scrolls out of/into the viewport (YouTube, Vimeo, and native ``) +- YouTube embeds include `enablejsapi=1` for postMessage playback control + ### Changed - Migrated all workflow and template paths from `.github/` to `.mokogitea/` - Template source paths updated -- 2.52.0 From e83162a37cc058a44b8bb87aca70081a2a197b90 Mon Sep 17 00:00:00 2001 From: Jonathan Miller <1+jmiller@noreply.git.mokoconsulting.tech> Date: Sat, 30 May 2026 16:02:59 +0000 Subject: [PATCH 3/5] chore: sync .mokogitea/workflows/pr-check.yml from moko-platform [skip ci] --- .mokogitea/workflows/pr-check.yml | 38 ++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/.mokogitea/workflows/pr-check.yml b/.mokogitea/workflows/pr-check.yml index df06523..ce64a27 100644 --- a/.mokogitea/workflows/pr-check.yml +++ b/.mokogitea/workflows/pr-check.yml @@ -52,22 +52,22 @@ jobs: REASON="Fix branches must target 'dev', not '${BASE}'" fi ;; + patch/*) + if [ "$BASE" != "dev" ] && [ "$BASE" != "rc" ]; then + ALLOWED=false + REASON="Patch branches must target 'dev' or 'rc', not '${BASE}'" + fi + ;; hotfix/*) if [ "$BASE" != "dev" ] && [ "$BASE" != "main" ]; then ALLOWED=false REASON="Hotfix branches can only target 'dev' or 'main', not '${BASE}'" fi ;; - alpha/*|beta/*) - if [ "$BASE" != "dev" ]; then - ALLOWED=false - REASON="Pre-release branches must target 'dev', not '${BASE}'" - fi - ;; - rc/*) + rc) if [ "$BASE" != "main" ]; then ALLOWED=false - REASON="Release candidate branches must target 'main', not '${BASE}'" + REASON="RC branch can only merge into 'main', not '${BASE}'" fi ;; dev) @@ -183,6 +183,28 @@ jobs: ;; esac + - name: Check changelog has unreleased entry + run: | + if [ ! -f "CHANGELOG.md" ]; then + echo "::warning::No CHANGELOG.md found" + exit 0 + fi + # Check for content under [Unreleased] section + if ! grep -q "## \[Unreleased\]" CHANGELOG.md; then + echo "::error::CHANGELOG.md missing [Unreleased] section" + exit 1 + fi + # Check there's at least one entry (Added/Changed/Fixed/Removed) under Unreleased + UNRELEASED_CONTENT=$(sed -n '/## \[Unreleased\]/,/## \[/p' CHANGELOG.md | grep -cE '^\s*-\s' || true) + if [ "$UNRELEASED_CONTENT" -eq 0 ]; then + echo "::error::CHANGELOG.md [Unreleased] section has no entries. Add a changelog entry describing your changes." + echo "## Changelog Check: Failed" >> $GITHUB_STEP_SUMMARY + echo "The \`[Unreleased]\` section in CHANGELOG.md has no entries." >> $GITHUB_STEP_SUMMARY + echo "Add a line like \`- Description of your change\` under a heading (\`### Added\`, \`### Changed\`, \`### Fixed\`, etc.)" >> $GITHUB_STEP_SUMMARY + exit 1 + fi + echo "Changelog: ${UNRELEASED_CONTENT} entry/entries in [Unreleased]" + - name: Verify package source run: | SOURCE_DIR="src" -- 2.52.0 From 6501fe7d0bd7e3a8a30f5504a2684a22a7336e03 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 11:24:46 -0500 Subject: [PATCH 4/5] docs: add planned features to changelog (#39, #40) Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e9204a..eae924b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ Version format: `XX.YY.ZZ` (zero-padded semver). ## [Unreleased] +### Planned +- Configurable card fade-in delay (#39) +- Video audio mute/unmute option (#40) + ## [01.01.00] - 2026-05-30 ### Fixed -- 2.52.0 From 17b66b021034cc4e385e9e87089d237575468cab Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 14:02:37 -0500 Subject: [PATCH 5/5] feat: add card fade-in delay and video mute toggle (#39, #40) - Card fade-in delay: configurable delay (0-5000ms) before the content card appears with a smooth slide-up animation. Set via cardDelay param. - Mute toggle: optional button in bottom-right corner to unmute/mute video audio. Videos always start muted (browser autoplay requirement). Supports YouTube postMessage API, Vimeo postMessage, and native video. - New manifest params: cardDelay (number), showMuteToggle (radio) - Language strings added for both en-US and en-GB Closes #39, closes #40 Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- src/language/en-GB/mod_mokojoomhero.ini | 8 +++++ src/language/en-US/mod_mokojoomhero.ini | 8 +++++ src/media/css/mod_mokojoomhero.css | 39 +++++++++++++++++++++++++ src/media/js/mod_mokojoomhero.js | 30 +++++++++++++++++++ src/mod_mokojoomhero.php | 2 ++ src/mod_mokojoomhero.xml | 23 +++++++++++++++ src/tmpl/default.php | 10 ++++++- 7 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/language/en-GB/mod_mokojoomhero.ini b/src/language/en-GB/mod_mokojoomhero.ini index c2cf827..12ee63f 100644 --- a/src/language/en-GB/mod_mokojoomhero.ini +++ b/src/language/en-GB/mod_mokojoomhero.ini @@ -36,6 +36,14 @@ MOD_MOKOJOOMHERO_SLIDE_INTERVAL_DESC="Time between slides in milliseconds (e.g. MOD_MOKOJOOMHERO_VIDEO_FILE_LABEL="Video URL" MOD_MOKOJOOMHERO_VIDEO_FILE_DESC="Local file path, YouTube URL, or Vimeo URL. Any format works — the module auto-detects the source." +; Card delay +MOD_MOKOJOOMHERO_CARD_DELAY_LABEL="Card Fade-in Delay (ms)" +MOD_MOKOJOOMHERO_CARD_DELAY_DESC="Delay in milliseconds before the content card fades in. Set to 0 for no delay." + +; Mute toggle +MOD_MOKOJOOMHERO_MUTE_TOGGLE_LABEL="Show Mute Toggle" +MOD_MOKOJOOMHERO_MUTE_TOGGLE_DESC="Show a mute/unmute button on the hero video. Videos always start muted (required for autoplay)." + ; Hero height MOD_MOKOJOOMHERO_HERO_HEIGHT_LABEL="Hero Height" MOD_MOKOJOOMHERO_HERO_HEIGHT_DESC="Height of the hero section. Use px for fixed pixels (e.g. 400px) or vh for viewport height (e.g. 60vh for 60%% of screen)." diff --git a/src/language/en-US/mod_mokojoomhero.ini b/src/language/en-US/mod_mokojoomhero.ini index e3f89c0..0931854 100644 --- a/src/language/en-US/mod_mokojoomhero.ini +++ b/src/language/en-US/mod_mokojoomhero.ini @@ -41,6 +41,14 @@ MOD_MOKOJOOMHERO_HERO_HEIGHT_LABEL="Hero Height" MOD_MOKOJOOMHERO_HERO_HEIGHT_DESC="Height of the hero section. Use px for fixed pixels (e.g. 400px) or vh for viewport height (e.g. 60vh for 60% of screen)." MOD_MOKOJOOMHERO_HERO_HEIGHT_HINT="e.g. 60vh or 400px" +; Card delay +MOD_MOKOJOOMHERO_CARD_DELAY_LABEL="Card Fade-in Delay (ms)" +MOD_MOKOJOOMHERO_CARD_DELAY_DESC="Delay in milliseconds before the content card fades in. Set to 0 for no delay." + +; Mute toggle +MOD_MOKOJOOMHERO_MUTE_TOGGLE_LABEL="Show Mute Toggle" +MOD_MOKOJOOMHERO_MUTE_TOGGLE_DESC="Show a mute/unmute button on the hero video. Videos always start muted (required for autoplay)." + ; Overlay fieldset MOD_MOKOJOOMHERO_FIELDSET_OVERLAY="Overlay & Text" MOD_MOKOJOOMHERO_OVERLAY_COLOR_LABEL="Overlay Color" diff --git a/src/media/css/mod_mokojoomhero.css b/src/media/css/mod_mokojoomhero.css index 68f0f3c..f45eb39 100644 --- a/src/media/css/mod_mokojoomhero.css +++ b/src/media/css/mod_mokojoomhero.css @@ -126,6 +126,45 @@ iframe.mokojoomhero__video { text-decoration: underline; } +/* ============================================================ + Card fade-in delay + ============================================================ */ +.mokojoomhero__card[data-card-delay] { + opacity: 0; + animation: mokojoomhero-fadein 0.6s ease forwards; +} + +@keyframes mokojoomhero-fadein { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +/* ============================================================ + Mute toggle + ============================================================ */ +.mokojoomhero__mute-toggle { + position: absolute; + bottom: 1rem; + right: 1rem; + z-index: 2; + background: rgba(0, 0, 0, 0.5); + color: #fff; + border: none; + border-radius: 50%; + width: 40px; + height: 40px; + font-size: 1.2rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: background 0.2s; +} + +.mokojoomhero__mute-toggle:hover { + background: rgba(0, 0, 0, 0.7); +} + /* ============================================================ Responsive ============================================================ */ diff --git a/src/media/js/mod_mokojoomhero.js b/src/media/js/mod_mokojoomhero.js index 767843a..1375195 100644 --- a/src/media/js/mod_mokojoomhero.js +++ b/src/media/js/mod_mokojoomhero.js @@ -85,4 +85,34 @@ document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.mokojoomhero').forEach(function (hero) { observer.observe(hero); }); + + // ── Mute/unmute toggle ── + document.querySelectorAll('.mokojoomhero__mute-toggle').forEach(function (btn) { + var hero = btn.closest('.mokojoomhero'); + var video = hero.querySelector('video.mokojoomhero__video'); + var iframe = hero.querySelector('iframe.mokojoomhero__video'); + var icon = btn.querySelector('.mokojoomhero__mute-icon'); + + btn.addEventListener('click', function () { + var muted = btn.getAttribute('data-muted') === 'true'; + + if (video) { + video.muted = !muted; + } + if (iframe) { + var src = iframe.src || ''; + if (src.indexOf('youtube') !== -1) { + var func = muted ? 'unMute' : 'mute'; + iframe.contentWindow.postMessage('{"event":"command","func":"' + func + '","args":""}', '*'); + } else if (src.indexOf('vimeo') !== -1) { + var vol = muted ? 1 : 0; + iframe.contentWindow.postMessage('{"method":"setVolume","value":' + vol + '}', '*'); + } + } + + btn.setAttribute('data-muted', muted ? 'false' : 'true'); + btn.setAttribute('aria-label', muted ? 'Mute video' : 'Unmute video'); + icon.textContent = muted ? '\u{1F50A}' : '\u{1F507}'; + }); + }); }); diff --git a/src/mod_mokojoomhero.php b/src/mod_mokojoomhero.php index 9403fcc..58a6c2a 100644 --- a/src/mod_mokojoomhero.php +++ b/src/mod_mokojoomhero.php @@ -35,6 +35,8 @@ $textAlign = $params->get('textAlign', 'center'); $textColor = $params->get('textColor', '#ffffff'); $heroContent = $params->get('heroContent', ''); $showCard = (bool) $params->get('showCard', 1); +$cardDelay = (int) $params->get('cardDelay', 0); +$showMuteToggle = (bool) $params->get('showMuteToggle', 0); // Collect hero images $heroImages = []; diff --git a/src/mod_mokojoomhero.xml b/src/mod_mokojoomhero.xml index 4ac4422..655c66b 100644 --- a/src/mod_mokojoomhero.xml +++ b/src/mod_mokojoomhero.xml @@ -104,6 +104,18 @@ default="60vh" filter="string" /> + + JNO + JYES + JNO JYES + id; @@ -61,12 +63,18 @@ $heightAttr = htmlspecialchars($heroHeight, ENT_QUOTES, 'UTF-8'); + + + 🔇 + + + showtitle) : ?> - + style="animation-delay: ms;" data-card-delay=""> showtitle) : ?> title, ENT_QUOTES, 'UTF-8'); ?> -- 2.52.0