[TikiWiki-commits] [Git][tikiwiki/tiki][master] [FIX][ENH] Teleprompter: Improve Teleprompter controls and fullscreen UX
"Bruno Kambere \(@kambereBr\) via TikiWiki-cvs" <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <6a22ae39180fb_3819460006c@gitlab-sidekiq-low-urgency-cpu-bound-v2-679d75d87c-pvwsn.mail> |
Bruno Kambere pushed to branch master at Tiki Wiki CMS Groupware / Tiki
Commits:
76b7692e by UshindiG at 2026-06-05T13:49:09+03:00
[FIX][ENH] Teleprompter: Improve Teleprompter controls and fullscreen UX
---
* [FIX][ENH] Teleprompter: Improve Teleprompter controls and fullscreen UX
See merge request tikiwiki/tiki!10405
- - - - -
3 changed files:
- lib/wiki-plugins/css/teleprompter.css
- lib/wiki-plugins/js/teleprompter.js
- lib/wiki-plugins/wikiplugin_teleprompter.php
Changes:
=====================================
lib/wiki-plugins/css/teleprompter.css
=====================================
@@ -10,6 +10,18 @@
margin-bottom: 20px;
}
+.teleprompter-container:fullscreen {
+ width: 100% !important;
+ height: 100% !important;
+ background: #000;
+}
+
+.teleprompter-container:-webkit-full-screen {
+ width: 100% !important;
+ height: 100% !important;
+ background: #000;
+}
+
.teleprompter-container:focus-visible {
outline: 2px solid rgba(255, 255, 255, 0.7);
outline-offset: 2px;
@@ -137,11 +149,25 @@
bottom: 10px;
z-index: 3;
display: flex;
- gap: 8px;
+ flex-wrap: wrap;
+ gap: 6px;
+ max-width: calc(100% - 120px);
+ padding: 4px;
+ border-radius: 6px;
+ background: rgba(0, 0, 0, 0.35);
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.16s ease-in-out;
}
.teleprompter-controls-hidden {
- display: none;
+ display: none !important;
+}
+
+.teleprompter-control-group {
+ display: flex;
+ gap: 4px;
}
.teleprompter-btn {
@@ -151,15 +177,23 @@
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 12px;
+ font-weight: 600;
line-height: 1;
- padding: 0.4rem 0.6rem;
+ padding: 0.35rem 0.5rem;
cursor: pointer;
+ min-width: 32px;
+ min-height: 30px;
}
.teleprompter-btn:hover {
background: rgba(0, 0, 0, 0.7);
}
+.teleprompter-btn-active {
+ background: rgba(255, 255, 255, 0.22);
+ border-color: rgba(255, 255, 255, 0.75);
+}
+
.teleprompter-btn:focus-visible {
outline: 2px solid rgba(255, 255, 255, 0.7);
outline-offset: 2px;
@@ -178,8 +212,28 @@
font-family: monospace;
line-height: 1;
font-variant-numeric: tabular-nums;
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.16s ease-in-out;
+}
+
+.teleprompter-container:hover .teleprompter-controls,
+.teleprompter-container:focus-within .teleprompter-controls,
+.teleprompter-container.teleprompter-controls-active .teleprompter-controls,
+.teleprompter-container:hover .teleprompter-timer,
+.teleprompter-container:focus-within .teleprompter-timer,
+.teleprompter-container.teleprompter-controls-active .teleprompter-timer {
+ opacity: 1;
+ pointer-events: auto;
}
.teleprompter-timer-hidden {
- display: none;
+ display: none !important;
+}
+
+@media (max-width: 576px) {
+ .teleprompter-controls {
+ right: 12px;
+ max-width: calc(100% - 24px);
+ }
}
=====================================
lib/wiki-plugins/js/teleprompter.js
=====================================
@@ -53,8 +53,10 @@
pausedByUser: false,
reachedEnd: false,
resizeDebounceId: null,
+ controlsVisibilityTimer: null,
speed: clamp(Math.abs(toNumber(opts.speed, 35)), settings.minSpeed, settings.maxSpeed)
};
+ var initialSpeed = state.speed;
if (settings.reverseScroll) {
state.speed = -state.speed;
}
@@ -68,6 +70,9 @@
var $controls = $container.find(".teleprompter-controls");
var $toggleControl = $controls.find(".teleprompter-btn-toggle");
var $restartControl = $controls.find(".teleprompter-btn-restart");
+ var $speedControls = $controls.find("[data-tp-speed]");
+ var $fontControls = $controls.find("[data-tp-font]");
+ var $fullscreenControl = $controls.find("[data-tp-fullscreen]");
var $progress = $container.find(".teleprompter-progress");
var $progressThumb = $progress.find(".teleprompter-progress-thumb");
@@ -75,6 +80,21 @@
return settings.reverseScroll && state.maxOffset > 0 ? state.maxOffset : 0;
};
+ var revealControls = function () {
+ if (!settings.showControls) {
+ return;
+ }
+
+ $container.addClass("teleprompter-controls-active");
+ if (state.controlsVisibilityTimer !== null) {
+ window.clearTimeout(state.controlsVisibilityTimer);
+ }
+ state.controlsVisibilityTimer = window.setTimeout(function () {
+ state.controlsVisibilityTimer = null;
+ $container.removeClass("teleprompter-controls-active");
+ }, 3000);
+ };
+
var updateToggleControl = function () {
if (!$toggleControl.length) {
return;
@@ -234,6 +254,7 @@
var restartFromBeginning = function () {
refreshLayout();
+ state.speed = settings.reverseScroll ? -initialSpeed : initialSpeed;
state.offset = getStartOffset();
state.elapsedMs = 0;
state.lastTs = null;
@@ -296,6 +317,65 @@
}
};
+ var fullscreenElement = function () {
+ return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
+ };
+
+ var enterFullscreen = function () {
+ var element = $container.get(0);
+ if (!element) {
+ return false;
+ }
+
+ var requestFullscreen = element.requestFullscreen || element.webkitRequestFullscreen || element.mozRequestFullScreen || element.msRequestFullscreen;
+ if (typeof requestFullscreen !== "function") {
+ return false;
+ }
+
+ requestFullscreen.call(element);
+ return true;
+ };
+
+ var exitFullscreen = function () {
+ var exit = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen;
+ if (typeof exit === "function") {
+ exit.call(document);
+ }
+ };
+
+ var updateFullscreenControl = function () {
+ if (!$fullscreenControl.length) {
+ return;
+ }
+
+ var isFullscreen = fullscreenElement() === $container.get(0);
+ var label = isFullscreen ? $fullscreenControl.data("tpExitFullscreenLabel") : $fullscreenControl.data("tpFullscreenLabel");
+ $fullscreenControl
+ .empty()
+ .append($("<span>", {
+ "aria-hidden": "true",
+ "class": "fas " + (isFullscreen ? "fa-compress" : "fa-expand")
+ }))
+ .append($("<span>", {
+ "class": "visually-hidden",
+ text: label
+ }))
+ .attr({
+ "aria-label": label,
+ "aria-pressed": isFullscreen ? "true" : "false",
+ title: label
+ })
+ .toggleClass("teleprompter-btn-active", isFullscreen);
+ };
+
+ var toggleFullscreen = function () {
+ if (fullscreenElement() === $container.get(0)) {
+ exitFullscreen();
+ } else {
+ enterFullscreen();
+ }
+ };
+
var applyFontScaleStep = function (direction, stepCount) {
stepCount = Math.max(1, stepCount || 1);
state.fontScale = clamp(state.fontScale + direction * settings.fontScaleStep * stepCount, settings.minFontScale, settings.maxFontScale);
@@ -359,7 +439,11 @@
if (!settings.showControls && $controls.length) {
$controls.addClass("teleprompter-controls-hidden");
}
+ if (!$container.get(0).requestFullscreen && !$container.get(0).webkitRequestFullscreen && !$container.get(0).mozRequestFullScreen && !$container.get(0).msRequestFullscreen) {
+ $fullscreenControl.hide();
+ }
updateToggleControl();
+ updateFullscreenControl();
$content.find("img").off(eventNamespace).on("load" + eventNamespace, function () {
refreshLayout();
@@ -395,6 +479,30 @@
$container.trigger("focus");
});
+ $speedControls.off(eventNamespace).on("click" + eventNamespace, function (e) {
+ e.preventDefault();
+ applySpeedStep(toNumber($(this).data("tpSpeed"), 1), 1);
+ $container.trigger("focus");
+ });
+
+ $fontControls.off(eventNamespace).on("click" + eventNamespace, function (e) {
+ e.preventDefault();
+ applyFontScaleStep(toNumber($(this).data("tpFont"), 1), 1);
+ $container.trigger("focus");
+ });
+
+ $fullscreenControl.off(eventNamespace).on("click" + eventNamespace, function (e) {
+ e.preventDefault();
+ toggleFullscreen();
+ $container.trigger("focus");
+ });
+
+ $(document).off("fullscreenchange" + eventNamespace + " webkitfullscreenchange" + eventNamespace + " mozfullscreenchange" + eventNamespace + " MSFullscreenChange" + eventNamespace)
+ .on("fullscreenchange" + eventNamespace + " webkitfullscreenchange" + eventNamespace + " mozfullscreenchange" + eventNamespace + " MSFullscreenChange" + eventNamespace, function () {
+ updateFullscreenControl();
+ refreshLayout();
+ });
+
$container.off(eventNamespace).on("keydown" + eventNamespace, function (e) {
var target = e.target;
var tagName = target && target.tagName ? target.tagName.toLowerCase() : "";
@@ -402,6 +510,8 @@
return;
}
+ revealControls();
+
var key = e.key || "";
var lowerKey = key.toLowerCase();
@@ -418,6 +528,12 @@
return;
}
+ if (lowerKey === "f") {
+ toggleFullscreen();
+ e.preventDefault();
+ return;
+ }
+
if (key === "ArrowDown" || lowerKey === "s") {
applySpeedStep(1, 1);
e.preventDefault();
@@ -450,6 +566,8 @@
var stepCount = Math.max(1, Math.min(5, Math.round(Math.abs(originalEvent.deltaY) / 100)));
applySpeedStep(direction, stepCount);
e.preventDefault();
+ }).on("focus" + eventNamespace + " mousemove" + eventNamespace + " touchstart" + eventNamespace, function () {
+ revealControls();
});
};
})(jQuery);
=====================================
lib/wiki-plugins/wikiplugin_teleprompter.php
=====================================
@@ -338,6 +338,12 @@ function wikiplugin_teleprompter($data, $params)
$teleprompterControlsLabel = htmlspecialchars(tr('Teleprompter controls'), ENT_QUOTES);
$pauseButtonLabel = htmlspecialchars(tr('Pause'), ENT_QUOTES);
$restartButtonLabel = htmlspecialchars(tr('Restart'), ENT_QUOTES);
+ $slowerButtonLabel = htmlspecialchars(tr('Slower'), ENT_QUOTES);
+ $fasterButtonLabel = htmlspecialchars(tr('Faster'), ENT_QUOTES);
+ $smallerTextButtonLabel = htmlspecialchars(tr('Smaller text'), ENT_QUOTES);
+ $largerTextButtonLabel = htmlspecialchars(tr('Larger text'), ENT_QUOTES);
+ $fullscreenButtonLabel = htmlspecialchars(tr('Fullscreen'), ENT_QUOTES);
+ $exitFullscreenButtonLabel = htmlspecialchars(tr('Exit fullscreen'), ENT_QUOTES);
return '<div id="' . $containerId . '" class="teleprompter-container' . $mirrorClass . $focusClass . '" role="region" aria-label="' . $teleprompterRegionLabel . '" tabindex="0">' .
'<div id="' . $trackId . '" class="teleprompter-track">' .
@@ -346,8 +352,19 @@ function wikiplugin_teleprompter($data, $params)
'<div class="teleprompter-focus-overlay" aria-hidden="true"><div class="tp-focus-mask tp-focus-mask-top"></div><div class="tp-focus-mask tp-focus-mask-bottom"></div><div class="tp-focus-guide"></div></div>' .
'<div class="teleprompter-progress" aria-hidden="true"><div class="teleprompter-progress-thumb"></div></div>' .
'<div class="teleprompter-controls' . $controlsClass . '" aria-label="' . $teleprompterControlsLabel . '">' .
+ '<div class="teleprompter-control-group">' .
'<button type="button" class="teleprompter-btn teleprompter-btn-toggle" data-tp-toggle="1" aria-pressed="false">' . $pauseButtonLabel . '</button>' .
'<button type="button" class="teleprompter-btn teleprompter-btn-restart" data-tp-restart="1">' . $restartButtonLabel . '</button>' .
+ '<button type="button" class="teleprompter-btn teleprompter-btn-fullscreen" data-tp-fullscreen="1" title="' . $fullscreenButtonLabel . '" aria-label="' . $fullscreenButtonLabel . '" data-tp-fullscreen-label="' . $fullscreenButtonLabel . '" data-tp-exit-fullscreen-label="' . $exitFullscreenButtonLabel . '" aria-pressed="false"><span class="fas fa-expand" aria-hidden="true"></span><span class="visually-hidden">' . $fullscreenButtonLabel . '</span></button>' .
+ '</div>' .
+ '<div class="teleprompter-control-group">' .
+ '<button type="button" class="teleprompter-btn" data-tp-speed="-1" title="' . $slowerButtonLabel . '" aria-label="' . $slowerButtonLabel . '"><span class="fas fa-backward" aria-hidden="true"></span><span class="visually-hidden">' . $slowerButtonLabel . '</span></button>' .
+ '<button type="button" class="teleprompter-btn" data-tp-speed="1" title="' . $fasterButtonLabel . '" aria-label="' . $fasterButtonLabel . '"><span class="fas fa-forward" aria-hidden="true"></span><span class="visually-hidden">' . $fasterButtonLabel . '</span></button>' .
+ '</div>' .
+ '<div class="teleprompter-control-group">' .
+ '<button type="button" class="teleprompter-btn" data-tp-font="-1" title="' . $smallerTextButtonLabel . '" aria-label="' . $smallerTextButtonLabel . '">A-</button>' .
+ '<button type="button" class="teleprompter-btn" data-tp-font="1" title="' . $largerTextButtonLabel . '" aria-label="' . $largerTextButtonLabel . '">A+</button>' .
+ '</div>' .
'</div>' .
'<div id="' . $timerId . '" class="teleprompter-timer' . $timerClass . '" aria-live="polite" aria-atomic="true">00:00</div>' .
'</div>';
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/76b7692ec860ee3b6f47198558588dd90e650ee7
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/76b7692ec860ee3b6f47198558588dd90e650ee7
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs