Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions assets/scss/_video-landing_project.scss
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,20 @@ a#videoPageLink:focus {
margin-bottom: 2rem;
}

.video-grid-container {
position: relative;
min-height: 500px;
transition: min-height 0.15s ease;
}

.video-group {
position: absolute;
width: 100%;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease;
}

.video-card {
background-color: rgba(18,18,18,1);
border-radius: 12px;
Expand Down
3 changes: 1 addition & 2 deletions content/en/videos/template-category/sub-category/video-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ tags: [] # example: [review, collaboration, comments] # also available as hyperl
duration: 2:30 # optional, duration of the video in minutes:seconds format, "min" is automatically appended the duration
---

{{< youtube id=videoId class="youtube-embed-container" >}}
<!-- example: {{< youtube bb6J--aApk8 >}} -->
{{< youtube id=bb6J--aApk8 class="yt-embed-container" >}}
52 changes: 52 additions & 0 deletions layouts/partials/video-category-navigation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{{ $.Scratch.Set "pathToHashMap" dict }}
{{ $videos := .Site.GetPage "section" "videos" }}
{{ if $videos }}
{{ range $mainIndex, $mainSection := $videos.Sections }}
{{ $mainPath := $mainSection.RelPermalink }}
{{ if not (hasPrefix $mainPath "/") }}
{{ $mainPath = "/" | add $mainPath }}
{{ end }}
{{ $.Scratch.SetInMap "pathToHashMap" $mainPath (printf "category-%d-subcategory-0" $mainIndex) }}
{{ range $subIndex, $subSection := $mainSection.Sections }}
{{ $subPath := $subSection.RelPermalink }}
{{ if not (hasPrefix $subPath "/") }}
{{ $subPath = "/" | add $subPath }}
{{ end }}
{{ $.Scratch.SetInMap "pathToHashMap" $subPath (printf "category-%d-subcategory-%d" $mainIndex $subIndex) }}
{{ end }}
{{ end }}
{{ end }}

<div id="video-hash-map" data-map='{{ $.Scratch.Get "pathToHashMap" | jsonify }}' style="display:none"></div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const mapEl = document.getElementById('video-hash-map');
const pathToHashMap = mapEl ? JSON.parse(mapEl.dataset.map || '{}') : {};

const extractVideoPath = (pathname) => {
const match = pathname.match(/\/videos\/.*/);
if (!match) return null;
const path = match[0];
return path.endsWith('/') ? path : path + '/';
};

const currentPath = extractVideoPath(window.location.pathname);
if (currentPath && !window.location.hash && pathToHashMap[currentPath]) {
window.location.hash = pathToHashMap[currentPath];
}

document.querySelectorAll("a[href*='/videos/']").forEach(link => {
try {
const url = new URL(link.href);
if (url.origin !== window.location.origin || url.hash) return;
const pathKey = extractVideoPath(url.pathname);
if (pathKey && pathToHashMap[pathKey]) {
url.hash = pathToHashMap[pathKey];
link.href = url.toString();
}
} catch (_) {}
});
});
</script>


