mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-02 10:52:27 +00:00
Preserve autoplay preference on fallback; reload open comment thread after login
### Motivation
- Prevent a browser-policy muted-autoplay retry from overwriting a viewer's explicit mute/unmute preference and ensure fallback mutes are transient.
- Ensure that when a user logs in while a video comment modal is open, the open thread is reloaded (not just refreshed) so comments continue to display correctly after relay-backed services are reconfigured.
### Description
- Add `js/utils/autoplayPreference.js` with `muteForAutoplayFallback` and `consumeAutoplayFallbackMute` helpers to mark and consume transient fallback mutes.
- Update `js/services/playbackService.js` to treat sound as default unless the viewer explicitly chose mute, persist explicit choices via `localStorage`, ignore fallback-generated volume changes using `consumeAutoplayFallbackMute`, and expose `muteForAutoplayFallback` delegating to the new util.
- Replace direct `videoElement.muted = true` calls with `playbackService.muteForAutoplayFallback` in `js/app/playbackCoordinator.js` and `js/webtorrent.js` so fallback mutes are marked as transient.
- Change `js/app/authSessionCoordinator.js` to reload the currently open video comment thread with `commentController.load(activeModalVideo)` after login if a modal video is active, instead of only calling `refreshAuthState`.
- Update tests in `tests/services/playbackService.test.mjs` and add a test in `tests/app/login-defers-dms.test.mjs` to cover the login behavior that reloads an open comment thread.
### Testing
- Ran the `PlaybackService` unit tests (`tests/services/playbackService.test.mjs`) which assert `prepareVideoElement` behavior, explicit mute persistence, and the transient nature of fallback mute, and they passed.
- Ran the auth login unit tests including `tests/app/login-defers-dms.test.mjs` which verifies DM deferral and reload of an open comment thread, and they passed.
(cherry picked from commit ce14004725)
This commit is contained in:
1 parent
d8e5113efd
commit
f0a3ede3e5
7 files changed
+241
-23
No files matched your search
@@ -46,6 +46,14 @@ function closeLoginModal() {
|
||||
}
|
||||
}
|
||||
|
||||
function isHtmlElement(value, documentRef = document) {
|
||||
const HTMLElementConstructor =
|
||||
documentRef?.defaultView?.HTMLElement || globalThis.HTMLElement;
|
||||
return typeof HTMLElementConstructor === "function"
|
||||
? value instanceof HTMLElementConstructor
|
||||
: Boolean(value && value.nodeType === 1);
|
||||
}
|
||||
|
||||
// Cheap insurance against wireBitloginLogin() ever running twice for the same
|
||||
// element (e.g. a future bootstrap change that calls it more than once): the
|
||||
// same <bitlogin-auth> instance should only ever get one "bitlogin-login"
|
||||
@@ -82,12 +90,12 @@ function attachWidget(app, widget) {
|
||||
// Unstable-branch experiment (AGENTS.md §1, config/instance-config.js) --
|
||||
// leave the permanent, statically-declared markup in place but never load
|
||||
// the vendored bundle or show the (otherwise-empty, unupgraded) element.
|
||||
if (mount instanceof HTMLElement) {
|
||||
if (isHtmlElement(mount)) {
|
||||
mount.hidden = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mount instanceof HTMLElement) {
|
||||
if (isHtmlElement(mount)) {
|
||||
mount.hidden = false;
|
||||
}
|
||||
|
||||
@@ -162,22 +170,29 @@ function attachWidget(app, widget) {
|
||||
* @param {{ authService: { requestLogin: Function } }} app
|
||||
*/
|
||||
export function wireBitloginLogin(app) {
|
||||
if (!app?.authService) {
|
||||
if (!app?.authService || typeof document === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = document.getElementById("bitloginWidget");
|
||||
if (existing instanceof HTMLElement) {
|
||||
const documentRef = document;
|
||||
const existing = documentRef.getElementById("bitloginWidget");
|
||||
if (isHtmlElement(existing, documentRef)) {
|
||||
attachWidget(app, existing);
|
||||
return;
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const widget = document.getElementById("bitloginWidget");
|
||||
if (widget instanceof HTMLElement) {
|
||||
const Observer =
|
||||
documentRef.defaultView?.MutationObserver || globalThis.MutationObserver;
|
||||
if (typeof Observer !== "function" || !documentRef.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
const observer = new Observer(() => {
|
||||
const widget = documentRef.getElementById("bitloginWidget");
|
||||
if (isHtmlElement(widget, documentRef)) {
|
||||
observer.disconnect();
|
||||
attachWidget(app, widget);
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
observer.observe(documentRef.body, { childList: true, subtree: true });
|
||||
}
|
||||
Reference in new issue
Block a user