Repository navigation
Expand file tree
/
Copy pathvideos.html
More file actions
374 lines (343 loc) · 23.1 KB
/
Copy pathvideos.html
File metadata and controls
374 lines (343 loc) · 23.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
---
layout: default
title: Videos
permalink: /gallery/videos/
body_class: videos-page
description: "Curated videos from YouTube, TikTok, Instagram, and Twitter. Explore carefully selected video content covering technology, AI, space, entertainment, and more from Richard Djarbeng's collection."
---
<div class="videos-page-shell">
<aside class="video-filter-rail" id="video-filter-rail" aria-label="Video source filters">
<div class="video-filter-rail-header">Source</div>
<div class="video-filter-rail-actions" id="source-filter-list">
{% assign is_all_active = false %}
{% if page.url contains '/gallery/videos/' %}
{% unless page.url contains '/videos/youtube/' or page.url contains '/videos/tiktok/' or page.url contains '/videos/instagram/' or page.url contains '/videos/twitter/' %}
{% assign is_all_active = true %}
{% endunless %}
{% endif %}
<a href="/gallery/videos/" class="vid-source-btn {% if is_all_active %}active{% endif %}">
<svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" stroke-width="2" fill="none"/></svg>
<span>All</span>
</a>
<a href="/gallery/videos/youtube/" class="vid-source-btn {% if page.url contains '/videos/youtube/' %}active{% endif %}">
<svg viewBox="0 0 24 24"><path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z" fill="currentColor"/></svg>
<span>YouTube</span>
</a>
<a href="/gallery/videos/tiktok/" class="vid-source-btn {% if page.url contains '/videos/tiktok/' %}active{% endif %}">
<svg viewBox="0 0 24 24"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.06-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.9-.32-1.98-.23-2.81.33-.85.51-1.33 1.47-1.3 2.46.02.79.39 1.54 1.03 2.03.61.47 1.38.64 2.14.6.9-.06 1.76-.59 2.21-1.36.27-.4.39-.88.39-1.37.02-4.66.01-9.33.02-14z" fill="currentColor"/></svg>
<span>TikTok</span>
</a>
<a href="/gallery/videos/instagram/" class="vid-source-btn {% if page.url contains '/videos/instagram/' %}active{% endif %}">
<svg viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" fill="currentColor"/></svg>
<span>Instagram</span>
</a>
<a href="/gallery/videos/twitter/" class="vid-source-btn {% if page.url contains '/videos/twitter/' %}active{% endif %}">
<svg viewBox="0 0 24 24"><path d="M23.953 4.57c-.885.392-1.83.656-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z" fill="currentColor"/></svg>
<span>Twitter</span>
</a>
</div>
</aside>
<div class="videos-grid-area">
<div class="sticky-filter-stack">
<div class="genre-filter-row" id="genre-filter-scroll">
<a href="/gallery/videos/" class="genre-chip {% if page.url == '/gallery/videos/' %}active{% endif %}">All</a>
{% assign genres = site.gallery | where: "type", "video" | map: "genre" | uniq | compact | sort %}
{% for genre in genres %}
{% if genre != nil and genre != "" %}
{% assign genre_slug = genre | slugify %}
<a href="{{ '/gallery/videos/' | append: genre_slug | append: '/' | relative_url }}" class="genre-chip {% if page.url contains genre_slug %}active{% endif %}">{{ genre }}</a>
{% endif %}
{% endfor %}
</div>
{% assign vids_pager = custom_pager | default: page.custom_pager %}
{% assign show_collections = true %}
{% if vids_pager and vids_pager.current_page > 1 %}
{% assign show_collections = false %}
{% endif %}
{% if show_collections and site.video_collections %}
<div class="video-groups-container" id="video-groups-container" style="margin-top: 1rem;">
<div class="video-groups-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
<h2 class="video-groups-title" style="font-size: 1.5rem; margin: 0;">Browse by Collection</h2>
<button class="video-groups-toggle" id="video-groups-toggle" aria-expanded="true" style="background: none; border: none; color: var(--text-color); cursor: pointer; font-size: 0.9rem; font-weight: 500;">
Hide collections ⌃
</button>
</div>
{% assign all_vids = site.gallery | where: "type", "video" | sort: "date" | reverse %}
{% for group in site.video_collections %}
{% if group.youtube_playlist_url and group.youtube_playlist_url != "" %}
{% continue %}
{% endif %}
{% assign grp_videos = "" | split: "" %}
{% if group.match_by == "genre" or group.match_by == "genre_and_keywords" %}
{% assign genre_matches = all_vids | where: "genre", group.genre %}
{% assign grp_videos = grp_videos | concat: genre_matches %}
{% endif %}
{% if group.match_by == "keywords" or group.match_by == "genre_and_keywords" %}
{% for kw in group.keywords %}
{% assign kw_lower = kw | downcase %}
{% for vid in all_vids %}
{% assign vtl = vid.title | downcase %}
{% if vtl contains kw_lower %}
{% assign grp_videos = grp_videos | push: vid %}
{% endif %}
{% endfor %}
{% endfor %}
{% assign grp_videos = grp_videos | uniq %}
{% endif %}
{% if group.match_by == "manual" or group.videos %}
{% for slug in group.videos %}
{% for vid in all_vids %}
{% assign vid_file = vid.path | split: "/" | last | replace: ".md", "" %}
{% if vid_file == slug or vid.title == slug %}
{% assign grp_videos = grp_videos | push: vid %}
{% endif %}
{% endfor %}
{% endfor %}
{% assign grp_videos = grp_videos | uniq %}
{% endif %}
{% if grp_videos.size > 0 %}
<section class="video-group-rail-section" style="margin-bottom: 2rem;">
<div class="video-group-rail-header" style="display: flex; align-items: center; gap: 10px; margin-bottom: 1.5rem;">
{% if group.icon %}<span class="video-group-icon" style="font-size: 1.5rem;">{{ group.icon }}</span>{% endif %}
<div>
<a href="{{ group.url | relative_url }}" style="text-decoration: none; color: inherit; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
<h3 class="video-group-rail-title" style="margin: 0; font-size: 1.15rem; font-weight: 600;">{{ group.title }}</h3>
{% if group.youtube_playlist_url %}
<span class="youtube-playlist-badge" style="font-size: 0.65rem; font-weight: 700; background: rgba(255, 0, 0, 0.15); color: #ff3333; border: 1px solid rgba(255, 0, 0, 0.3); padding: 2px 8px; border-radius: 12px; text-transform: uppercase; letter-spacing: 0.5px; display: inline-flex; align-items: center; gap: 4px; line-height: 1;">
<svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"/></svg>
YouTube Playlist
</span>
{% else %}
<span class="collection-badge" style="font-size: 0.65rem; font-weight: 700; background: rgba(0, 123, 255, 0.1); color: #007bff; border: 1px solid rgba(0, 123, 255, 0.25); padding: 2px 8px; border-radius: 12px; text-transform: uppercase; letter-spacing: 0.5px; display: inline-flex; align-items: center; gap: 4px; line-height: 1;">
Collection
</span>
{% endif %}
</a>
{% if group.description %}<p class="video-group-rail-desc" style="margin: 4px 0 0; font-size: 0.85rem; color: var(--grey-text);">{{ group.description }}</p>{% endif %}
</div>
</div>
<div class="responsive-collection-grid" role="list">
{% for item in grp_videos limit:10 %}
{% assign grp_yt_id = "" %}
{% if item.platform == 'youtube' and item.youtube_id %}
{% if item.youtube_id contains 'youtu.be/' %}{% assign grp_yt_id = item.youtube_id | split: 'youtu.be/' | last | split: '?' | first %}
{% elsif item.youtube_id contains 'shorts/' %}{% assign grp_yt_id = item.youtube_id | split: 'shorts/' | last | split: '?' | first %}
{% elsif item.youtube_id contains 'v=' %}{% assign grp_yt_id = item.youtube_id | split: 'v=' | last | split: '&' | first %}
{% elsif item.youtube_id contains '?list=' %}{% assign grp_yt_id = item.youtube_id | split: '?list=' | first %}
{% elsif item.youtube_id contains '&list=' %}{% assign grp_yt_id = item.youtube_id | split: '&list=' | first %}
{% else %}{% assign grp_yt_id = item.youtube_id %}{% endif %}
{% endif %}
<a href="{{ item.url | relative_url }}" class="video-rail-card" role="listitem" title="{{ item.title | escape }}" style="flex: 0 0 200px; text-decoration: none; color: inherit; display: block;">
<div class="video-rail-thumb" style="width: 100%; aspect-ratio: 16/9; background: #000; position: relative; overflow: hidden; border-radius: 8px; margin-bottom: 8px;">
<img src="{% if item.thumbnail and item.thumbnail != '' %}{{ item.thumbnail }}{% elsif grp_yt_id != '' %}https://img.youtube.com/vi/{{ grp_yt_id }}/hqdefault.jpg{% else %}/assets/images/webOrMobile.jpeg{% endif %}" alt="{{ item.title | escape }}" loading="lazy" style="width: 100%; height: 100%; object-fit: cover; opacity: 0.8; transition: opacity 0.3s; display: block;">
<div class="video-rail-play" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.6); border-radius: 50%; padding: 8px; display: flex;">
<svg width="18" height="18" viewBox="0 0 24 24" fill="white"><path d="M8 5v14l11-7z"/></svg>
</div>
</div>
<div class="video-rail-info">
<p class="video-rail-title" style="margin: 0 0 4px; font-size: 0.9rem; font-weight: 500; line-height: 1.3;">{{ item.title | titleize | truncate: 60 }}</p>
<span class="video-rail-genre" style="font-size: 0.75rem; color: var(--grey-text); text-transform: uppercase;">{{ item.genre | default: item.category | default: "Video" }}</span>
</div>
</a>
{% endfor %}
</div>
<div style="display: flex; justify-content: center;">
<a href="{{ group.url | relative_url }}" class="vid-source-btn" style="text-decoration: none; font-size: 0.9rem; padding: 10px 24px; border-radius: 6px; border: 1px solid var(--card-border); background: var(--card-bg); font-weight: 600; display: inline-flex; align-items: center; gap: 8px; transition: all 0.2s;">
{% if group.youtube_playlist_url %}
Browse all videos in playlist: {{ group.title }} →
{% else %}
Browse all videos in collection: {{ group.title }} →
{% endif %}
</a>
</div>
</section>
{% endif %}
{% endfor %}
</div>
<script>
(function(){
var toggle = document.getElementById('video-groups-toggle');
var container = document.getElementById('video-groups-container');
if (!toggle) return;
toggle.addEventListener('click', function(){
var groups = container.querySelectorAll('.video-group-rail-section');
var isHidden = groups[0] && groups[0].style.display === 'none';
groups.forEach(function(g){ g.style.display = isHidden ? '' : 'none'; });
toggle.setAttribute('aria-expanded', isHidden ? 'true' : 'false');
toggle.textContent = isHidden ? 'Hide collections ⌃' : 'Show collections ⌄';
});
}());
</script>
{% endif %}
{% if show_collections %}
<div class="all-videos-transition" style="margin-top: 2rem; margin-bottom: 2rem;">
<h2 style="font-size: 1.5rem; margin-bottom: 0.5rem;">All Videos</h2>
<p style="color: var(--grey-text); font-size: 0.9rem;">Explore the full collection of videos across all platforms.</p>
</div>
{% endif %}
<div class="video-masonry" id="video-masonry">
{% if vids_pager %}
{% assign videos = vids_pager.posts %}
{% else %}
{% assign videos = site.gallery | where: "type", "video" | sort: "date" | reverse %}
{% endif %}
{% for item in videos %}
{% include video_card.html item=item %}
{% endfor %}
</div>
{% if vids_pager and vids_pager.total_pages > 1 %}
<div style="margin-top: 40px; margin-bottom: 40px;">
{% include pagination.html paginator=vids_pager base_url='/gallery/videos/' %}
</div>
{% endif %}
<div class="no-results" id="no-results" style="display: none;">
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#829ab1" stroke-width="2" style="margin-bottom: 15px;">
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.35-4.35"></path>
</svg>
<p>No videos match your search.</p>
</div>
</div>
<script>
// Return to the same spot after visiting a video or collection. Embeds and
// lazy images change the page height after load, which defeats the
// browser's own scroll restoration.
(function () {
var key = 'videosScroll:' + location.pathname;
window.addEventListener('pagehide', function () {
try { sessionStorage.setItem(key, String(window.scrollY)); } catch (e) {}
});
var nav = performance.getEntriesByType && performance.getEntriesByType('navigation')[0];
if (!nav || nav.type !== 'back_forward') return;
var y = 0;
try { y = parseInt(sessionStorage.getItem(key) || '0', 10); } catch (e) {}
if (!y) return;
if ('scrollRestoration' in history) history.scrollRestoration = 'manual';
var userMoved = false;
['wheel', 'touchstart', 'keydown'].forEach(function (ev) {
window.addEventListener(ev, function () { userMoved = true; }, { once: true, passive: true });
});
var restore = function () { if (!userMoved) window.scrollTo({ top: y, behavior: 'instant' }); };
restore();
document.addEventListener('DOMContentLoaded', restore);
window.addEventListener('load', function () { restore(); setTimeout(restore, 400); });
})();
document.addEventListener('DOMContentLoaded', () => {
const searchInput = document.getElementById('video-search-input');
const masonry = document.getElementById('video-masonry');
const noResults = document.getElementById('no-results');
const allCards = Array.from(document.querySelectorAll('.video-masonry-item'));
function updateVisibility() {
let matchedCards = 0;
let activeSearch = searchInput ? searchInput.value.trim().toLowerCase() : '';
allCards.forEach(card => {
const title = (card.getAttribute('data-title') || '').toLowerCase();
if (title.includes(activeSearch)) {
card.style.display = 'inline-block';
matchedCards++;
} else {
card.style.display = 'none';
}
});
if (matchedCards === 0) {
noResults.style.display = 'flex';
masonry.style.display = 'none';
} else {
noResults.style.display = 'none';
masonry.style.display = 'block';
}
}
// Search Logic
let searchTimeout;
if (searchInput) {
searchInput.addEventListener('input', function () {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
updateVisibility();
}, 200);
});
}
// Sidebar open/close behavior (Removed as it's no longer a drawer)
/*
sidebarToggle.addEventListener('click', () => {
sidebar.classList.add('open');
sidebarOverlay.classList.add('active');
});
sidebarOverlay.addEventListener('click', () => {
sidebar.classList.remove('open');
sidebarOverlay.classList.remove('active');
});
*/
// Initialize count
updateVisibility();
// Thumbnail loading
const thumbnails = document.querySelectorAll('img.robust-thumbnail');
thumbnails.forEach(img => {
const platform = img.getAttribute('data-platform');
const fallback = img.getAttribute('data-fallback');
if (platform === 'tiktok' && img.src.includes(fallback)) {
const tkId = img.getAttribute('data-tiktok-id');
if (tkId) {
img.style.objectFit = 'contain';
img.style.padding = '3rem';
}
}
if (platform === 'instagram' && img.src.includes(fallback)) {
const igId = img.getAttribute('data-instagram-id');
if (igId) {
const igUrl = `https://www.instagram.com/p/${igId}/media/?size=l`;
const tempImg = new Image();
tempImg.onload = () => { img.src = igUrl; img.style.objectFit = 'cover'; img.style.padding = '0'; };
tempImg.src = igUrl;
img.style.objectFit = 'contain';
img.style.padding = '3rem';
}
}
});
// Inline Play Logic
document.querySelectorAll('.inline-play-btn').forEach(btn => {
btn.addEventListener('click', function (e) {
e.preventDefault();
const container = this.closest('.inline-play-container');
const platform = container.getAttribute('data-platform');
let iframe = document.createElement('iframe');
iframe.setAttribute('width', '100%');
iframe.setAttribute('height', '100%');
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('allowfullscreen', 'true');
iframe.style.position = 'absolute';
iframe.style.top = '0';
iframe.style.left = '0';
if (platform === 'youtube') {
const vidId = container.getAttribute('data-vid');
const listId = container.getAttribute('data-list');
let src = `https://www.youtube.com/embed/${vidId}?autoplay=1`;
if (listId) {
src = `https://www.youtube.com/embed/videoseries?list=${listId}&autoplay=1`;
if (vidId) src += `&v=${vidId}`;
}
iframe.setAttribute('src', src);
iframe.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture');
} else if (platform === 'tiktok') {
const tkId = container.getAttribute('data-tk');
iframe.setAttribute('src', `https://www.tiktok.com/embed/v2/${tkId}?lang=en-US`);
iframe.setAttribute('allow', 'encrypted-media');
} else if (platform === 'instagram') {
const igId = container.getAttribute('data-ig');
iframe.setAttribute('src', `https://www.instagram.com/p/${igId}/embed/captioned/`);
iframe.setAttribute('allow', 'autoplay; encrypted-media; picture-in-picture');
iframe.setAttribute('scrolling', 'no');
iframe.setAttribute('allowtransparency', 'true');
} else if (platform === 'twitter') {
const ttUrl = container.getAttribute('data-tt');
container.innerHTML = `<blockquote class="twitter-tweet" data-theme="dark"><a href="${ttUrl}"></a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"><\/script>`;
container.style.overflow = "auto";
container.style.background = "#000";
return;
}
container.innerHTML = '';
container.appendChild(iframe);
});
});
});
</script>