53 changes: 22 additions & 31 deletions layouts/partials/video-landing-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<div class="category-tabs">
{{ $currentPage := . }}
{{ range $index, $section := $videoContentDir.Sections }}
<a href="#category-{{ $index }}" class="category-tab" data-category="{{ $index }}">
<a href="{{ .RelPermalink }}#category-{{ $index }}" class="category-tab" data-category="{{ $index }}">
<div class="tab-icon">
{{ if .Params.icon }}
{{ if hasPrefix .Params.icon "bi" }}
Expand All @@ -32,14 +32,14 @@
<!-- if a category has at least 1 subcategory -->
{{ if gt (len .Sections) 0 }}
{{ range $subIndex, $subSection := .Sections }}
<a href="#category-{{ $mainIndex }}-subcategory-{{ $subIndex }}" class="subcategory-btn"
<a href="{{ .RelPermalink }}#category-{{ $mainIndex }}-subcategory-{{ $subIndex }}" class="subcategory-btn"
data-main-category="{{ $mainIndex }}" data-subcategory="{{ $subIndex }}">
{{ .Title }}
</a>
{{ end }}
{{ else }}
<!-- if no subcategories i.e. videos are directly in category folder: set a default "All" subcategory -->
<a href="#category-{{ $mainIndex }}-subcategory-main" class="subcategory-btn"
<a href="{{ $mainSection.RelPermalink }}#category-{{ $mainIndex }}-subcategory-main" class="subcategory-btn"
data-main-category="{{ $mainIndex }}" data-subcategory="main">
All
</a>
Expand All @@ -55,7 +55,7 @@
{{ range $mainIndex, $mainSection := $videoContentDir.Sections }}
<!-- display videos from subcategories -->
{{ range $subIndex, $subSection := .Sections }}
<div class="video-group" id="video-group-{{ $mainIndex }}-{{ $subIndex }}" style="display: none;">
<div class="video-group" id="video-group-{{ $mainIndex }}-{{ $subIndex }}">
<div class="video-grid">
{{ range $subSection.Pages }}
<div class="video-card"
Expand Down Expand Up @@ -106,7 +106,7 @@ <h3>{{ .Title }}</h3>

<!-- for direct videos in main category (when no subcategories) -->
{{ if eq (len .Sections) 0 }}
<div class="video-group" id="video-group-{{ $mainIndex }}-0" style="display: none;">
<div class="video-group" id="video-group-{{ $mainIndex }}-0">
<div class="video-grid">
{{ range where $mainSection.Pages "Kind" "page" }}
<div class="video-card"
Expand Down Expand Up @@ -208,39 +208,30 @@ <h3>{{ .Title }}</h3>
if (currentSubcategoryBtns.length > 0 && subCategoryIndex < currentSubcategoryBtns.length) {
currentSubcategoryBtns[subCategoryIndex].classList.add('active');
}



// show/hide video groups
const videoGroups = document.querySelectorAll('.video-group');
videoGroups.forEach(group => group.style.display = 'none');
videoGroups.forEach(group => {
group.style.opacity = '0';
group.style.pointerEvents = 'none';
});
const activeVideoGroup = document.getElementById(`video-group-${mainCategoryIndex}-${subCategoryIndex}`);
if (activeVideoGroup) {
activeVideoGroup.style.display = 'block';
activeVideoGroup.style.opacity = '1';
activeVideoGroup.style.pointerEvents = 'auto';
syncContainerHeight(activeVideoGroup);
}

// update url hash, can later modify this to have
// this: category-getting-started-subcategory-onboarding
// instead of: category-0-subcategory-1

window.location.hash = `category-${mainCategoryIndex}-subcategory-${subCategoryIndex}`;
}

// Add click handlers to main category tabs
categoryTabs.forEach((tab, index) => {
tab.addEventListener('click', function(e) {
e.preventDefault();
updateContent(index);
});
});

// Add click handlers to subcategory buttons
subcategoryBtns.forEach(btn => {
btn.addEventListener('click', function(e) {
e.preventDefault();
const mainCategoryIndex = parseInt(this.getAttribute('data-main-category'));
const subCategoryIndex = parseInt(this.getAttribute('data-subcategory'));
updateContent(mainCategoryIndex, subCategoryIndex);
});
});
// sync container height to prevent collapse
function syncContainerHeight(activeGroup) {
const containerEl = document.querySelector('.video-grid-container');
if (activeGroup && containerEl) {
const height = activeGroup.scrollHeight;
containerEl.style.minHeight = height + 'px';
}
}

// handle initial load and urL hash changes
function handleHashChange() {
Expand Down
1 change: 1 addition & 0 deletions layouts/video/baseof.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
</div>
{{ partial "footer.html" . }}
</div>
{{partial "video-category-navigation.html" .}}
{{ partial "scripts.html" . }} {{ partial "image-modal.html" . }}
</body>
</html>
Loading