"Open in new tab"

This commit is contained in:
Simon
2026-07-06 15:32:31 +00:00
parent 7207e36510
commit b6b17b1f52
2 changed files with 34 additions and 6 deletions

View File

@@ -1495,7 +1495,13 @@ body.theme-light .favorite-btn {
z-index: 5;
}
.cp-retry-btn {
.cp-error-actions {
display: flex;
gap: 10px;
}
.cp-retry-btn,
.cp-open-btn {
padding: 8px 20px;
border-radius: 999px;
border: 1px solid var(--accent);
@@ -1503,12 +1509,19 @@ body.theme-light .favorite-btn {
color: var(--accent);
cursor: pointer;
font: inherit;
text-decoration: none;
line-height: 1.2;
}
.cp-retry-btn:hover {
.cp-retry-btn:hover,
.cp-open-btn:hover {
background: rgba(201, 165, 103, 0.15);
}
.cp-open-btn[hidden] {
display: none;
}
.cp-replay-btn {
position: absolute;
top: 50%;

View File

@@ -51,7 +51,10 @@ App.player = App.player || {};
<div class="cp-spinner" aria-hidden="true"><div class="cp-spinner-ring"></div></div>
<div class="cp-error" hidden>
<p class="cp-error-text"></p>
<div class="cp-error-actions">
<button class="cp-retry-btn" type="button">Retry</button>
<a class="cp-open-btn" type="button" target="_blank" rel="noopener noreferrer" hidden>Open in new tab</a>
</div>
</div>
<button class="cp-replay-btn" type="button" aria-label="Replay" hidden>
<img class="icon-svg" src="https://cdn.jsdelivr.net/npm/heroicons@2.0.13/24/outline/arrow-path.svg" alt="Replay">
@@ -543,11 +546,12 @@ App.player = App.player || {};
if (spinner) spinner.classList.toggle('is-visible', show);
}
function showError(message, onRetry) {
function showError(message, onRetry, sourceUrl) {
showBuffering(false);
const errorEl = q('.cp-error');
const textEl = q('.cp-error-text');
const retryBtn = q('.cp-retry-btn');
const openBtn = q('.cp-open-btn');
if (!errorEl) return;
if (textEl) textEl.textContent = message || 'Playback failed.';
errorEl.hidden = false;
@@ -558,6 +562,15 @@ App.player = App.player || {};
onRetry();
};
}
if (openBtn) {
if (sourceUrl) {
openBtn.href = sourceUrl;
openBtn.hidden = false;
} else {
openBtn.hidden = true;
openBtn.removeAttribute('href');
}
}
}
function hideError() {
@@ -594,9 +607,11 @@ App.player = App.player || {};
const clearLoading = () => {
if (originEl) originEl.classList.remove('is-loading');
};
const sourceUrl = (videoData && (videoData.url || (videoData.meta && videoData.meta.url))) || '';
if (!sources.length) {
clearLoading();
showError('Unable to play this stream.', () => playSources(videoData, opts));
showError('Unable to play this stream.', () => playSources(videoData, opts), sourceUrl);
return;
}
@@ -621,7 +636,7 @@ App.player = App.player || {};
if (hasNext) attempt(index + 1);
else {
clearLoading();
showError(message, () => playSources(videoData, opts));
showError(message, () => playSources(videoData, opts), sourceUrl);
}
};