Fix up landing page colors
This commit is contained in:
parent
a04b00c0a7
commit
292c400dfb
|
@ -7438,6 +7438,15 @@ article code {
|
||||||
.mw-site {
|
.mw-site {
|
||||||
max-width: 80rem; }
|
max-width: 80rem; }
|
||||||
|
|
||||||
|
.mh-3 {
|
||||||
|
max-height: 4rem; }
|
||||||
|
|
||||||
|
.mh-4 {
|
||||||
|
max-height: 8rem; }
|
||||||
|
|
||||||
|
.mh-5 {
|
||||||
|
max-height: 16rem; }
|
||||||
|
|
||||||
.mh-100 {
|
.mh-100 {
|
||||||
max-height: 100%; }
|
max-height: 100%; }
|
||||||
|
|
||||||
|
@ -8576,17 +8585,6 @@ input[type=submit] {
|
||||||
border-bottom-color: transparent; }
|
border-bottom-color: transparent; }
|
||||||
.thread .title:hover {
|
.thread .title:hover {
|
||||||
border-bottom-color: initial; }
|
border-bottom-color: initial; }
|
||||||
.thread.read {
|
|
||||||
color: #555;
|
|
||||||
color: var(--forum-thread-read-color); }
|
|
||||||
.thread.read td {
|
|
||||||
color: #555;
|
|
||||||
color: var(--forum-thread-read-color); }
|
|
||||||
.thread.read a {
|
|
||||||
color: #888;
|
|
||||||
color: var(--forum-thread-read-link-color); }
|
|
||||||
.thread.read .title {
|
|
||||||
font-weight: 500; }
|
|
||||||
.forum .thread .info th {
|
.forum .thread .info th {
|
||||||
width: 50px; }
|
width: 50px; }
|
||||||
|
|
||||||
|
@ -8598,18 +8596,18 @@ input[type=submit] {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #bbb;
|
background-color: #bbb;
|
||||||
background-color: var(--dimmest-color); }
|
background-color: var(--dimmest-color); }
|
||||||
.thread .avatar-icon:not(.lite) {
|
|
||||||
left: 30px;
|
.read {
|
||||||
bottom: 10px; }
|
color: #555;
|
||||||
.thread .info .avatar-icon:not(.lite) {
|
color: var(--forum-thread-read-color); }
|
||||||
bottom: 0px;
|
.read td {
|
||||||
left: 0px; }
|
color: #555;
|
||||||
.feed .avatar-icon:not(.lite) {
|
color: var(--forum-thread-read-color); }
|
||||||
left: -50px;
|
.read a {
|
||||||
bottom: -10px; }
|
color: #888;
|
||||||
.project .box .avatar-icon:not(.lite) {
|
color: var(--forum-thread-read-link-color); }
|
||||||
left: 0px;
|
.read .title {
|
||||||
bottom: -10px; }
|
font-weight: 500; }
|
||||||
|
|
||||||
.goto {
|
.goto {
|
||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
|
@ -9220,6 +9218,10 @@ span.icon-rss::before {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
height: 10rem; } }
|
height: 10rem; } }
|
||||||
|
|
||||||
|
.landing .excerpt-fade {
|
||||||
|
background-image: linear-gradient(to top, var(--content-background), rgba(0, 0, 0, 0));
|
||||||
|
pointer-events: none; }
|
||||||
|
|
||||||
.star-btn {
|
.star-btn {
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|
11
src/db/db.go
11
src/db/db.go
|
@ -72,11 +72,18 @@ func (it *StructQueryIterator) Next() (interface{}, bool) {
|
||||||
field = field.Elem()
|
field = field.Elem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some actual values still come through as pointers (like net.IPNet). Dunno why.
|
||||||
|
// Regardless, we know it's not nil, so we can get at the contents.
|
||||||
|
valReflected := reflect.ValueOf(val)
|
||||||
|
if valReflected.Kind() == reflect.Ptr {
|
||||||
|
valReflected = valReflected.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
switch field.Kind() {
|
switch field.Kind() {
|
||||||
case reflect.Int:
|
case reflect.Int:
|
||||||
field.SetInt(reflect.ValueOf(val).Int())
|
field.SetInt(valReflected.Int())
|
||||||
default:
|
default:
|
||||||
field.Set(reflect.ValueOf(val))
|
field.Set(valReflected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,18 @@ article code {
|
||||||
max-width: 80rem;
|
max-width: 80rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mh-3 {
|
||||||
|
max-height: $height-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mh-4 {
|
||||||
|
max-height: $height-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mh-5 {
|
||||||
|
max-height: $height-5;
|
||||||
|
}
|
||||||
|
|
||||||
.mh-100 {
|
.mh-100 {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,22 +47,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.read {
|
|
||||||
@include usevar('color', 'forum-thread-read-color');
|
|
||||||
|
|
||||||
td {
|
|
||||||
@include usevar('color', 'forum-thread-read-color');
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
@include usevar('color', 'forum-thread-read-link-color');
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.forum & .info th {
|
.forum & .info th {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
@ -75,27 +59,21 @@
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@include usevar(background-color, dimmest-color);
|
@include usevar(background-color, dimmest-color);
|
||||||
|
}
|
||||||
|
|
||||||
&:not(.lite) {
|
.read {
|
||||||
.thread & {
|
@include usevar('color', 'forum-thread-read-color');
|
||||||
left: 30px;
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thread .info & {
|
td {
|
||||||
bottom: 0px;
|
@include usevar('color', 'forum-thread-read-color');
|
||||||
left: 0px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.feed & {
|
a {
|
||||||
left: -50px;
|
@include usevar('color', 'forum-thread-read-link-color');
|
||||||
bottom: -10px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.project .box & {
|
.title {
|
||||||
left: 0px;
|
font-weight: 500;
|
||||||
bottom: -10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,4 +83,9 @@
|
||||||
height: 10rem;
|
height: 10rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.excerpt-fade {
|
||||||
|
background-image: linear-gradient(to top, var(--content-background) , rgba(0, 0, 0, 0));
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{{/*
|
{{/*
|
||||||
This template is intended to display a single post or thread in the context of a forum, the feed, or a similar layout.
|
This template is intended to display a single post or thread in the context of a forum, the feed, or a similar layout.
|
||||||
|
|
||||||
It should be called with PostListItemData.
|
It should be called with PostListItem.
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
<div class="flex items-center ph3 pv2">
|
<div class="post-list-item flex items-center ph3 pv2 {{ if .Unread }}unread{{ else }}read{{ end }}">
|
||||||
<img class="avatar-icon mr2" src="{{ .User.AvatarUrl }}">
|
<img class="avatar-icon mr2" src="{{ .User.AvatarUrl }}">
|
||||||
<div class="flex-grow-1 overflow-hidden">
|
<div class="flex-grow-1 overflow-hidden">
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
|
|
|
@ -1,5 +1,33 @@
|
||||||
{{ template "base.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" }}
|
{{ define "content" }}
|
||||||
<div class="content-block">
|
<div class="content-block">
|
||||||
<div class="optionbar pb2">
|
<div class="optionbar pb2">
|
||||||
|
@ -33,58 +61,41 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-block news cf">
|
<div class="content-block news cf">
|
||||||
|
{{ $newsPost := .NewsPost }}
|
||||||
{{ range $i, $col := .PostColumns }}
|
{{ range $i, $col := .PostColumns }}
|
||||||
<div class="fl w-100 w-50-l">
|
<div class="fl w-100 w-50-l">
|
||||||
<div class="mw7 mw-none-l center-layout">
|
<div class="mw7 mw-none-l center-layout">
|
||||||
{{ if eq $i 0 }}
|
{{ if eq $i 0 }}
|
||||||
<div class="pt3">
|
<div class="pt3">
|
||||||
Wow, a featured post!
|
{{ template "landing_page_featured_post" $newsPost}}
|
||||||
{{/* {% include "blog_index_thread_list_entry.html" with post=featured_post align_top=True %} */}}
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ range $entry := $col }}
|
{{ range $entry := $col }}
|
||||||
{{ $proj := $entry.Project }}
|
{{ $proj := $entry.Project }}
|
||||||
{{ $posts := $entry.Posts }}
|
{{ $posts := $entry.Posts }}
|
||||||
<div class="pt3" id="p{{ $proj.Subdomain }}"> {{/* TODO: Is this ID used for anything? */}}
|
<div class="pt3" id="p{{ $proj.Subdomain }}">
|
||||||
<a {{/* TODO: Replace this special-case style with a CSS class */}}
|
{{ $c1 := hex2color $proj.Color1 }}
|
||||||
|
<a
|
||||||
|
class="project-title"
|
||||||
href="{{ projecturl "/" $proj }}"
|
href="{{ projecturl "/" $proj }}"
|
||||||
style="color: #{{ eq $.Theme "dark" | ternary (brighten $proj.Color1 0.1) (darken $proj.Color1 0.2) }}"
|
|
||||||
>
|
>
|
||||||
<h2 class="ph3">{{ $proj.Name }}</h2>
|
<h2 class="ph3">{{ $proj.Name }}</h2>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{{ with $entry.FeaturedPost }}
|
{{ with $entry.FeaturedPost }}
|
||||||
<div class="flex items-start ph3 pv2">
|
{{ template "landing_page_featured_post" . }}
|
||||||
<img class="avatar-icon mr2" src="{{ .User.AvatarUrl }}">
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<div class="overflow-hidden">
|
|
||||||
<div class="title nowrap truncate"><a href="{{ .Url }}">{{ .Title }}</a></div>
|
|
||||||
<div class="details">
|
|
||||||
<a class="user" href="{{ .User.ProfileUrl }}">{{ .User.Name }}</a> — <span class="datetime">{{ relativedate .Date }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{{ .Content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ range $post := $posts }}
|
{{ range $post := $posts }}
|
||||||
{{ template "post_list_item.html" $post }}
|
{{ template "post_list_item.html" $post }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{/*
|
|
||||||
{% with more=posts|length|add:-5|clamp_lower:0 %}
|
<div class="ph3 thread unread more">
|
||||||
{% if more > 0 %}
|
<a class="title" href="{{ projecturl "/forums" $proj }}">
|
||||||
<div class="ph3 thread unread more">
|
More posts →
|
||||||
<a class="title"
|
</a>
|
||||||
href="{% url 'project_forum' subdomain=proj.slug %}"
|
</div>
|
||||||
>{{ more }} more recently →</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
*/}}
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -94,43 +105,6 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{/*
|
{{/*
|
||||||
{{ 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">
|
|
||||||
{{ range _, $col := .RecentPostColumns }}
|
|
||||||
{{ range _, $entry := $col }}
|
|
||||||
{{ $themeDim := eq .Theme "dark" | ternary (darken .Color 0.5) (brighten .Color 0.2) }}
|
|
||||||
{{ $themeDimmer := eq .Theme "dark" | ternary (darken .Color 0.65) (brighten .Color 0.4) }}
|
|
||||||
{{ $themeDimmest := eq .Theme "dark" | ternary (darken .Color 0.8) (brighten .Color 0.6) }}
|
|
||||||
|
|
||||||
{{ $linkColor := eq .Theme "dark" | ternary (brighten .Color 0.1) (darken .Color 0.2) }}
|
|
||||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (brighten .Color 0.2) (darken .Color 0.1) }}
|
|
||||||
|
|
||||||
{{ eq .Theme "dark" }}
|
|
||||||
#p{{ .Project.Subdomain }} .unread a { color: #{% rgb_accent entry.project.color_1 0.55 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .unread a:hover { color: #{% rgb_accent entry.project.color_1 0.65 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .unread .avatar-icon { border: 2px solid #{% rgb_accent entry.project.color_1 0.55 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .thread:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.14 False 0.03%}; }
|
|
||||||
#p{{ .Project.Subdomain }} .forum .post:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.14 False 0.03 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .blog .post:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.14 False 0.03 %}; }
|
|
||||||
{{ else }}
|
|
||||||
#p{{ .Project.Subdomain }} .unread a { color: #{% rgb_accent entry.project.color_1 0.35 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .unread a:hover { color: #{% rgb_accent entry.project.color_1 0.45 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .unread .avatar-icon { border: 2px solid #{% rgb_accent entry.project.color_1 0.35 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .thread:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.94 False 0.2 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .forum .post:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.94 False 0.2 %}; }
|
|
||||||
#p{{ .Project.Subdomain }} .blog .post:nth-of-type(even) { background-color:#{% rgb_accent entry.project.color_1 0.94 False 0.2 %}; }
|
|
||||||
{{ end }}
|
|
||||||
#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 }}
|
|
||||||
|
|
||||||
{% block columns %}
|
{% block columns %}
|
||||||
{% include "showcase/js_templates.html" %}
|
{% include "showcase/js_templates.html" %}
|
||||||
{% include "timeline/js_templates.html" %}
|
{% include "timeline/js_templates.html" %}
|
||||||
|
@ -288,4 +262,28 @@
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock %}
|
{% 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">
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<div class="title nowrap truncate"><a href="{{ .Url }}">{{ .Title }}</a></div>
|
||||||
|
<div class="details">
|
||||||
|
<a class="user" href="{{ .User.ProfileUrl }}">{{ .User.Name }}</a> — <span class="datetime">{{ relativedate .Date }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-hidden mh-5 mt2 relative">
|
||||||
|
<div>
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
<div class="excerpt-fade absolute w-100 h4 bottom-0"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mt2">
|
||||||
|
<a href="{{ .Url }}">Read More →</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
background-size: "{{ . }}";
|
background-size: "{{ . }}";
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{ $bgcolor := or .Project.Color1 "999999" }}
|
{{ $bgcolor := or .Project.Color1 "999999" | hex2color }}
|
||||||
background-color: #{{ eq .Theme "dark" | ternary (darken $bgcolor 0.6) (brighten $bgcolor 0.6) }};
|
background-color: {{ eq .Theme "dark" | ternary (darken 0.6 $bgcolor) (brighten 0.6 $bgcolor) | color2css }};
|
||||||
background-image: url('data:image/png;base64,{{ eq .Theme "dark" | ternary $bgdark $bglight }}');
|
background-image: url('data:image/png;base64,{{ eq .Theme "dark" | ternary $bgdark $bglight }}');
|
||||||
background-size: auto;
|
background-size: auto;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
{{ $themeDim := eq .Theme "dark" | ternary (darken .Color 0.5) (brighten .Color 0.2) }}
|
{{ $c := hex2color .Color }}
|
||||||
{{ $themeDimmer := eq .Theme "dark" | ternary (darken .Color 0.65) (brighten .Color 0.4) }}
|
{{ $themeDim := eq .Theme "dark" | ternary (lightness 0.35 $c) (lightness 0.75 $c) | color2css }}
|
||||||
{{ $themeDimmest := eq .Theme "dark" | ternary (darken .Color 0.8) (brighten .Color 0.6) }}
|
{{ $themeDimmer := eq .Theme "dark" | ternary (lightness 0.3 $c) (lightness 0.8 $c) | color2css }}
|
||||||
|
{{ $themeDimmest := eq .Theme "dark" | ternary (lightness 0.2 $c) (lightness 0.85 $c) | color2css }}
|
||||||
|
|
||||||
{{ $linkColor := eq .Theme "dark" | ternary (brighten .Color 0.1) (darken .Color 0.2) }}
|
{{ $linkColor := eq .Theme "dark" | ternary (lightness 0.55 $c) (lightness 0.35 $c) | color2css }}
|
||||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (brighten .Color 0.2) (darken .Color 0.1) }}
|
{{ $linkHoverColor := eq .Theme "dark" | ternary (lightness 0.65 $c) (lightness 0.45 $c) | color2css }}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--theme-color: #{{ .Color }};
|
--theme-color: {{ $c | color2css }};
|
||||||
--theme-color-dim: #{{ $themeDim }};
|
--theme-color-dim: {{ $themeDim }};
|
||||||
--theme-color-dimmer: #{{ $themeDimmer }};
|
--theme-color-dimmer: {{ $themeDimmer }};
|
||||||
--theme-color-dimmest: #{{ $themeDimmest }};
|
--theme-color-dimmest: {{ $themeDimmest }};
|
||||||
|
|
||||||
--link-color: #{{ $linkColor }};
|
--link-color: {{ $linkColor }};
|
||||||
--link-color-hover: #{{ $linkHoverColor }};
|
--link-color-hover: {{ $linkHoverColor }};
|
||||||
}
|
}
|
||||||
|
|
||||||
.accent {
|
.accent {
|
||||||
background-color: #{{ $themeDim }};
|
background-color: {{ $themeDim }};
|
||||||
background-color: var(--theme-dim);
|
background-color: var(--theme-dim);
|
||||||
}
|
}
|
||||||
.user-bar {
|
.user-bar {
|
||||||
border-bottom-color: #{{ $themeDim }};
|
border-bottom-color: {{ $themeDim }};
|
||||||
border-bottom-color: var(--theme-dim);
|
border-bottom-color: var(--theme-dim);
|
||||||
}
|
}
|
||||||
header .content-title .subtitle {
|
header .content-title .subtitle {
|
||||||
border-top-color: #{{ $themeDim }};
|
border-top-color: {{ $themeDim }};
|
||||||
border-top-color: var(--theme-dim);
|
border-top-color: var(--theme-dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
a, .thread:before, button, .button, input[type=button], input[type=submit] {
|
a, .thread:before, button, .button, input[type=button], input[type=submit] {
|
||||||
color: #{{ $linkColor }};
|
color: {{ $linkColor }};
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
}
|
}
|
||||||
a:hover, button:hover, .button:hover, input[type=button]:hover, input[type=submit]:hover {
|
a:hover, button:hover, .button:hover, input[type=button]:hover, input[type=submit]:hover {
|
||||||
color: #{{ $linkHoverColor }};
|
color: {{ $linkHoverColor }};
|
||||||
color: var(--link-hover-color);
|
color: var(--link-hover-color);
|
||||||
}
|
}
|
||||||
.unread .avatar-icon {
|
.unread .avatar-icon {
|
||||||
border: 2px solid #{{ $linkColor }};
|
border: 2px solid {{ $linkColor }};
|
||||||
border: 2px solid var(--link-color);
|
border: 2px solid var(--link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ all of this CSS.
|
||||||
{% endif %} */
|
{% endif %} */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--background-even-background: #{{ eq .Theme "dark" | ternary (darken .Color 0.8) (brighten .Color 0.9) }};
|
--background-even-background: {{ eq .Theme "dark" | ternary (lightness 0.15 $c) (lightness 0.95 $c) | color2css }};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assets */
|
/* Assets */
|
||||||
|
|
|
@ -67,15 +67,19 @@ func names(ts []*template.Template) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var HMNTemplateFuncs = template.FuncMap{
|
var HMNTemplateFuncs = template.FuncMap{
|
||||||
"brighten": func(hexColor string, amount float64) (string, error) {
|
"alpha": func(alpha float64, color noire.Color) noire.Color {
|
||||||
if len(hexColor) < 6 {
|
color.Alpha = alpha
|
||||||
return "", fmt.Errorf("couldn't brighten invalid hex color: %v", hexColor)
|
return color
|
||||||
}
|
},
|
||||||
return noire.NewHex(hexColor).Tint(amount).Hex(), nil
|
"brighten": func(amount float64, color noire.Color) noire.Color {
|
||||||
|
return color.Tint(amount)
|
||||||
},
|
},
|
||||||
"cachebust": func() string {
|
"cachebust": func() string {
|
||||||
return cachebust
|
return cachebust
|
||||||
},
|
},
|
||||||
|
"color2css": func(color noire.Color) template.CSS {
|
||||||
|
return template.CSS(color.HTML())
|
||||||
|
},
|
||||||
"currentprojecturl": func(url string) string {
|
"currentprojecturl": func(url string) string {
|
||||||
return hmnurl.Url(url, nil) // TODO: Use project subdomain
|
return hmnurl.Url(url, nil) // TODO: Use project subdomain
|
||||||
},
|
},
|
||||||
|
@ -83,11 +87,18 @@ var HMNTemplateFuncs = template.FuncMap{
|
||||||
absUrl := hmnurl.Url(url, nil)
|
absUrl := hmnurl.Url(url, nil)
|
||||||
return fmt.Sprintf("%s?%s", absUrl, query) // TODO: Use project subdomain
|
return fmt.Sprintf("%s?%s", absUrl, query) // TODO: Use project subdomain
|
||||||
},
|
},
|
||||||
"darken": func(hexColor string, amount float64) (string, error) {
|
"darken": func(amount float64, color noire.Color) noire.Color {
|
||||||
if len(hexColor) < 6 {
|
return color.Shade(amount)
|
||||||
return "", fmt.Errorf("couldn't darken invalid hex color: %v", hexColor)
|
},
|
||||||
|
"hex2color": func(hex string) (noire.Color, error) {
|
||||||
|
if len(hex) < 6 {
|
||||||
|
return noire.Color{}, fmt.Errorf("hex color was invalid: %v", hex)
|
||||||
}
|
}
|
||||||
return noire.NewHex(hexColor).Shade(amount).Hex(), nil
|
return noire.NewHex(hex), nil
|
||||||
|
},
|
||||||
|
"lightness": func(lightness float64, color noire.Color) noire.Color {
|
||||||
|
h, s, _, a := color.HSLA()
|
||||||
|
return noire.NewHSLA(h, s, lightness*100, a)
|
||||||
},
|
},
|
||||||
"projecturl": func(url string, proj interface{}) string {
|
"projecturl": func(url string, proj interface{}) string {
|
||||||
return hmnurl.ProjectUrl(url, nil, getProjectSubdomain(proj))
|
return hmnurl.ProjectUrl(url, nil, getProjectSubdomain(proj))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package website
|
package website
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ import (
|
||||||
type LandingTemplateData struct {
|
type LandingTemplateData struct {
|
||||||
templates.BaseData
|
templates.BaseData
|
||||||
|
|
||||||
|
NewsPost LandingPageFeaturedPost
|
||||||
PostColumns [][]LandingPageProject
|
PostColumns [][]LandingPageProject
|
||||||
ShowcaseTimelineJson string
|
ShowcaseTimelineJson string
|
||||||
}
|
}
|
||||||
|
@ -29,7 +31,7 @@ type LandingPageFeaturedPost struct {
|
||||||
User templates.User
|
User templates.User
|
||||||
Date time.Time
|
Date time.Time
|
||||||
Unread bool
|
Unread bool
|
||||||
Content string
|
Content template.HTML
|
||||||
}
|
}
|
||||||
|
|
||||||
func Index(c *RequestContext) ResponseData {
|
func Index(c *RequestContext) ResponseData {
|
||||||
|
@ -67,7 +69,7 @@ func Index(c *RequestContext) ResponseData {
|
||||||
for _, projRow := range allProjects {
|
for _, projRow := range allProjects {
|
||||||
proj := projRow.(*models.Project)
|
proj := projRow.(*models.Project)
|
||||||
|
|
||||||
type ProjectPost struct {
|
type projectPostQuery struct {
|
||||||
Post models.Post `db:"post"`
|
Post models.Post `db:"post"`
|
||||||
Thread models.Thread `db:"thread"`
|
Thread models.Thread `db:"thread"`
|
||||||
Cat models.Category `db:"cat"`
|
Cat models.Category `db:"cat"`
|
||||||
|
@ -75,8 +77,7 @@ func Index(c *RequestContext) ResponseData {
|
||||||
ThreadLastReadTime *time.Time `db:"tlri.lastread"`
|
ThreadLastReadTime *time.Time `db:"tlri.lastread"`
|
||||||
CatLastReadTime *time.Time `db:"clri.lastread"`
|
CatLastReadTime *time.Time `db:"clri.lastread"`
|
||||||
}
|
}
|
||||||
|
projectPostIter, err := db.Query(c.Context(), c.Conn, projectPostQuery{},
|
||||||
projectPostIter, err := db.Query(c.Context(), c.Conn, ProjectPost{},
|
|
||||||
`
|
`
|
||||||
SELECT $columns
|
SELECT $columns
|
||||||
FROM
|
FROM
|
||||||
|
@ -116,7 +117,7 @@ func Index(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, projectPostRow := range projectPosts {
|
for _, projectPostRow := range projectPosts {
|
||||||
projectPost := projectPostRow.(*ProjectPost)
|
projectPost := projectPostRow.(*projectPostQuery)
|
||||||
|
|
||||||
hasRead := false
|
hasRead := false
|
||||||
if projectPost.ThreadLastReadTime != nil && projectPost.ThreadLastReadTime.After(projectPost.Post.PostDate) {
|
if projectPost.ThreadLastReadTime != nil && projectPost.ThreadLastReadTime.After(projectPost.Post.PostDate) {
|
||||||
|
@ -148,20 +149,18 @@ func Index(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
content := contentResult.(*featuredContentResult).Content
|
content := contentResult.(*featuredContentResult).Content
|
||||||
|
|
||||||
// c.Logger.Debug().Str("content", content).Msg("")
|
|
||||||
|
|
||||||
landingPageProject.FeaturedPost = &LandingPageFeaturedPost{
|
landingPageProject.FeaturedPost = &LandingPageFeaturedPost{
|
||||||
Title: projectPost.Thread.Title,
|
Title: projectPost.Thread.Title,
|
||||||
Url: templates.PostUrl(projectPost.Post, projectPost.Cat.Kind, proj.Subdomain()), // TODO
|
Url: templates.PostUrl(projectPost.Post, projectPost.Cat.Kind, proj.Subdomain()),
|
||||||
User: templates.UserToTemplate(&projectPost.User),
|
User: templates.UserToTemplate(&projectPost.User),
|
||||||
Date: projectPost.Post.PostDate,
|
Date: projectPost.Post.PostDate,
|
||||||
Unread: !hasRead,
|
Unread: !hasRead,
|
||||||
Content: content,
|
Content: template.HTML(content),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
landingPageProject.Posts = append(landingPageProject.Posts, templates.PostListItem{
|
landingPageProject.Posts = append(landingPageProject.Posts, templates.PostListItem{
|
||||||
Title: projectPost.Thread.Title,
|
Title: projectPost.Thread.Title,
|
||||||
Url: templates.PostUrl(projectPost.Post, projectPost.Cat.Kind, proj.Subdomain()), // TODO
|
Url: templates.PostUrl(projectPost.Post, projectPost.Cat.Kind, proj.Subdomain()),
|
||||||
User: templates.UserToTemplate(&projectPost.User),
|
User: templates.UserToTemplate(&projectPost.User),
|
||||||
Date: projectPost.Post.PostDate,
|
Date: projectPost.Post.PostDate,
|
||||||
Unread: !hasRead,
|
Unread: !hasRead,
|
||||||
|
@ -230,12 +229,51 @@ func Index(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type newsPostQuery struct {
|
||||||
|
Post models.Post `db:"post"`
|
||||||
|
PostVersion models.PostVersion `db:"ver"`
|
||||||
|
Thread models.Thread `db:"thread"`
|
||||||
|
User models.User `db:"auth_user"`
|
||||||
|
}
|
||||||
|
newsPostRow, err := db.QueryOne(c.Context(), c.Conn, newsPostQuery{},
|
||||||
|
`
|
||||||
|
SELECT $columns
|
||||||
|
FROM
|
||||||
|
handmade_post AS post
|
||||||
|
JOIN handmade_thread AS thread ON post.thread_id = thread.id
|
||||||
|
JOIN handmade_category AS cat ON thread.category_id = cat.id
|
||||||
|
JOIN auth_user ON post.author_id = auth_user.id
|
||||||
|
JOIN handmade_postversion AS ver ON post.current_id = ver.id
|
||||||
|
WHERE
|
||||||
|
cat.project_id = $1
|
||||||
|
AND cat.kind = $2
|
||||||
|
AND post.id = thread.first_id
|
||||||
|
AND thread.moderated = 0
|
||||||
|
ORDER BY post.postdate DESC
|
||||||
|
LIMIT 1
|
||||||
|
`,
|
||||||
|
models.HMNProjectID,
|
||||||
|
models.CatTypeBlog,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news post"))
|
||||||
|
}
|
||||||
|
newsPostResult := newsPostRow.(*newsPostQuery)
|
||||||
|
|
||||||
baseData := getBaseData(c)
|
baseData := getBaseData(c)
|
||||||
baseData.BodyClasses = append(baseData.BodyClasses, "hmdev", "landing") // TODO: Is "hmdev" necessary any more?
|
baseData.BodyClasses = append(baseData.BodyClasses, "hmdev", "landing") // TODO: Is "hmdev" necessary any more?
|
||||||
|
|
||||||
var res ResponseData
|
var res ResponseData
|
||||||
err = res.WriteTemplate("index.html", LandingTemplateData{
|
err = res.WriteTemplate("index.html", LandingTemplateData{
|
||||||
BaseData: getBaseData(c),
|
BaseData: baseData,
|
||||||
|
NewsPost: LandingPageFeaturedPost{
|
||||||
|
Title: newsPostResult.Thread.Title,
|
||||||
|
Url: templates.PostUrl(newsPostResult.Post, models.CatTypeBlog, ""),
|
||||||
|
User: templates.UserToTemplate(&newsPostResult.User),
|
||||||
|
Date: newsPostResult.Post.PostDate,
|
||||||
|
Unread: true, // TODO
|
||||||
|
Content: template.HTML(newsPostResult.PostVersion.TextParsed),
|
||||||
|
},
|
||||||
PostColumns: cols,
|
PostColumns: cols,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue