Fix up landing page colors
This commit is contained in:
parent
a04b00c0a7
commit
292c400dfb
|
@ -7438,6 +7438,15 @@ article code {
|
|||
.mw-site {
|
||||
max-width: 80rem; }
|
||||
|
||||
.mh-3 {
|
||||
max-height: 4rem; }
|
||||
|
||||
.mh-4 {
|
||||
max-height: 8rem; }
|
||||
|
||||
.mh-5 {
|
||||
max-height: 16rem; }
|
||||
|
||||
.mh-100 {
|
||||
max-height: 100%; }
|
||||
|
||||
|
@ -8576,17 +8585,6 @@ input[type=submit] {
|
|||
border-bottom-color: transparent; }
|
||||
.thread .title:hover {
|
||||
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 {
|
||||
width: 50px; }
|
||||
|
||||
|
@ -8598,18 +8596,18 @@ input[type=submit] {
|
|||
overflow: hidden;
|
||||
background-color: #bbb;
|
||||
background-color: var(--dimmest-color); }
|
||||
.thread .avatar-icon:not(.lite) {
|
||||
left: 30px;
|
||||
bottom: 10px; }
|
||||
.thread .info .avatar-icon:not(.lite) {
|
||||
bottom: 0px;
|
||||
left: 0px; }
|
||||
.feed .avatar-icon:not(.lite) {
|
||||
left: -50px;
|
||||
bottom: -10px; }
|
||||
.project .box .avatar-icon:not(.lite) {
|
||||
left: 0px;
|
||||
bottom: -10px; }
|
||||
|
||||
.read {
|
||||
color: #555;
|
||||
color: var(--forum-thread-read-color); }
|
||||
.read td {
|
||||
color: #555;
|
||||
color: var(--forum-thread-read-color); }
|
||||
.read a {
|
||||
color: #888;
|
||||
color: var(--forum-thread-read-link-color); }
|
||||
.read .title {
|
||||
font-weight: 500; }
|
||||
|
||||
.goto {
|
||||
font-size: 200%;
|
||||
|
@ -9220,6 +9218,10 @@ span.icon-rss::before {
|
|||
width: 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 {
|
||||
border-bottom-width: 2px;
|
||||
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()
|
||||
}
|
||||
|
||||
// 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() {
|
||||
case reflect.Int:
|
||||
field.SetInt(reflect.ValueOf(val).Int())
|
||||
field.SetInt(valReflected.Int())
|
||||
default:
|
||||
field.Set(reflect.ValueOf(val))
|
||||
field.Set(valReflected)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -248,6 +248,18 @@ article code {
|
|||
max-width: 80rem;
|
||||
}
|
||||
|
||||
.mh-3 {
|
||||
max-height: $height-3;
|
||||
}
|
||||
|
||||
.mh-4 {
|
||||
max-height: $height-4;
|
||||
}
|
||||
|
||||
.mh-5 {
|
||||
max-height: $height-5;
|
||||
}
|
||||
|
||||
.mh-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 {
|
||||
width: 50px;
|
||||
}
|
||||
|
@ -75,27 +59,21 @@
|
|||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
@include usevar(background-color, dimmest-color);
|
||||
}
|
||||
|
||||
&:not(.lite) {
|
||||
.thread & {
|
||||
left: 30px;
|
||||
bottom: 10px;
|
||||
.read {
|
||||
@include usevar('color', 'forum-thread-read-color');
|
||||
|
||||
td {
|
||||
@include usevar('color', 'forum-thread-read-color');
|
||||
}
|
||||
|
||||
.thread .info & {
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
a {
|
||||
@include usevar('color', 'forum-thread-read-link-color');
|
||||
}
|
||||
|
||||
.feed & {
|
||||
left: -50px;
|
||||
bottom: -10px;
|
||||
}
|
||||
|
||||
.project .box & {
|
||||
left: 0px;
|
||||
bottom: -10px;
|
||||
}
|
||||
.title {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,4 +83,9 @@
|
|||
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.
|
||||
|
||||
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 }}">
|
||||
<div class="flex-grow-1 overflow-hidden">
|
||||
<div class="breadcrumbs">
|
||||
|
|
|
@ -1,5 +1,33 @@
|
|||
{{ 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">
|
||||
|
@ -33,58 +61,41 @@
|
|||
</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">
|
||||
Wow, a featured post!
|
||||
{{/* {% include "blog_index_thread_list_entry.html" with post=featured_post align_top=True %} */}}
|
||||
{{ template "landing_page_featured_post" $newsPost}}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ range $entry := $col }}
|
||||
{{ $proj := $entry.Project }}
|
||||
{{ $posts := $entry.Posts }}
|
||||
<div class="pt3" id="p{{ $proj.Subdomain }}"> {{/* TODO: Is this ID used for anything? */}}
|
||||
<a {{/* TODO: Replace this special-case style with a CSS class */}}
|
||||
<div class="pt3" id="p{{ $proj.Subdomain }}">
|
||||
{{ $c1 := hex2color $proj.Color1 }}
|
||||
<a
|
||||
class="project-title"
|
||||
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>
|
||||
</a>
|
||||
|
||||
{{ with $entry.FeaturedPost }}
|
||||
<div class="flex items-start ph3 pv2">
|
||||
<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>
|
||||
{{ template "landing_page_featured_post" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $post := $posts }}
|
||||
{{ template "post_list_item.html" $post }}
|
||||
{{ end }}
|
||||
{{/*
|
||||
{% 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>
|
||||
<a class="title" href="{{ projecturl "/forums" $proj }}">
|
||||
More posts →
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
*/}}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
@ -94,43 +105,6 @@
|
|||
{{ 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 %}
|
||||
{% include "showcase/js_templates.html" %}
|
||||
{% include "timeline/js_templates.html" %}
|
||||
|
@ -289,3 +263,27 @@
|
|||
{% 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">
|
||||
<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: "{{ . }}";
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ $bgcolor := or .Project.Color1 "999999" }}
|
||||
background-color: #{{ eq .Theme "dark" | ternary (darken $bgcolor 0.6) (brighten $bgcolor 0.6) }};
|
||||
{{ $bgcolor := or .Project.Color1 "999999" | hex2color }}
|
||||
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-size: auto;
|
||||
{{ end }}
|
||||
|
|
|
@ -1,43 +1,44 @@
|
|||
{{ $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) }}
|
||||
{{ $c := hex2color .Color }}
|
||||
{{ $themeDim := eq .Theme "dark" | ternary (lightness 0.35 $c) (lightness 0.75 $c) | color2css }}
|
||||
{{ $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) }}
|
||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (brighten .Color 0.2) (darken .Color 0.1) }}
|
||||
{{ $linkColor := eq .Theme "dark" | ternary (lightness 0.55 $c) (lightness 0.35 $c) | color2css }}
|
||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (lightness 0.65 $c) (lightness 0.45 $c) | color2css }}
|
||||
|
||||
:root {
|
||||
--theme-color: #{{ .Color }};
|
||||
--theme-color-dim: #{{ $themeDim }};
|
||||
--theme-color-dimmer: #{{ $themeDimmer }};
|
||||
--theme-color-dimmest: #{{ $themeDimmest }};
|
||||
--theme-color: {{ $c | color2css }};
|
||||
--theme-color-dim: {{ $themeDim }};
|
||||
--theme-color-dimmer: {{ $themeDimmer }};
|
||||
--theme-color-dimmest: {{ $themeDimmest }};
|
||||
|
||||
--link-color: #{{ $linkColor }};
|
||||
--link-color-hover: #{{ $linkHoverColor }};
|
||||
--link-color: {{ $linkColor }};
|
||||
--link-color-hover: {{ $linkHoverColor }};
|
||||
}
|
||||
|
||||
.accent {
|
||||
background-color: #{{ $themeDim }};
|
||||
background-color: {{ $themeDim }};
|
||||
background-color: var(--theme-dim);
|
||||
}
|
||||
.user-bar {
|
||||
border-bottom-color: #{{ $themeDim }};
|
||||
border-bottom-color: {{ $themeDim }};
|
||||
border-bottom-color: var(--theme-dim);
|
||||
}
|
||||
header .content-title .subtitle {
|
||||
border-top-color: #{{ $themeDim }};
|
||||
border-top-color: {{ $themeDim }};
|
||||
border-top-color: var(--theme-dim);
|
||||
}
|
||||
|
||||
a, .thread:before, button, .button, input[type=button], input[type=submit] {
|
||||
color: #{{ $linkColor }};
|
||||
color: {{ $linkColor }};
|
||||
color: var(--link-color);
|
||||
}
|
||||
a:hover, button:hover, .button:hover, input[type=button]:hover, input[type=submit]:hover {
|
||||
color: #{{ $linkHoverColor }};
|
||||
color: {{ $linkHoverColor }};
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
.unread .avatar-icon {
|
||||
border: 2px solid #{{ $linkColor }};
|
||||
border: 2px solid {{ $linkColor }};
|
||||
border: 2px solid var(--link-color);
|
||||
}
|
||||
|
||||
|
@ -91,7 +92,7 @@ all of this CSS.
|
|||
{% endif %} */
|
||||
|
||||
: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 */
|
||||
|
|
|
@ -67,15 +67,19 @@ func names(ts []*template.Template) []string {
|
|||
}
|
||||
|
||||
var HMNTemplateFuncs = template.FuncMap{
|
||||
"brighten": func(hexColor string, amount float64) (string, error) {
|
||||
if len(hexColor) < 6 {
|
||||
return "", fmt.Errorf("couldn't brighten invalid hex color: %v", hexColor)
|
||||
}
|
||||
return noire.NewHex(hexColor).Tint(amount).Hex(), nil
|
||||
"alpha": func(alpha float64, color noire.Color) noire.Color {
|
||||
color.Alpha = alpha
|
||||
return color
|
||||
},
|
||||
"brighten": func(amount float64, color noire.Color) noire.Color {
|
||||
return color.Tint(amount)
|
||||
},
|
||||
"cachebust": func() string {
|
||||
return cachebust
|
||||
},
|
||||
"color2css": func(color noire.Color) template.CSS {
|
||||
return template.CSS(color.HTML())
|
||||
},
|
||||
"currentprojecturl": func(url string) string {
|
||||
return hmnurl.Url(url, nil) // TODO: Use project subdomain
|
||||
},
|
||||
|
@ -83,11 +87,18 @@ var HMNTemplateFuncs = template.FuncMap{
|
|||
absUrl := hmnurl.Url(url, nil)
|
||||
return fmt.Sprintf("%s?%s", absUrl, query) // TODO: Use project subdomain
|
||||
},
|
||||
"darken": func(hexColor string, amount float64) (string, error) {
|
||||
if len(hexColor) < 6 {
|
||||
return "", fmt.Errorf("couldn't darken invalid hex color: %v", hexColor)
|
||||
"darken": func(amount float64, color noire.Color) noire.Color {
|
||||
return color.Shade(amount)
|
||||
},
|
||||
"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 {
|
||||
return hmnurl.ProjectUrl(url, nil, getProjectSubdomain(proj))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package website
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
type LandingTemplateData struct {
|
||||
templates.BaseData
|
||||
|
||||
NewsPost LandingPageFeaturedPost
|
||||
PostColumns [][]LandingPageProject
|
||||
ShowcaseTimelineJson string
|
||||
}
|
||||
|
@ -29,7 +31,7 @@ type LandingPageFeaturedPost struct {
|
|||
User templates.User
|
||||
Date time.Time
|
||||
Unread bool
|
||||
Content string
|
||||
Content template.HTML
|
||||
}
|
||||
|
||||
func Index(c *RequestContext) ResponseData {
|
||||
|
@ -67,7 +69,7 @@ func Index(c *RequestContext) ResponseData {
|
|||
for _, projRow := range allProjects {
|
||||
proj := projRow.(*models.Project)
|
||||
|
||||
type ProjectPost struct {
|
||||
type projectPostQuery struct {
|
||||
Post models.Post `db:"post"`
|
||||
Thread models.Thread `db:"thread"`
|
||||
Cat models.Category `db:"cat"`
|
||||
|
@ -75,8 +77,7 @@ func Index(c *RequestContext) ResponseData {
|
|||
ThreadLastReadTime *time.Time `db:"tlri.lastread"`
|
||||
CatLastReadTime *time.Time `db:"clri.lastread"`
|
||||
}
|
||||
|
||||
projectPostIter, err := db.Query(c.Context(), c.Conn, ProjectPost{},
|
||||
projectPostIter, err := db.Query(c.Context(), c.Conn, projectPostQuery{},
|
||||
`
|
||||
SELECT $columns
|
||||
FROM
|
||||
|
@ -116,7 +117,7 @@ func Index(c *RequestContext) ResponseData {
|
|||
}
|
||||
|
||||
for _, projectPostRow := range projectPosts {
|
||||
projectPost := projectPostRow.(*ProjectPost)
|
||||
projectPost := projectPostRow.(*projectPostQuery)
|
||||
|
||||
hasRead := false
|
||||
if projectPost.ThreadLastReadTime != nil && projectPost.ThreadLastReadTime.After(projectPost.Post.PostDate) {
|
||||
|
@ -148,20 +149,18 @@ func Index(c *RequestContext) ResponseData {
|
|||
}
|
||||
content := contentResult.(*featuredContentResult).Content
|
||||
|
||||
// c.Logger.Debug().Str("content", content).Msg("")
|
||||
|
||||
landingPageProject.FeaturedPost = &LandingPageFeaturedPost{
|
||||
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),
|
||||
Date: projectPost.Post.PostDate,
|
||||
Unread: !hasRead,
|
||||
Content: content,
|
||||
Content: template.HTML(content),
|
||||
}
|
||||
} else {
|
||||
landingPageProject.Posts = append(landingPageProject.Posts, templates.PostListItem{
|
||||
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),
|
||||
Date: projectPost.Post.PostDate,
|
||||
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.BodyClasses = append(baseData.BodyClasses, "hmdev", "landing") // TODO: Is "hmdev" necessary any more?
|
||||
|
||||
var res ResponseData
|
||||
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,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue