Spaces:
Running
Running
feat(wall): FPT player opens scrollable feed interleaved with Short AI in newest-first order
Browse files- static/app_v2.js +103 -20
static/app_v2.js
CHANGED
|
@@ -618,30 +618,113 @@ function _renderYTFeedInWall(){
|
|
| 618 |
function openYTEmbedFeed(videoId, title){
|
| 619 |
// Open a YouTube embed in the SAME TikTok-style viewer used by Short AI
|
| 620 |
// (buildTikTokSlide + initTikTokFeed) — 100% match with Short AI player.
|
|
|
|
|
|
|
|
|
|
| 621 |
showView('view-tiktok');
|
| 622 |
var el = document.getElementById('view-tiktok');
|
| 623 |
if(!el){ return; }
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 630 |
var h = '<button class="back-btn" onclick="switchCat(\'home\')">← Tường AI</button>'
|
| 631 |
-
+ '<div class="tiktok-container"><div class="tiktok-feed" id="tiktok-feed">'
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 645 |
el.innerHTML = h;
|
| 646 |
setTimeout(function(){ initTikTokFeed(); }, 200);
|
| 647 |
}
|
|
|
|
| 618 |
function openYTEmbedFeed(videoId, title){
|
| 619 |
// Open a YouTube embed in the SAME TikTok-style viewer used by Short AI
|
| 620 |
// (buildTikTokSlide + initTikTokFeed) — 100% match with Short AI player.
|
| 621 |
+
// Builds a SCROLLABLE feed that starts at this FPT video and lets the user
|
| 622 |
+
// swipe UP/DOWN to browse older FPT videos interleaved with Short AI content,
|
| 623 |
+
// in newest-first order.
|
| 624 |
showView('view-tiktok');
|
| 625 |
var el = document.getElementById('view-tiktok');
|
| 626 |
if(!el){ return; }
|
| 627 |
+
|
| 628 |
+
function _fptTs(v){
|
| 629 |
+
if(v && v.published){
|
| 630 |
+
var d = new Date(v.published);
|
| 631 |
+
if(!isNaN(d.getTime())) return d.getTime();
|
| 632 |
+
}
|
| 633 |
+
return 0;
|
| 634 |
+
}
|
| 635 |
+
|
| 636 |
+
// 1) Gather all playable items: FPT wall videos + Short AI posts (newest first)
|
| 637 |
+
var items = [];
|
| 638 |
+
var seenFpt = {};
|
| 639 |
+
function pushFpt(v){
|
| 640 |
+
if(!v) return;
|
| 641 |
+
var vid = v.videoId || v.id;
|
| 642 |
+
if(!vid || seenFpt[vid]) return;
|
| 643 |
+
seenFpt[vid] = 1;
|
| 644 |
+
items.push({
|
| 645 |
+
kind:'fpt',
|
| 646 |
+
videoId: vid,
|
| 647 |
+
title: v.title || 'Video',
|
| 648 |
+
img: v.img || 'https://i.ytimg.com/vi/' + vid + '/hqdefault.jpg',
|
| 649 |
+
ts: _fptTs(v)
|
| 650 |
+
});
|
| 651 |
+
}
|
| 652 |
+
(_ytFeedVideos||[]).forEach(pushFpt);
|
| 653 |
+
(_fptVideos||[]).forEach(pushFpt);
|
| 654 |
+
(_wallPosts||[]).forEach(function(p){
|
| 655 |
+
if(!p || !p.video) return;
|
| 656 |
+
var ts = parseInt(p.created||'0',10);
|
| 657 |
+
if(isNaN(ts) || !ts){ var d = new Date(p.created_str||''); ts = isNaN(d.getTime()) ? 0 : d.getTime(); }
|
| 658 |
+
items.push({
|
| 659 |
+
kind:'ai',
|
| 660 |
+
videoId: p.id || ('ai-' + items.length),
|
| 661 |
+
postId: p.id || '',
|
| 662 |
+
title: p.title || 'Video',
|
| 663 |
+
img: p.short_thumb || p.img || '',
|
| 664 |
+
text: (p.text && p.text !== p.title ? p.text : '').slice(0,400),
|
| 665 |
+
video: p.video,
|
| 666 |
+
ts: ts
|
| 667 |
+
});
|
| 668 |
+
});
|
| 669 |
+
|
| 670 |
+
// 2) Sort newest-first, then rotate so the clicked FPT video is first
|
| 671 |
+
items.sort(function(a,b){ return (b.ts||0) - (a.ts||0); });
|
| 672 |
+
var start = 0;
|
| 673 |
+
for(var i=0;i<items.length;i++){
|
| 674 |
+
if(items[i].kind==='fpt' && String(items[i].videoId)===String(videoId)){ start=i; break; }
|
| 675 |
+
}
|
| 676 |
+
var ordered = items.slice(start).concat(items.slice(0,start));
|
| 677 |
+
if(!ordered.length){
|
| 678 |
+
ordered = [{kind:'fpt', videoId:videoId, title:title||'Video', img:'https://i.ytimg.com/vi/'+videoId+'/hqdefault.jpg', ts:0}];
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
function fptVtag(it){
|
| 682 |
+
var emb = 'https://www.youtube.com/embed/' + esc(it.videoId) + '?autoplay=1&rel=0&enablejsapi=1';
|
| 683 |
+
return '<div class="yt-thumb-wrap" style="background-image:url(\'' + esc(it.img) + '\')">'
|
| 684 |
+
+ '<iframe data-yt-src="' + emb + '" allowfullscreen '
|
| 685 |
+
+ 'allow="accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture" '
|
| 686 |
+
+ 'referrerpolicy="strict-origin-when-cross-origin"></iframe></div>';
|
| 687 |
+
}
|
| 688 |
+
function aiVtag(it){
|
| 689 |
+
var isYT = /youtube\.com\/embed|youtu\.be\/|youtube-nocookie|tiktok\.com\/embed|facebook\.com\/plugins|instagram\.com\/p\/.*\/embed|platform\.twitter\.com|player\.vimeo\.com/.test(it.video||'');
|
| 690 |
+
if(!it.video) return '';
|
| 691 |
+
return isYT
|
| 692 |
+
? '<div class="yt-thumb-wrap" style="background-image:url(\'' + esc(it.img) + '\')"><iframe data-yt-src="' + esc(it.video) + '" allowfullscreen allow="accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture" referrerpolicy="strict-origin-when-cross-origin"></iframe></div>'
|
| 693 |
+
: '<video playsinline preload="none"' + (it.img ? ' poster="' + esc(it.img) + '"' : '') + ' src="' + esc(it.video) + '" loop></video>';
|
| 694 |
+
}
|
| 695 |
+
|
| 696 |
var h = '<button class="back-btn" onclick="switchCat(\'home\')">← Tường AI</button>'
|
| 697 |
+
+ '<div class="tiktok-container"><div class="tiktok-feed" id="tiktok-feed">';
|
| 698 |
+
ordered.forEach(function(it, idx){
|
| 699 |
+
var vtag, badge, badgeClass, shareUrl, postId, desc, extraBtn;
|
| 700 |
+
if(it.kind === 'fpt'){
|
| 701 |
+
vtag = fptVtag(it);
|
| 702 |
+
badge = 'FPT Play'; badgeClass = 'badge-fpt';
|
| 703 |
+
shareUrl = 'https://www.youtube.com/watch?v=' + it.videoId;
|
| 704 |
+
postId = ''; desc = ''; extraBtn = '';
|
| 705 |
+
} else {
|
| 706 |
+
vtag = aiVtag(it);
|
| 707 |
+
badge = 'Short AI'; badgeClass = 'badge-ai';
|
| 708 |
+
shareUrl = it.video || '';
|
| 709 |
+
postId = it.postId || '';
|
| 710 |
+
desc = it.text || '';
|
| 711 |
+
extraBtn = '<button class="tiktok-right-btn" onclick="event.stopPropagation();shareVideoToApps(\'' + esc(it.video) + '\',\'' + esc(it.title) + '\')"><div class="icon">📥</div></button>';
|
| 712 |
+
}
|
| 713 |
+
h += buildTikTokSlide({
|
| 714 |
+
vtag: vtag,
|
| 715 |
+
title: it.title,
|
| 716 |
+
badge: badge,
|
| 717 |
+
badgeClass: badgeClass,
|
| 718 |
+
videoId: it.videoId + '-feed-' + String(idx),
|
| 719 |
+
idx: idx,
|
| 720 |
+
total: ordered.length,
|
| 721 |
+
shareUrl: shareUrl,
|
| 722 |
+
postId: postId,
|
| 723 |
+
desc: desc,
|
| 724 |
+
extraBtn: extraBtn || ''
|
| 725 |
+
});
|
| 726 |
+
});
|
| 727 |
+
h += '</div></div>';
|
| 728 |
el.innerHTML = h;
|
| 729 |
setTimeout(function(){ initTikTokFeed(); }, 200);
|
| 730 |
}
|