Compare commits

..
4 Commits
4 changed files with 250 additions and 141 deletions
+225 -124
View File
@@ -57,7 +57,11 @@ try {
// Ensure Fediverse Global Search (SepiaSearch) is default in PeertubeServerConfig
try {
if (window.PeertubeServerConfig && window.PeertubeServerConfig.search && window.PeertubeServerConfig.search.searchIndex) {
if (
window.PeertubeServerConfig &&
window.PeertubeServerConfig.search &&
window.PeertubeServerConfig.search.searchIndex
) {
window.PeertubeServerConfig.search.searchIndex.isDefaultSearch = true;
}
} catch (e) {}
@@ -149,7 +153,7 @@ try {
) {
var s = document.createElement('script');
s.id = 'yaknet-account-script';
s.src = 'https://auth.yakhub.com.tr/js/yaknet-account.js';
s.src = 'https://cdnjs.yakhub.com.tr/ajax/libs/yaknet-account/latest/yaknet-account.js';
s.async = true;
document.head.appendChild(s);
}
@@ -157,34 +161,37 @@ try {
// Intercept and sanitize YakNet Account Web Component popup menu
function hookYakNetAccountComponent() {
if (typeof customElements === 'undefined') return;
customElements.whenDefined('yaknet-account').then(function () {
var YakNetAccount = customElements.get('yaknet-account');
if (!YakNetAccount || !YakNetAccount.prototype || YakNetAccount.prototype._yaktubeSanitizerHooked) return;
YakNetAccount.prototype._yaktubeSanitizerHooked = true;
var originalRender = YakNetAccount.prototype.render;
if (typeof originalRender === 'function') {
YakNetAccount.prototype.render = function () {
originalRender.call(this);
try {
if (this.shadowRoot) {
var isOfficial = isOfficialYakTubeServer();
// 1. In YakTube: Suppress redundant/recursive link to YakTube inside services list
var selfLinks = this.shadowRoot.querySelectorAll('a[href*="yaktube.yakhub.com.tr"]');
selfLinks.forEach(function (a) {
a.style.display = 'none';
});
// 2. In third-party PeerTube instances: Suppress entire external services grid & header to avoid community backlash
if (!isOfficial) {
var appsGrid = this.shadowRoot.querySelector('.yn-apps-grid');
if (appsGrid) appsGrid.style.display = 'none';
var sectionTitle = this.shadowRoot.querySelector('#yn-services-label, .yn-section-title');
if (sectionTitle) sectionTitle.style.display = 'none';
customElements
.whenDefined('yaknet-account')
.then(function () {
var YakNetAccount = customElements.get('yaknet-account');
if (!YakNetAccount || !YakNetAccount.prototype || YakNetAccount.prototype._yaktubeSanitizerHooked) return;
YakNetAccount.prototype._yaktubeSanitizerHooked = true;
var originalRender = YakNetAccount.prototype.render;
if (typeof originalRender === 'function') {
YakNetAccount.prototype.render = function () {
originalRender.call(this);
try {
if (this.shadowRoot) {
var isOfficial = isOfficialYakTubeServer();
// 1. In YakTube: Suppress redundant/recursive link to YakTube inside services list
var selfLinks = this.shadowRoot.querySelectorAll('a[href*="yaktube.yakhub.com.tr"]');
selfLinks.forEach(function (a) {
a.style.display = 'none';
});
// 2. In third-party PeerTube instances: Suppress entire external services grid & header to avoid community backlash
if (!isOfficial) {
var appsGrid = this.shadowRoot.querySelector('.yn-apps-grid');
if (appsGrid) appsGrid.style.display = 'none';
var sectionTitle = this.shadowRoot.querySelector('#yn-services-label, .yn-section-title');
if (sectionTitle) sectionTitle.style.display = 'none';
}
}
}
} catch (e) {}
};
}
}).catch(function () {});
} catch (e) {}
};
}
})
.catch(function () {});
}
hookYakNetAccountComponent();
@@ -206,7 +213,7 @@ try {
if (!document.getElementById(iframeId)) {
var iframe = document.createElement('iframe');
iframe.id = iframeId;
iframe.src = 'https://auth.yakhub.com.tr/sdk/sso-frame';
iframe.src = 'https://developer-console.yakhub.com.tr/sdk/sso-frame';
iframe.title = 'YakNet Oturum Kontrolü';
iframe.setAttribute('aria-hidden', 'true');
iframe.tabIndex = -1;
@@ -225,7 +232,7 @@ try {
sessionStorage.removeItem('yaknet_manual_logout');
var callbackUrl = 'https://yaktube.yakhub.com.tr/plugins/peertube-plugin-auth-yaknet/router/auth-callback';
window.location.href =
'https://auth.yakhub.com.tr/oauth/authorize?client_id=01a03c41-f758-721e-b927-619bffde5c23&redirect_uri=' +
'https://developer-console.yakhub.com.tr/oauth/authorize?client_id=01a03c41-f758-721e-b927-619bffde5c23&redirect_uri=' +
encodeURIComponent(callbackUrl) +
'&response_type=code&scope=';
}
@@ -255,7 +262,7 @@ try {
}
});
// Global listener for YakNet SSO broadcast from auth.yakhub.com.tr
// Global listener for YakNet SSO broadcast from developer-console.yakhub.com.tr
window.addEventListener('yaknet-auth', function (e) {
if (e.detail && e.detail.authenticated && e.detail.user) {
var token = localStorage.getItem('access_token');
@@ -300,7 +307,8 @@ try {
sessionStorage.setItem('yaknet_manual_logout', 'true');
} catch (err) {}
window.location.replace(
'https://auth.yakhub.com.tr/sdk/logout?redirect_uri=' + encodeURIComponent('https://yaktube.yakhub.com.tr')
'https://developer-console.yakhub.com.tr/sdk/logout?redirect_uri=' +
encodeURIComponent('https://yaktube.yakhub.com.tr')
);
}
@@ -489,7 +497,7 @@ try {
'<yaknet-account ' +
'client-id="01a03c41-f758-721e-b927-619bffde5c23" ' +
'redirect-uri="https://yaktube.yakhub.com.tr/plugins/peertube-plugin-auth-yaknet/router/auth-callback" ' +
'base-url="https://auth.yakhub.com.tr" ' +
'base-url="https://developer-console.yakhub.com.tr" ' +
'login-url="/login" ' +
'authenticated="true" ' +
'user-name="' +
@@ -605,12 +613,12 @@ try {
'<p style="font-size: 13px; color: #94a3b8; margin-bottom: 16px; line-height: 1.45;">' +
'YouTube gibi tek bir YakNet hesabıyla güvenle giriş yapabilir, kendi video ve müzik kanallarınızı oluşturabilirsiniz.' +
'</p>' +
'<a href="https://auth.yakhub.com.tr/oauth/authorize?client_id=01a03c41-f758-721e-b927-619bffde5c23&redirect_uri=https%3A%2F%2Fyaktube.yakhub.com.tr%2Fplugins%2Fpeertube-plugin-auth-yaknet%2Frouter%2Fauth-callback&response_type=code&scope=" class="yaknet-sso-login-btn" aria-label="YakNet Hesabınız ile Tek Tıkla Giriş Yapın">' +
'<a href="https://developer-console.yakhub.com.tr/oauth/authorize?client_id=01a03c41-f758-721e-b927-619bffde5c23&redirect_uri=https%3A%2F%2Fyaktube.yakhub.com.tr%2Fplugins%2Fpeertube-plugin-auth-yaknet%2Frouter%2Fauth-callback&response_type=code&scope=" class="yaknet-sso-login-btn" aria-label="YakNet Hesabınız ile Tek Tıkla Giriş Yapın">' +
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>' +
'<span>YakNet ile Giriş Yap</span>' +
'</a>' +
'<div style="margin-top: 14px; font-size: 13px; color: #94a3b8;">' +
'YakNet hesabınız yok mu? <a href="https://auth.yakhub.com.tr/register" target="_blank" rel="noopener noreferrer" style="color: #ff8f37; font-weight: 600; text-decoration: underline;">YakNet Hesabı Oluştur</a>' +
'YakNet hesabınız yok mu? <a href="https://developer-console.yakhub.com.tr/register" target="_blank" rel="noopener noreferrer" style="color: #ff8f37; font-weight: 600; text-decoration: underline;">YakNet Hesabı Oluştur</a>' +
'</div>' +
'<div style="margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,0.08); font-size: 11.5px; color: #64748b; line-height: 1.45;">' +
'Giriş yaparak <a href="/about/instance" target="_blank" style="color: #94a3b8; text-decoration: underline;">Kullanım Koşulları</a>\'nı ve <a href="/about/instance" target="_blank" style="color: #94a3b8; text-decoration: underline;">Gizlilik Politikası</a>\'nı kabul etmiş sayılırsınız.' +
@@ -630,8 +638,7 @@ try {
var registerLinks = document.querySelectorAll('a[href*="/signup"], a[href*="/register"]');
registerLinks.forEach(function (l) {
l.href = 'https://auth.yakhub.com.tr/register';
l.target = '_blank';
l.href = 'https://developer-console.yakhub.com.tr/register';
l.innerText = 'YakNet Hesabı Oluştur';
});
@@ -1296,20 +1303,34 @@ try {
var header = document.createElement('div');
header.className = 'yaktube-feature-modal-header';
header.innerHTML = '<h3 class="yaktube-feature-modal-title"><span>⏱️</span> Uyku Zamanlayıcısı</h3>' +
header.innerHTML =
'<h3 class="yaktube-feature-modal-title"><span>⏱️</span> Uyku Zamanlayıcısı</h3>' +
'<button class="yaktube-feature-modal-close" aria-label="Kapat (Escape)">&times;</button>';
var body = document.createElement('div');
body.className = 'yaktube-feature-modal-body';
body.innerHTML = '<p class="yaktube-qr-desc">Videonun ne zaman durdurulacağını seçin. Süre bittiğinde ses yavaşça kısılarak oynatma durdurulur.</p>' +
body.innerHTML =
'<p class="yaktube-qr-desc">Videonun ne zaman durdurulacağını seçin. Süre bittiğinde ses yavaşça kısılarak oynatma durdurulur.</p>' +
'<div class="yaktube-timer-options">' +
'<button class="yaktube-timer-btn' + (sleepTimer.mode === '15' ? ' active' : '') + '" data-mins="15">15 Dakika</button>' +
'<button class="yaktube-timer-btn' + (sleepTimer.mode === '30' ? ' active' : '') + '" data-mins="30">30 Dakika</button>' +
'<button class="yaktube-timer-btn' + (sleepTimer.mode === '45' ? ' active' : '') + '" data-mins="45">45 Dakika</button>' +
'<button class="yaktube-timer-btn' + (sleepTimer.mode === '60' ? ' active' : '') + '" data-mins="60">60 Dakika</button>' +
'<button class="yaktube-timer-btn' +
(sleepTimer.mode === '15' ? ' active' : '') +
'" data-mins="15">15 Dakika</button>' +
'<button class="yaktube-timer-btn' +
(sleepTimer.mode === '30' ? ' active' : '') +
'" data-mins="30">30 Dakika</button>' +
'<button class="yaktube-timer-btn' +
(sleepTimer.mode === '45' ? ' active' : '') +
'" data-mins="45">45 Dakika</button>' +
'<button class="yaktube-timer-btn' +
(sleepTimer.mode === '60' ? ' active' : '') +
'" data-mins="60">60 Dakika</button>' +
'</div>' +
'<button class="yaktube-timer-btn' + (sleepTimer.mode === 'end' ? ' active' : '') + '" data-mins="end" style="width:100%;">🎬 Bu Video Bitince</button>' +
(sleepTimer.targetTime || sleepTimer.mode ? '<button id="yaktube-timer-cancel-btn" class="yaktube-timer-btn" style="background:#ef4444!important;color:#fff!important;border-color:#ef4444!important;">❌ Zamanlayıcıyı İptal Et</button>' : '');
'<button class="yaktube-timer-btn' +
(sleepTimer.mode === 'end' ? ' active' : '') +
'" data-mins="end" style="width:100%;">🎬 Bu Video Bitince</button>' +
(sleepTimer.targetTime || sleepTimer.mode
? '<button id="yaktube-timer-cancel-btn" class="yaktube-timer-btn" style="background:#ef4444!important;color:#fff!important;border-color:#ef4444!important;">❌ Zamanlayıcıyı İptal Et</button>'
: '');
card.appendChild(header);
card.appendChild(body);
@@ -1376,18 +1397,24 @@ try {
var header = document.createElement('div');
header.className = 'yaktube-feature-modal-header';
header.innerHTML = '<h3 class="yaktube-feature-modal-title"><span>📱</span> Telefonda Devam Et</h3>' +
header.innerHTML =
'<h3 class="yaktube-feature-modal-title"><span>📱</span> Telefonda Devam Et</h3>' +
'<button class="yaktube-feature-modal-close" aria-label="Kapat (Escape)">&times;</button>';
var formattedTime = formatClockTime(currentSec);
var qrImageUrl = 'https://api.qrserver.com/v1/create-qr-code/?size=220x220&margin=8&data=' + encodeURIComponent(targetUrl);
var qrImageUrl =
'https://api.qrserver.com/v1/create-qr-code/?size=220x220&margin=8&data=' + encodeURIComponent(targetUrl);
var body = document.createElement('div');
body.className = 'yaktube-feature-modal-body';
body.innerHTML =
'<p class="yaktube-qr-desc">Telefonunuzun kamerasıyla QR kodu okutarak videoyu kaldığınız yerden (<strong>' + formattedTime + '</strong>) izlemeye devam edebilirsiniz.</p>' +
'<p class="yaktube-qr-desc">Telefonunuzun kamerasıyla QR kodu okutarak videoyu kaldığınız yerden (<strong>' +
formattedTime +
'</strong>) izlemeye devam edebilirsiniz.</p>' +
'<div class="yaktube-qr-wrapper">' +
'<img src="' + qrImageUrl + '" alt="Video Bağlantısı QR Kodu" width="190" height="190" style="display:block;border-radius:8px;" />' +
'<img src="' +
qrImageUrl +
'" alt="Video Bağlantısı QR Kodu" width="190" height="190" style="display:block;border-radius:8px;" />' +
'</div>' +
'<button id="yaktube-qr-copy-action-btn" class="yaktube-qr-copy-btn">📋 Bağlantıyı Kopyala</button>';
@@ -1409,15 +1436,18 @@ try {
var copyBtn = body.querySelector('#yaktube-qr-copy-action-btn');
copyBtn.addEventListener('click', function () {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(targetUrl).then(function () {
copyBtn.textContent = '✅ Bağlantı Kopyalandı!';
announce('Bağlantı panoya kopyalandı: ' + targetUrl);
setTimeout(function () {
copyBtn.textContent = '📋 Bağlantıyı Kopyala';
}, 2500);
}).catch(function () {
fallbackCopy(targetUrl, copyBtn);
});
navigator.clipboard
.writeText(targetUrl)
.then(function () {
copyBtn.textContent = '✅ Bağlantı Kopyalandı!';
announce('Bağlantı panoya kopyalandı: ' + targetUrl);
setTimeout(function () {
copyBtn.textContent = '📋 Bağlantıyı Kopyala';
}, 2500);
})
.catch(function () {
fallbackCopy(targetUrl, copyBtn);
});
} else {
fallbackCopy(targetUrl, copyBtn);
}
@@ -1454,7 +1484,8 @@ try {
if (!existing) {
existing = document.createElement('div');
existing.className = 'yaktube-doubletap-overlay ' + className;
existing.innerHTML = '<div class="yaktube-ripple-content">' + (isLeft ? '⏪ 10sn Geri' : '10sn İleri ⏩') + '</div>';
existing.innerHTML =
'<div class="yaktube-ripple-content">' + (isLeft ? '⏪ 10sn Geri' : '10sn İleri ⏩') + '</div>';
container.appendChild(existing);
}
existing.classList.add('yaktube-ripple-active');
@@ -1466,7 +1497,8 @@ try {
function initTouchSeekGesture(video) {
if (!video) return;
var playerContainer = video.closest('.video-js, .player-container, .player, my-video-watch') || video.parentElement;
var playerContainer =
video.closest('.video-js, .player-container, .player, my-video-watch') || video.parentElement;
if (!playerContainer || playerContainer.hasAttribute('data-yaktube-touch-seek-hooked')) return;
playerContainer.setAttribute('data-yaktube-touch-seek-hooked', 'true');
@@ -1543,7 +1575,8 @@ try {
}
if (text === 'tam ekran' || text === 'büyük ekran' || text === 'tam ekran yap') {
var playerWrap = document.querySelector('.player-container, .video-player-container, my-video-watch .player') || video;
var playerWrap =
document.querySelector('.player-container, .video-player-container, my-video-watch .player') || video;
if (playerWrap) {
if (!document.fullscreenElement) {
if (playerWrap.requestFullscreen) playerWrap.requestFullscreen();
@@ -1979,49 +2012,72 @@ try {
}
function ensureFediverseBridge(query, currentSearchTarget) {
var searchMount = document.querySelector('my-search, my-search-results');
if (!searchMount) return;
var bridge = document.getElementById('yaktube-fediverse-bridge');
var ondemandContainer = document.getElementById('yaktube-ondemand-container');
var searchResult = searchMount.querySelector('.search-result');
if (!bridge) {
bridge = document.createElement('div');
bridge.id = 'yaktube-fediverse-bridge';
bridge.className = 'yaktube-fediverse-bridge';
bridge.setAttribute('role', 'region');
bridge.setAttribute('aria-label', 'Fediverse Video Arama Ağı ve Kapsam Seçimi');
}
var searchResult = document.querySelector('.search-result, my-search .search-result');
var ondemandContainer = document.getElementById('yaktube-ondemand-container');
if (searchResult && searchResult.parentNode) {
searchResult.parentNode.insertBefore(bridge, searchResult);
} else if (ondemandContainer && ondemandContainer.parentNode) {
ondemandContainer.parentNode.insertBefore(bridge, ondemandContainer.nextSibling);
} else {
var mainCol = document.querySelector('my-search, main, .main-col') || document.body;
mainCol.appendChild(bridge);
// Ensure bridge is always strictly inside searchMount
if (ondemandContainer && ondemandContainer.parentElement === searchMount) {
if (ondemandContainer.nextSibling !== bridge) {
searchMount.insertBefore(bridge, ondemandContainer.nextSibling);
}
} else if (searchResult && searchResult.parentElement === searchMount) {
if (bridge.nextSibling !== searchResult) {
searchMount.insertBefore(bridge, searchResult);
}
} else if (bridge.parentElement !== searchMount) {
searchMount.appendChild(bridge);
}
var isFediverse = currentSearchTarget === 'search-index';
bridge.innerHTML =
'<div class="yaktube-fediverse-bridge-content">' +
'<div class="yaktube-fediverse-bridge-left">' +
'<div class="yaktube-fediverse-bridge-badge-wrap">' +
'<span class="yaktube-fediverse-badge">🌐 Fediverse Ağı</span>' +
'<span class="yaktube-fediverse-status">' +
(isFediverse ? 'SepiaSearch Küresel Fediverse Arama Aktif' : escapeHtml(getInstanceName()) + ' Yerel Arama Aktif') +
'</span>' +
'</div>' +
'<h2 class="yaktube-fediverse-title">🌐 Fediverse & Küresel Ağ Arama Sonuçları</h2>' +
'<p class="yaktube-fediverse-sub">Merkeziyetsiz federe ağdaki (SepiaSearch ve bağımsız PeerTube sunucuları) video sonuçları aşağıda listelenmektedir.</p>' +
'</div>' +
'<div class="yaktube-scope-selector" role="tablist" aria-label="Arama Kapsamı Seçimi">' +
'<button type="button" id="yaktube-scope-global-btn" class="yaktube-scope-btn ' + (isFediverse ? 'active' : '') + '" role="tab" aria-selected="' + (isFediverse ? 'true' : 'false') + '" aria-label="Tüm Fediverse ve SepiaSearch ağındaki videoları ara" title="Tüm Fediverse genelinde ara">' +
'🌐 Tüm Fediverse (SepiaSearch)' +
'</button>' +
'<button type="button" id="yaktube-scope-local-btn" class="yaktube-scope-btn ' + (!isFediverse ? 'active' : '') + '" role="tab" aria-selected="' + (!isFediverse ? 'true' : 'false') + '" aria-label="Sadece ' + escapeHtml(getInstanceName()) + ' yerel sunucusundaki videoları ara" title="Sadece ' + escapeHtml(getInstanceName()) + ' yerel kütüphanesinde ara">' +
'🏠 Sadece ' + escapeHtml(getInstanceName()) + ' (Yerel)' +
'</button>' +
'</div>' +
'<div class="yaktube-fediverse-bridge-left">' +
'<div class="yaktube-fediverse-bridge-badge-wrap">' +
'<span class="yaktube-fediverse-badge">🌐 Fediverse Ağı</span>' +
'<span class="yaktube-fediverse-status">' +
(isFediverse
? 'SepiaSearch Küresel Fediverse Arama Aktif'
: escapeHtml(getInstanceName()) + ' Yerel Arama Aktif') +
'</span>' +
'</div>' +
'<h2 class="yaktube-fediverse-title">🌐 Fediverse & Küresel Ağ Arama Sonuçları</h2>' +
'<p class="yaktube-fediverse-sub">Merkeziyetsiz federe ağdaki (SepiaSearch ve bağımsız PeerTube sunucuları) video sonuçları aşağıda listelenmektedir.</p>' +
'</div>' +
'<div class="yaktube-scope-selector" role="tablist" aria-label="Arama Kapsamı Seçimi">' +
'<button type="button" id="yaktube-scope-global-btn" class="yaktube-scope-btn ' +
(isFediverse ? 'active' : '') +
'" role="tab" aria-selected="' +
(isFediverse ? 'true' : 'false') +
'" aria-label="Tüm Fediverse ve SepiaSearch ağındaki videoları ara" title="Tüm Fediverse genelinde ara">' +
'🌐 Tüm Fediverse (SepiaSearch)' +
'</button>' +
'<button type="button" id="yaktube-scope-local-btn" class="yaktube-scope-btn ' +
(!isFediverse ? 'active' : '') +
'" role="tab" aria-selected="' +
(!isFediverse ? 'true' : 'false') +
'" aria-label="Sadece ' +
escapeHtml(getInstanceName()) +
' yerel sunucusundaki videoları ara" title="Sadece ' +
escapeHtml(getInstanceName()) +
' yerel kütüphanesinde ara">' +
'🏠 Sadece ' +
escapeHtml(getInstanceName()) +
' (Yerel)' +
'</button>' +
'</div>' +
'</div>';
var globalBtn = document.getElementById('yaktube-scope-global-btn');
@@ -2150,8 +2206,8 @@ try {
'</div>' +
'</div>';
var mainMount =
document.querySelector('my-search, my-search-results, router-outlet, main, .main-col') || document.body;
var mainMount = document.querySelector('my-search, my-search-results, .main-col .main-row, .main-col, main');
if (!mainMount) mainMount = document.querySelector('.main-col');
if (mainMount && mainMount.firstChild) {
mainMount.insertBefore(liveContainer, mainMount.firstChild);
} else if (mainMount) {
@@ -2442,6 +2498,14 @@ try {
var query = searchParam.trim();
// Clean up any stray containers mistakenly attached directly to document.body
try {
var strays = document.querySelectorAll('body > #yaktube-ondemand-container, body > #yaktube-fediverse-bridge');
strays.forEach(function (s) {
s.remove();
});
} catch (e) {}
// Ensure Fediverse Global Search (SepiaSearch) is default target if not specified in URL
if (!url.searchParams.has('searchTarget')) {
url.searchParams.set('searchTarget', 'search-index');
@@ -2450,34 +2514,40 @@ try {
}
var currentSearchTarget = url.searchParams.get('searchTarget') || 'search-index';
// CRITICAL: We MUST wait for Angular to mount the search view (<my-search>)!
// If we inject before <my-search> exists, it lands in document.body before <my-app>,
// which pushes the entire site header, sidebar, and layout down the page.
var searchMount = document.querySelector('my-search, my-search-results');
if (!searchMount) {
return;
}
var queryKey = query + '___' + currentSearchTarget;
var lastQueryKey = lastQuery + '___' + lastSearchTarget;
var container = document.getElementById('yaktube-ondemand-container');
var nativeResults = searchMount.querySelector('.search-result');
if (queryKey === lastQueryKey) {
var existingBridge = document.getElementById('yaktube-fediverse-bridge');
if (!existingBridge && document.querySelector('my-search')) {
ensureFediverseBridge(query, currentSearchTarget);
if (container && container.parentElement !== searchMount) {
searchMount.insertBefore(container, nativeResults || searchMount.firstChild);
}
ensureFediverseBridge(query, currentSearchTarget);
return;
}
lastQuery = query;
lastSearchTarget = currentSearchTarget;
var container = document.getElementById('yaktube-ondemand-container');
if (!container) {
container = document.createElement('div');
container.id = 'yaktube-ondemand-container';
container.className = 'yaktube-ondemand-section';
container.setAttribute('role', 'region');
container.setAttribute('aria-label', 'Canlı YouTube ve ' + getInstanceName() + ' Arama Sonuçları');
var mainContent =
document.querySelector('my-search, my-search-results, router-outlet, main, .main-col') || document.body;
if (mainContent && mainContent.firstChild) {
mainContent.insertBefore(container, mainContent.firstChild);
} else if (mainContent) {
mainContent.appendChild(container);
}
searchMount.insertBefore(container, nativeResults || searchMount.firstChild);
} else if (container.parentElement !== searchMount) {
searchMount.insertBefore(container, nativeResults || searchMount.firstChild);
}
container.innerHTML =
@@ -2494,7 +2564,9 @@ try {
'</div>' +
'<div class="yaktube-loading">' +
'<div class="yaktube-spinner" aria-hidden="true"></div>' +
'<div style="margin-top: 10px;">YouTube ve ' + escapeHtml(getInstanceName()) + ' yerel kütüphanesindeki eşleşmeler taranıyor...</div>' +
'<div style="margin-top: 10px;">YouTube ve ' +
escapeHtml(getInstanceName()) +
' yerel kütüphanesindeki eşleşmeler taranıyor...</div>' +
'</div>';
var shortcutsBtn = document.getElementById('yaktube-open-shortcuts');
@@ -2607,7 +2679,7 @@ try {
statusBadge =
'<span class="yaktube-badge" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); margin-bottom: 6px; display: inline-block;">✅ ' +
escapeHtml(getInstanceName()) +
'\'da Mevcut</span>';
"'da Mevcut</span>";
}
var actionButton = '';
@@ -2626,9 +2698,11 @@ try {
escapeHtml(item.localVideo.url) +
'" class="yaktube-play-btn" aria-label="' +
escapeHtml(item.title) +
' videosunu ' + escapeHtml(getInstanceName()) + '\'dan hemen izle">▶️ ' +
' videosunu ' +
escapeHtml(getInstanceName()) +
'\'dan İzle</a>';
'\'dan hemen izle">▶️ ' +
escapeHtml(getInstanceName()) +
"'dan İzle</a>";
} else {
actionButton =
'<button class="yaktube-import-btn" data-url="' +
@@ -2641,10 +2715,10 @@ try {
escapeHtml(getInstanceName()) +
'\'a aktar ve izle">📥 ' +
escapeHtml(getInstanceName()) +
'\'a Aktar & İzle</button>';
"'a Aktar & İzle</button>";
}
var durationText = isLive ? 'CANLI' : (item.durationFormatted || formatClockTime(item.duration));
var durationText = isLive ? 'CANLI' : item.durationFormatted || formatClockTime(item.duration);
var cardLabel =
item.title +
(isLive ? ' (Canlı Yayın)' : isLocal ? ' (' + getInstanceName() + ' kütüphanenizde mevcut)' : '') +
@@ -2705,20 +2779,34 @@ try {
if (localResults.length > 0) {
var localCardsHtml = '';
localResults.forEach(function (lItem) {
var lThumb = lItem.thumbnailPath || (lItem.thumbnails && lItem.thumbnails[0] ? lItem.thumbnails[0].fileUrl : '/client/assets/images/default-thumbnail.jpg');
var lThumb =
lItem.thumbnailPath ||
(lItem.thumbnails && lItem.thumbnails[0]
? lItem.thumbnails[0].fileUrl
: '/client/assets/images/default-thumbnail.jpg');
var lDuration = formatClockTime(lItem.duration);
var lChannel = (lItem.channel && (lItem.channel.displayName || lItem.channel.name)) ||
(lItem.account && (lItem.account.displayName || lItem.account.name)) ||
getInstanceName();
var lWatchUrl = lItem.url || ('/videos/watch/' + (lItem.shortUUID || lItem.uuid));
var lChannel =
(lItem.channel && (lItem.channel.displayName || lItem.channel.name)) ||
(lItem.account && (lItem.account.displayName || lItem.account.name)) ||
getInstanceName();
var lWatchUrl = lItem.url || '/videos/watch/' + (lItem.shortUUID || lItem.uuid);
var lViews = (lItem.views || 0) + ' görüntüleme';
var lLabel = lItem.name + ', ' + lChannel + ', ' + getInstanceName() + ' yerel sunucusunda mevcut, Süre: ' + lDuration;
var lLabel =
lItem.name +
', ' +
lChannel +
', ' +
getInstanceName() +
' yerel sunucusunda mevcut, Süre: ' +
lDuration;
localCardsHtml +=
'<div class="yaktube-card yaktube-local-card" role="article" tabindex="0" aria-label="' +
escapeHtml(lLabel) +
'">' +
'<a href="' + escapeHtml(lWatchUrl) + '" style="text-decoration:none; color:inherit; display:flex; flex-direction:column; height:100%;">' +
'<a href="' +
escapeHtml(lWatchUrl) +
'" style="text-decoration:none; color:inherit; display:flex; flex-direction:column; height:100%;">' +
'<div class="yaktube-thumb-wrap">' +
'<img class="yaktube-thumb-img" src="' +
escapeHtml(lThumb) +
@@ -2731,30 +2819,42 @@ try {
'</div>' +
'<div class="yaktube-info">' +
'<div>' +
'<span class="yaktube-badge" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); margin-bottom: 6px; display: inline-block;">✅ ' + escapeHtml(getInstanceName()) + '\'da Mevcut</span>' +
'<span class="yaktube-badge" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); margin-bottom: 6px; display: inline-block;">✅ ' +
escapeHtml(getInstanceName()) +
"'da Mevcut</span>" +
'<h3 class="yaktube-video-name" title="' +
escapeHtml(lItem.name) +
'" style="margin:0; font-size:13px; font-weight:600; line-height:1.35;">' +
escapeHtml(lItem.name) +
'</h3>' +
'<div class="yaktube-channel-name">' +
escapeHtml(lChannel) + ' • ' + escapeHtml(lViews) +
escapeHtml(lChannel) +
' • ' +
escapeHtml(lViews) +
'</div>' +
'</div>' +
'<div class="yaktube-play-btn" style="margin-top:8px;">▶️ ' + escapeHtml(getInstanceName()) + '\'dan Hemen İzle</div>' +
'<div class="yaktube-play-btn" style="margin-top:8px;">▶️ ' +
escapeHtml(getInstanceName()) +
"'dan Hemen İzle</div>" +
'</div>' +
'</a>' +
'</div>';
});
localShelfHtml =
'<div id="yaktube-local-shelf" class="yaktube-local-shelf" role="region" aria-label="' + escapeHtml(getInstanceName()) + ' Yerel Kütüphanesi">' +
'<div id="yaktube-local-shelf" class="yaktube-local-shelf" role="region" aria-label="' +
escapeHtml(getInstanceName()) +
' Yerel Kütüphanesi">' +
'<div class="yaktube-header" style="margin-top: 24px; border-bottom-color: rgba(16, 185, 129, 0.3);">' +
'<div class="yaktube-header-left">' +
'<span class="yaktube-badge" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%);">✅ Yerel Kütüphane</span>' +
'<h2 class="yaktube-title-h3" style="margin:0; font-size:1.15rem;">"' +
escapeHtml(query) +
'" için ' + escapeHtml(getInstanceName()) + ' Sunucusunda ' + localTotal + ' Video Bulundu</h2>' +
'" için ' +
escapeHtml(getInstanceName()) +
' Sunucusunda ' +
localTotal +
' Video Bulundu</h2>' +
'</div>' +
'<span class="yaktube-local-shelf-sub">Doğrudan sunucumuzda barındırılan, yüksek hızlı ve anında izlenebilen videolar</span>' +
'</div>' +
@@ -2895,7 +2995,7 @@ try {
if (email) headers['X-User-Email'] = email;
if (username) headers['X-User-Username'] = username;
var authUrl = 'https://auth.yakhub.com.tr/api/yaktube/search-history' + (queryParams || '');
var authUrl = 'https://developer-console.yakhub.com.tr/api/yaktube/search-history' + (queryParams || '');
var bridgeUrl = '/api-custom/search-history' + (queryParams || '');
var options = {
@@ -3350,7 +3450,8 @@ try {
announce('"' + transcript + '" için arama başlatılıyor...', true);
setTimeout(function () {
closeFullSearchModal();
window.location.href = '/search?search=' + encodeURIComponent(transcript) + '&searchTarget=search-index';
window.location.href =
'/search?search=' + encodeURIComponent(transcript) + '&searchTarget=search-index';
}, 500);
}
}
+2 -8
View File
@@ -27,13 +27,7 @@ function resolveYtDlpPath(logger) {
path.join(process.cwd(), 'bin', 'yt-dlp.exe'),
'yt-dlp.exe'
]
: [
'/usr/local/bin/yt-dlp',
'/usr/bin/yt-dlp',
'/bin/yt-dlp',
path.join(process.cwd(), 'bin', 'yt-dlp'),
'yt-dlp'
];
: ['/usr/local/bin/yt-dlp', '/usr/bin/yt-dlp', '/bin/yt-dlp', path.join(process.cwd(), 'bin', 'yt-dlp'), 'yt-dlp'];
for (const candidate of candidates) {
try {
@@ -64,7 +58,7 @@ async function getDefaultChannelId(category) {
return cachedChannels.defaultId || '1146';
}
return new Promise((resolve) => {
return new Promise(resolve => {
const req = http.request(
{
hostname: '127.0.0.1',
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "peertube-plugin-yaktube-ondemand",
"version": "1.5.0",
"version": "1.5.2",
"description": "Accessible On-Demand YouTube Import, Live Streams, Smart Recommendations, Sleep Timer, Touch Gestures, Voice Assistant & A11y Engine for PeerTube",
"main": "main.js",
"library": "./main.js",
@@ -43,7 +43,7 @@
"author": "Enes Yakıştır <[email protected]>",
"repository": {
"type": "git",
"url": "https://github.com/yakistir98/peertube-plugin-yaktube-ondemand.git"
"url": "git+https://github.com/yakistir98/peertube-plugin-yaktube-ondemand.git"
},
"homepage": "https://yaktube.yakhub.com.tr",
"bugs": "https://github.com/yakistir98/peertube-plugin-yaktube-ondemand/issues",
+21 -7
View File
@@ -1151,9 +1151,18 @@ body:has(#yaktube-ondemand-container) my-error-page {
}
@keyframes yaktube-ripple-bounce {
0% { transform: scale(0.7); opacity: 0.5; }
50% { transform: scale(1.1); opacity: 1; }
100% { transform: scale(1); opacity: 1; }
0% {
transform: scale(0.7);
opacity: 0.5;
}
50% {
transform: scale(1.1);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
/* -------------------------------------------------------------------------- */
@@ -1285,9 +1294,15 @@ body:has(#yaktube-ondemand-container) my-error-page {
}
@keyframes yaktube-pulse {
0% { transform: scale(1); }
50% { transform: scale(1.04); }
100% { transform: scale(1); }
0% {
transform: scale(1);
}
50% {
transform: scale(1.04);
}
100% {
transform: scale(1);
}
}
.yaktube-qr-wrapper {
@@ -1339,4 +1354,3 @@ body:has(#yaktube-ondemand-container) my-error-page {
box-shadow: 0 6px 20px rgba(255, 143, 55, 0.4) !important;
outline: none !important;
}