You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

217 lines
8.8 KiB

{{define "content"}}
<!-- Mobile Dropdown Selector -->
{{if .BlogItems}}
{{template "mobile-dropdown" (dict "Id" "mobile-blog-selector" "Items" .BlogItems "Profiles" $.Profiles "Type" "blog")}}
{{end}}
<div class="blog-layout">
<!-- Left Sidebar -->
<aside class="blog-sidebar">
<div class="blog-header">
{{if .BlogIndexAuthor}}
<div class="blog-author-handle">{{template "user-badge-simple" (dict "Pubkey" .BlogIndexAuthor "Profiles" $.Profiles)}}</div>
{{end}}
{{if .BlogIndexImage}}
<div class="blog-image">
<img src="{{.BlogIndexImage}}" alt="{{.BlogIndexTitle}}" />
</div>
{{end}}
<h1 class="blog-title">{{if .BlogIndexTitle}}{{.BlogIndexTitle}}{{else}}Blog{{end}}</h1>
{{if .BlogIndexAuthor}}
<p class="blog-byline">by {{template "user-badge-simple" (dict "Pubkey" .BlogIndexAuthor "Profiles" $.Profiles)}}</p>
{{end}}
{{if .BlogIndexSummary}}
<p class="blog-description">{{.BlogIndexSummary}}</p>
{{end}}
<div class="blog-tags">
<span class="tag">#company</span>
<span class="tag">#GitCitadel</span>
</div>
</div>
<nav class="blog-nav" aria-label="Blog articles">
<ul class="article-menu">
{{range $index, $item := .BlogItems}}
<li>
<a href="#" class="article-link" data-dtag="{{$item.DTag}}" data-index="{{$index}}"{{if eq $index 0}} data-active="true"{{end}}>
<div class="article-link-title"><span class="icon-inline">{{icon "file-text"}}</span> {{$item.Title}}</div>
{{if $item.Time}}
<div class="article-link-meta">
<span class="article-date"><span class="icon-inline">{{icon "clock"}}</span> {{$item.Time}}</span>
{{if $item.Author}}
<span class="article-author">{{template "user-badge-simple" (dict "Pubkey" $item.Author "Profiles" $.Profiles)}}</span>
{{end}}
</div>
{{end}}
</a>
</li>
{{end}}
</ul>
</nav>
</aside>
<!-- Right Content Pane -->
<main class="blog-content">
{{range $index, $item := .BlogItems}}
<article class="blog-article{{if eq $index 0}} active{{end}}" data-dtag="{{$item.DTag}}" id="article-{{$item.DTag}}">
<header class="article-header">
<h1 class="article-title">{{$item.Title}}</h1>
<p class="article-subtitle">This entry originally appeared in this blog.</p>
</header>
{{if and $item.Image (ne $item.Image "")}}
<div class="article-image">
<img src="{{$item.Image}}" alt="{{$item.Title}}" />
</div>
{{end}}
{{if $item.Summary}}<p class="article-summary">{{$item.Summary}}</p>{{end}}
<div class="article-content">
{{$item.Content}}
</div>
</article>
{{else}}
<article class="blog-article active">
<header class="article-header">
<h1 class="article-title"><span class="icon-inline">{{icon "file-x"}}</span> No Articles</h1>
</header>
<div class="article-content">
<p><span class="icon-inline">{{icon "inbox"}}</span> No blog articles available yet.</p>
</div>
</article>
{{end}}
</main>
</div>
<script>
(function() {
const articleLinks = document.querySelectorAll('.article-link');
const articles = document.querySelectorAll('.blog-article');
function showArticle(dtag) {
// Hide all articles
articles.forEach(article => {
article.classList.remove('active');
});
// Show selected article
const targetArticle = document.querySelector(`.blog-article[data-dtag="${dtag}"]`);
if (targetArticle) {
targetArticle.classList.add('active');
}
// Update active link
articleLinks.forEach(link => {
if (link.dataset.dtag === dtag) {
link.setAttribute('data-active', 'true');
} else {
link.removeAttribute('data-active');
}
});
// Update URL hash without scrolling
if (history.pushState) {
history.pushState(null, null, `#${dtag}`);
} else {
window.location.hash = dtag;
}
}
// Handle link clicks
articleLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const dtag = this.dataset.dtag;
showArticle(dtag);
});
});
// Handle initial hash on page load
if (window.location.hash) {
const hash = window.location.hash.substring(1);
const targetLink = document.querySelector(`.article-link[data-dtag="${hash}"]`);
if (targetLink) {
showArticle(hash);
}
}
// Handle browser back/forward
window.addEventListener('popstate', function() {
const hash = window.location.hash.substring(1);
if (hash) {
showArticle(hash);
} else {
// Show first article if no hash
const firstLink = document.querySelector('.article-link');
if (firstLink) {
showArticle(firstLink.dataset.dtag);
}
}
});
// Handle mobile custom dropdown
const mobileToggle = document.getElementById('mobile-blog-selector-toggle');
const mobileMenu = document.getElementById('mobile-blog-selector-menu');
if (mobileToggle && mobileMenu) {
mobileToggle.addEventListener('click', function(e) {
e.stopPropagation();
const isExpanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !isExpanded);
mobileMenu.classList.toggle('active');
});
// Close dropdown when clicking outside
document.addEventListener('click', function(e) {
if (!mobileToggle.contains(e.target) && !mobileMenu.contains(e.target)) {
mobileToggle.setAttribute('aria-expanded', 'false');
mobileMenu.classList.remove('active');
}
});
// Handle option selection
mobileMenu.querySelectorAll('li[role="option"]').forEach(function(option) {
option.addEventListener('click', function() {
const dtag = this.dataset.value;
showArticle(dtag);
// Update selected state
mobileMenu.querySelectorAll('li').forEach(li => li.classList.remove('selected'));
this.classList.add('selected');
this.setAttribute('aria-selected', 'true');
// Update toggle button
const avatar = this.querySelector('.mobile-dropdown-avatar, .mobile-dropdown-avatar-placeholder');
const title = this.querySelector('.mobile-dropdown-title').textContent;
const selected = mobileToggle.querySelector('.mobile-dropdown-selected');
selected.innerHTML = avatar.outerHTML + '<span class="mobile-dropdown-title">' + title + '</span>';
// Close dropdown
mobileToggle.setAttribute('aria-expanded', 'false');
mobileMenu.classList.remove('active');
});
});
// Update dropdown when article changes
const originalShowArticle = showArticle;
showArticle = function(dtag) {
originalShowArticle(dtag);
const selectedOption = mobileMenu.querySelector(`li[data-value="${dtag}"]`);
if (selectedOption) {
mobileMenu.querySelectorAll('li').forEach(li => {
li.classList.remove('selected');
li.setAttribute('aria-selected', 'false');
});
selectedOption.classList.add('selected');
selectedOption.setAttribute('aria-selected', 'true');
// Update toggle button
const avatar = selectedOption.querySelector('.mobile-dropdown-avatar, .mobile-dropdown-avatar-placeholder');
const title = selectedOption.querySelector('.mobile-dropdown-title').textContent;
const selected = mobileToggle.querySelector('.mobile-dropdown-selected');
selected.innerHTML = avatar.outerHTML + '<span class="mobile-dropdown-title">' + title + '</span>';
}
};
}
})();
</script>
{{end}}
{{/* Feed is defined in components.html */}}