' +
- '

' +
- '
' +
- durationText +
- '' +
+ if (ytCount > 0) {
+ var countText = ytCount === 1 ? '1 Video Bulundu' : ytCount + ' Video Bulundu';
+ ytHeaderHtml =
+ '';
- });
-
- var loadMoreHtml = '';
- if (visibleCount < count) {
- loadMoreHtml =
- '
' +
- '
';
+
+ var visibleResults = uniqueYtResults.slice(0, visibleYtCount);
+ visibleResults.forEach(function (item) {
+ var isLocal = !!item.isDownloaded;
+ var isLive = !!item.isLive;
+
+ var statusBadge = '';
+ if (isLive) {
+ statusBadge =
+ '
🔴 CANLI YAYIN';
+ } else if (isLocal) {
+ statusBadge =
+ '
✅ ' +
+ escapeHtml(getInstanceName()) +
+ '\'da Mevcut';
+ }
+
+ var actionButton = '';
+ if (isLive) {
+ actionButton =
+ '
🔴 Canlı Yayını İzle';
+ } else if (isLocal && item.localVideo && item.localVideo.url) {
+ actionButton =
+ '
▶️ ' +
+ escapeHtml(getInstanceName()) +
+ '\'dan İzle';
+ } else {
+ actionButton =
+ '
📥 ' +
+ escapeHtml(getInstanceName()) +
+ '\'a Aktar & İzle';
+ }
+
+ var durationText = isLive ? 'CANLI' : (item.durationFormatted || formatClockTime(item.duration));
+ var cardLabel =
+ item.title +
+ (isLive ? ' (Canlı Yayın)' : isLocal ? ' (' + getInstanceName() + ' kütüphanenizde mevcut)' : '') +
+ ', ' +
+ item.channel +
+ ' kanalı, Süre: ' +
+ durationText;
+
+ ytCardsHtml +=
+ '
' +
+ '
' +
+ '
 +
+ ')
' +
+ '
' +
+ escapeHtml(durationText) +
+ '' +
+ '
' +
+ '
' +
+ '
' +
+ statusBadge +
+ '
' +
+ escapeHtml(item.title) +
+ '
' +
+ '
' +
+ escapeHtml(item.channel) +
+ '
' +
+ '
' +
+ actionButton +
+ '
' +
+ '
';
+ });
+
+ if (visibleYtCount < ytCount) {
+ ytLoadMoreHtml =
+ '
' +
+ '' +
+ '➕ Daha Fazla Video Göster (' +
+ visibleYtCount +
+ ' / ' +
+ ytCount +
+ ')' +
+ '' +
+ '
';
+ }
+ }
+
+ // 2. Local Videos Shelf
+ var localShelfHtml = '';
+ 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 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 lViews = (lItem.views || 0) + ' görüntüleme';
+ var lLabel = lItem.name + ', ' + lChannel + ', YakTube yerel sunucusunda mevcut, Süre: ' + lDuration;
+
+ localCardsHtml +=
+ '
';
+ });
+
+ localShelfHtml =
+ '
' +
+ '' +
+ '
' +
+ localCardsHtml +
+ '
' +
+ '
';
}
container.innerHTML =
- '' +
- '
' +
- cardsHtml +
- '
' +
- loadMoreHtml;
+ ytHeaderHtml +
+ (ytCount > 0 ? '
' + ytCardsHtml + '
' : '') +
+ ytLoadMoreHtml +
+ localShelfHtml;
var sBtn = document.getElementById('yaktube-open-shortcuts');
if (sBtn) {
@@ -1927,9 +2157,9 @@ try {
var loadMoreBtn = document.getElementById('yaktube-load-more-btn');
if (loadMoreBtn) {
loadMoreBtn.addEventListener('click', function () {
- visibleCount = Math.min(visibleCount + 6, count);
- render();
- announce(visibleCount + ' adet video gösteriliyor.');
+ visibleYtCount = Math.min(visibleYtCount + 6, ytCount);
+ renderAll();
+ announce(visibleYtCount + ' adet video gösteriliyor.');
});
}
@@ -1950,7 +2180,17 @@ try {
});
}
- render();
+ renderAll();
+
+ var announceMsg = '"' + query + '" için arama sonuçları listelendi: ';
+ if (localTotal > 0) {
+ announceMsg += localTotal + ' adet yerel ' + getInstanceName() + ' videosu, ';
+ }
+ if (ytCount > 0) {
+ announceMsg += ytCount + ' adet YouTube sonucu ve ';
+ }
+ announceMsg += 'Fediverse sonuçları hazır.';
+ announce(announceMsg);
}
})
.catch(function (err) {
@@ -1958,14 +2198,15 @@ try {
container.innerHTML =
'';
- announce('Arama s\u0131ras\u0131nda bir ba\u011flant\u0131 sorunu olu\u015ftu.');
+ announce('Arama sırasında bir bağlantı sorunu oluştu.');
})
.finally(function () {
isSearching = false;
+ ensureFediverseBridge(query, currentSearchTarget);
});
}
@@ -2353,7 +2594,7 @@ try {
saveRecentSearch(q);
announce('"' + q + '" için arama yapılıyor...', true);
closeFullSearchModal();
- window.location.href = '/search?search=' + encodeURIComponent(q);
+ window.location.href = '/search?search=' + encodeURIComponent(q) + '&searchTarget=search-index';
}
}
window.__yaktube_execute_search__ = executeSearch;
@@ -2485,7 +2726,7 @@ try {
announce('"' + transcript + '" için arama başlatılıyor...', true);
setTimeout(function () {
closeFullSearchModal();
- window.location.href = '/search?search=' + encodeURIComponent(transcript);
+ window.location.href = '/search?search=' + encodeURIComponent(transcript) + '&searchTarget=search-index';
}, 500);
}
}
diff --git a/package.json b/package.json
index 1a61662..45753ef 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "peertube-plugin-yaktube-ondemand",
- "version": "1.4.28",
+ "version": "1.4.29",
"description": "Accessible On-Demand YouTube Import, Live Streams, Smart Recommendations and A11y Engine for PeerTube",
"main": "main.js",
"library": "./main.js",
diff --git a/style.css b/style.css
index 5cbda54..7c25035 100644
--- a/style.css
+++ b/style.css
@@ -960,3 +960,140 @@ body:has(#yaktube-ondemand-container) my-error-page {
height: 0 !important;
overflow: hidden !important;
}
+
+/* -------------------------------------------------------------------------- */
+/* YakTube Local Video Shelf & Highlights (v1.4.29) */
+/* -------------------------------------------------------------------------- */
+.yaktube-local-shelf {
+ margin-top: 24px;
+ padding-top: 20px;
+ border-top: 1px solid rgba(16, 185, 129, 0.25);
+}
+
+.yaktube-local-shelf-sub {
+ font-size: 12px;
+ color: #a7f3d0;
+ margin-top: 4px;
+ display: block;
+}
+
+.yaktube-local-card {
+ border-color: rgba(16, 185, 129, 0.35) !important;
+}
+
+.yaktube-local-card:hover,
+.yaktube-local-card:focus-within {
+ border-color: #10b981 !important;
+ box-shadow: 0 10px 22px rgba(16, 185, 129, 0.22) !important;
+}
+
+/* -------------------------------------------------------------------------- */
+/* YakTube Fediverse Bridge & Scope Selector (v1.4.29) */
+/* -------------------------------------------------------------------------- */
+.yaktube-fediverse-bridge {
+ margin: 28px 0 16px 0;
+ padding: 16px 20px;
+ background: linear-gradient(135deg, rgba(30, 27, 75, 0.85) 0%, rgba(15, 23, 42, 0.9) 100%);
+ border: 1px solid rgba(99, 102, 241, 0.4);
+ border-radius: 14px;
+ backdrop-filter: blur(12px);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
+ color: #ffffff;
+}
+
+.yaktube-fediverse-bridge-content {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ flex-wrap: wrap;
+ gap: 16px;
+}
+
+.yaktube-fediverse-bridge-left {
+ flex: 1 1 320px;
+}
+
+.yaktube-fediverse-bridge-badge-wrap {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 6px;
+}
+
+.yaktube-fediverse-badge {
+ background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
+ color: #fff;
+ font-size: 11px;
+ font-weight: 700;
+ padding: 3px 9px;
+ border-radius: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.yaktube-fediverse-status {
+ font-size: 12px;
+ font-weight: 600;
+ color: #a5b4fc;
+}
+
+.yaktube-fediverse-title {
+ margin: 0;
+ font-size: 1.15rem;
+ font-weight: 700;
+ color: #ffffff;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.yaktube-fediverse-sub {
+ margin: 4px 0 0 0;
+ font-size: 12px;
+ color: #94a3b8;
+ line-height: 1.4;
+}
+
+.yaktube-scope-selector {
+ display: inline-flex;
+ align-items: center;
+ background: rgba(15, 23, 42, 0.75);
+ border: 1px solid rgba(255, 255, 255, 0.15);
+ border-radius: 10px;
+ padding: 4px;
+ gap: 4px;
+}
+
+.yaktube-scope-btn {
+ background: transparent;
+ border: 1px solid transparent;
+ color: #94a3b8;
+ padding: 8px 16px;
+ font-size: 13px;
+ font-weight: 600;
+ border-radius: 8px;
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ transition: all 0.2s ease;
+}
+
+.yaktube-scope-btn:hover {
+ color: #ffffff;
+ background: rgba(255, 255, 255, 0.08);
+}
+
+.yaktube-scope-btn.active {
+ background: linear-gradient(135deg, #ff8f37 0%, #ff5e3a 100%);
+ color: #ffffff;
+ border-color: rgba(255, 143, 55, 0.4);
+ box-shadow: 0 2px 8px rgba(255, 143, 55, 0.35);
+ font-weight: 700;
+}
+
+.yaktube-scope-btn:focus-visible {
+ outline: 2px solid #ff8f37;
+ outline-offset: 2px;
+}