304 lines
13 KiB
HTML
304 lines
13 KiB
HTML
{{ template "base.html" . }}
|
|
|
|
{{ define "extrahead" }}
|
|
<link rel="stylesheet" type="text/css" href="{{ static "landing.css" }}"/>
|
|
<script type="text/javascript" src="{{ static "util.js" }}"></script>
|
|
<style type="text/css">
|
|
{{ $base := . }}
|
|
{{ range $col := .PostColumns }}
|
|
{{ range $entry := $col }}
|
|
{{ $c1 := hex2color .Project.Color1 }}
|
|
{{ $linkColor := eq $base.Theme "dark" | ternary (lightness 0.55 $c1) (lightness 0.35 $c1) | color2css }}
|
|
{{ $linkHoverColor := eq $base.Theme "dark" | ternary (lightness 0.65 $c1) (lightness 0.45 $c1) | color2css }}
|
|
{{ $projectPostBackground := eq $base.Theme "dark" | ternary (lightness 0.15 $c1) (lightness 0.95 $c1) | alpha 0.2 | color2css }}
|
|
|
|
#p{{ .Project.Subdomain }} a.project-title { color: {{ $linkColor }}; }
|
|
#p{{ .Project.Subdomain }} .unread a { color: {{ $linkColor }}; }
|
|
#p{{ .Project.Subdomain }} .unread a:hover { color: {{ $linkHoverColor }} }
|
|
#p{{ .Project.Subdomain }} .unread .avatar-icon { border-color: {{ $linkColor }}; }
|
|
#p{{ .Project.Subdomain }} .post-list-item:nth-of-type(even) { background-color: {{ $projectPostBackground }}; }
|
|
#p{{ .Project.Subdomain }} .thread.more { background-color:transparent; }
|
|
{{ end }}
|
|
{{ end }}
|
|
</style>
|
|
{{/*
|
|
<script type="text/javascript" src="{% static 'templates.js' %}?v={% cachebust %}"></script>
|
|
<script type="text/javascript" src="{% static 'timeline.js' %}?v={% cachebust %}"></script>
|
|
<script type="text/javascript" src="{% static 'showcase.js' %}?v={% cachebust %}"></script>
|
|
*/}}
|
|
{{ end }}
|
|
|
|
{{ define "content" }}
|
|
<div class="content-block">
|
|
<div class="optionbar pb2">
|
|
<div class="tc tl-l w-100">
|
|
<h2 class="di-l mr2-l">Around the Network</h2>
|
|
<ul class="list dib-l">
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .FeedUrl }}">View all posts on HMN</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .PodcastUrl }}">Podcast</a>
|
|
</li>
|
|
{{/* TODO: Make a better IRC intro page because the current one is trash anyway */}}
|
|
{{/*
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .StreamsUrl }}">See who's live</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .IRCUrl }}" target="_blank">Chat in IRC</a>
|
|
</li>
|
|
*/}}
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .DiscordUrl }}" target="_blank">Chat on Discord</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .ShowUrl }}" target="_blank">See the Show</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content-block news cf">
|
|
{{ $newsPost := .NewsPost }}
|
|
{{ range $i, $col := .PostColumns }}
|
|
<div class="fl w-100 w-50-l">
|
|
<div class="mw7 mw-none-l center-layout">
|
|
{{ if eq $i 0 }}
|
|
<div class="pt3">
|
|
{{ template "landing_page_featured_post" $newsPost}}
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{ range $entry := $col }}
|
|
{{ $proj := $entry.Project }}
|
|
{{ $posts := $entry.Posts }}
|
|
<div class="pt3" id="p{{ $proj.Subdomain }}">
|
|
{{ $c1 := hex2color $proj.Color1 }}
|
|
<a
|
|
class="project-title"
|
|
href="{{ $proj.Url }}"
|
|
>
|
|
<h2 class="ph3">{{ $proj.Name }}</h2>
|
|
</a>
|
|
|
|
{{ with $entry.FeaturedPost }}
|
|
{{ template "landing_page_featured_post" . }}
|
|
{{ end }}
|
|
|
|
{{ range $post := $posts }}
|
|
{{ template "post_list_item" $post }}
|
|
{{ end }}
|
|
|
|
<div class="ph3 thread unread more">
|
|
<a class="title" href="{{ $entry.ForumsUrl }}">
|
|
More posts →
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{/* TODO(asaf): Delete this section once we're done with the landing page
|
|
{% block columns %}
|
|
{% include "showcase/js_templates.html" %}
|
|
{% include "timeline/js_templates.html" %}
|
|
<div class="content-block pb3">
|
|
<div class="tc tl-l w-100 pb2">
|
|
<h2 class="di-l mr2-l">Community Showcase</h2>
|
|
<ul class="list dib-l">
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{{ .ShowcaseUrl }}">View all</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="showcase relative overflow-hidden">
|
|
<div id="showcase-items" class="flex relative pl3 pl0-ns"></div>
|
|
<div class="arrow-container left">
|
|
<a href="javascript:void(0)" class="arrow svgicon svgicon-nofix" onclick="scrollShowcase('left')">{% svg 'chevron-left' %}</a>
|
|
</div>
|
|
<div class="arrow-container right">
|
|
<a href="javascript:void(0)" class="arrow svgicon svgicon-nofix" onclick="scrollShowcase('right')">{% svg 'chevron-right' %}</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="c--dimmer i pv2 ph3 ph0-ns">
|
|
This is a selection of recent work done by community members. Want to participate? <a href="{{ .DiscordUrl }}" target="_blank">Join us on Discord.</a>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
const timelineData = JSON.parse("{{ showcase_timeline_json|escapejs }}");
|
|
|
|
const showcaseEl = document.querySelector('#showcase-items');
|
|
for (const item of timelineData.items) {
|
|
const [itemEl, addThumbnail] = makeShowcaseItem(item);
|
|
addThumbnail();
|
|
itemEl.container.classList.add('mr3');
|
|
showcaseEl.appendChild(itemEl.root);
|
|
}
|
|
|
|
function rem2px(rem) {
|
|
return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
}
|
|
|
|
function scrollShowcase(direction = null) {
|
|
const ITEM_WIDTH = showcaseEl.querySelector('.showcase-item').getBoundingClientRect().width;
|
|
const ITEM_SPACING = rem2px(1);
|
|
|
|
const showcaseWidth = showcaseEl.getBoundingClientRect().width;
|
|
const numVisible = showcaseWidth / (ITEM_WIDTH + ITEM_SPACING);
|
|
const scrollMagnitude = Math.floor(numVisible) - 1;
|
|
const scrollDirection = (direction === 'right' ? 1 : (direction === 'left' ? -1 : 0));
|
|
const scrollAmount = scrollMagnitude * scrollDirection;
|
|
|
|
const minIndex = 0;
|
|
const maxIndex = timelineData.items.length - Math.floor(numVisible);
|
|
|
|
const currentScrollIndex = parseInt(showcaseEl.getAttribute('data-scroll-index'), 10) || 0;
|
|
const newScrollIndex = Math.max(minIndex, Math.min(maxIndex, currentScrollIndex + scrollAmount));
|
|
|
|
showcaseEl.style.transform = `translateX(${-newScrollIndex * (ITEM_WIDTH + ITEM_SPACING)}px)`;
|
|
showcaseEl.setAttribute('data-scroll-index', newScrollIndex);
|
|
|
|
const leftArrowEl = document.querySelector('.arrow-container.left');
|
|
const rightArrowEl = document.querySelector('.arrow-container.right');
|
|
|
|
leftArrowEl.classList.toggle('hide', newScrollIndex === minIndex);
|
|
rightArrowEl.classList.toggle('hide', newScrollIndex === maxIndex);
|
|
}
|
|
scrollShowcase(); // force a scroll as an easy way to initialize styles
|
|
|
|
window.addEventListener('resize', () => scrollShowcase());
|
|
</script>
|
|
|
|
<div class="content-block">
|
|
<div class="optionbar pb2">
|
|
<div class="tc tl-l w-100">
|
|
<h2 class="di-l mr2-l">Around the Network</h2>
|
|
<ul class="list dib-l">
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{% url 'feed' %}">View all posts on HMN</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="{% url 'podcast' %}">Podcast</a>
|
|
</li>
|
|
<!-- <li class="dib-ns ma0 ph2">
|
|
<a href="{% url 'streams' %}">See who's live</a>
|
|
</li> -->
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="/blogs/p/1138-%5Btutorial%5D_handmade_network_irc" target="_blank">Chat in IRC</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="https://discord.gg/hxWxDee" target="_blank">Chat on Discord</a>
|
|
</li>
|
|
<li class="dib-ns ma0 ph2">
|
|
<a href="https://handmadedev.show/" target="_blank">See the Show</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% spaceless %}
|
|
<div class="content-block news cf">
|
|
{% for col in recent_post_columns %}
|
|
<div class="fl w-100 w-50-l">
|
|
<div class="mw7 mw-none-l center-layout">
|
|
{% if forloop.counter == 1 %}
|
|
<div class="pt3">
|
|
{% include "blog_index_thread_list_entry.html" with post=featured_post align_top=True %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% for entry in col %}
|
|
{% with proj=entry.project posts=entry.posts %}
|
|
<div class="pt3" id="p{{proj.slug}}">
|
|
<a
|
|
href="{% url 'cover_page' subdomain=proj.slug %}"
|
|
{% if user|get_theme == 'dark' %}
|
|
style="color:#{% rgb_accent proj.color_1 0.55 %};"
|
|
{% else %}
|
|
style="color:#{% rgb_accent proj.color_1 0.25 %};"
|
|
{% endif %}
|
|
>
|
|
<h2 class="ph3">{{ proj.name }}</h2>
|
|
</a>
|
|
|
|
{% if entry.featured and proj.slug != "hmn" %}
|
|
{% with post=entry.featured.0 has_read=entry.featured.1 %}
|
|
{% if post.category.kind == 5 and post.parent == None %}
|
|
{% include "thread_list_entry.html" with thread=post.thread %}
|
|
{% else %}
|
|
{% include "blog_index_thread_list_entry.html" with align_top=True %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
{% endif %}
|
|
|
|
{% for post, has_read in posts %}
|
|
{% if forloop.counter0 < max_posts %}
|
|
{% include "thread_list_entry.html" with thread=post.thread %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% with more=posts|length|add:-5|clamp_lower:0 %}
|
|
{% if more > 0 %}
|
|
<div class="ph3 thread unread more">
|
|
<a class="title"
|
|
href="{% url 'project_forum' subdomain=proj.slug %}"
|
|
>{{ more }} more recently →</a>
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
</div>
|
|
{% endwith %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endspaceless %}
|
|
{% endblock %}
|
|
*/}}
|
|
|
|
{{ define "landing_page_featured_post" }}
|
|
{{/* Call this template with a LandingPageFeaturedPost. */}}
|
|
<div class="flex items-start ph3 pv2 {{ if .Unread }}unread{{ else }}read{{ end }}">
|
|
<img class="avatar-icon mr2" src="{{ .User.AvatarUrl }}">
|
|
<div class="flex-grow-1 overflow-hidden">
|
|
<div class="title mb1"><a href="{{ .Url }}">{{ .Title }}</a></div>
|
|
<div class="details">
|
|
<a class="user" href="{{ .User.ProfileUrl }}">{{ .User.Name }}</a> — {{ timehtml (relativedate .Date) .Date }}
|
|
</div>
|
|
<div class="overflow-hidden mh-5 mt2 relative">
|
|
<div>
|
|
{{ .Content }}
|
|
</div>
|
|
<div class="excerpt-fade absolute w-100 h4 bottom-0 z-999"></div>
|
|
</div>
|
|
<div class="mt2">
|
|
<a href="{{ .Url }}">Read More →</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
|
|
{{ define "post_list_item" }}
|
|
{{/* Call this template with a PostListItem. */}}
|
|
<div class="post-list-item flex items-center ph3 pv2 {{ if .Unread }}unread{{ else }}read{{ end }} {{ .Classes }}">
|
|
<img class="avatar-icon mr2" src="{{ .User.AvatarUrl }}">
|
|
<div class="flex-grow-1 overflow-hidden">
|
|
<div class="title nowrap truncate"><a href="{{ .Url }}" title="{{ .Preview }}">{{ .Title }}</a></div>
|
|
<div class="details">
|
|
<a class="user" href="{{ .User.ProfileUrl }}">{{ .User.Name }}</a> — {{ timehtml (relativedate .Date) .Date }}
|
|
</div>
|
|
</div>
|
|
<div class="goto">
|
|
<a href="{{ .Url }}">»</a>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|