Remove light/dark theme settings entirely
There is simply no need any more; system light/dark preferences handle this fine.
This commit is contained in:
parent
d9073db5d0
commit
04bc4e5035
|
@ -0,0 +1,47 @@
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.handmade.network/hmn/hmn/src/migration/types"
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registerMigration(RemoveDarkTheme{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemoveDarkTheme struct{}
|
||||||
|
|
||||||
|
func (m RemoveDarkTheme) Version() types.MigrationVersion {
|
||||||
|
return types.MigrationVersion(time.Date(2024, 6, 18, 2, 25, 36, 0, time.UTC))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveDarkTheme) Name() string {
|
||||||
|
return "RemoveDarkTheme"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveDarkTheme) Description() string {
|
||||||
|
return "Remove the darktheme field from users"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveDarkTheme) Up(ctx context.Context, tx pgx.Tx) error {
|
||||||
|
_, err := tx.Exec(ctx,
|
||||||
|
`
|
||||||
|
ALTER TABLE hmn_user
|
||||||
|
DROP COLUMN darktheme;
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m RemoveDarkTheme) Down(ctx context.Context, tx pgx.Tx) error {
|
||||||
|
_, err := tx.Exec(ctx,
|
||||||
|
`
|
||||||
|
ALTER TABLE hmn_user
|
||||||
|
ADD COLUMN darktheme BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
|
`,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ type User struct {
|
||||||
Signature string `db:"signature"`
|
Signature string `db:"signature"`
|
||||||
AvatarAssetID *uuid.UUID `db:"avatar_asset_id"`
|
AvatarAssetID *uuid.UUID `db:"avatar_asset_id"`
|
||||||
|
|
||||||
DarkTheme bool `db:"darktheme"`
|
|
||||||
Timezone string `db:"timezone"`
|
Timezone string `db:"timezone"`
|
||||||
|
|
||||||
ShowEmail bool `db:"showemail"`
|
ShowEmail bool `db:"showemail"`
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
|
@ -14,7 +14,7 @@ import (
|
||||||
"git.handmade.network/hmn/hmn/src/models"
|
"git.handmade.network/hmn/hmn/src/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PostToTemplate(p *models.Post, author *models.User, currentTheme string) Post {
|
func PostToTemplate(p *models.Post, author *models.User) Post {
|
||||||
return Post{
|
return Post{
|
||||||
ID: p.ID,
|
ID: p.ID,
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ func PostToTemplate(p *models.Post, author *models.User, currentTheme string) Po
|
||||||
Preview: p.Preview,
|
Preview: p.Preview,
|
||||||
ReadOnly: p.ReadOnly,
|
ReadOnly: p.ReadOnly,
|
||||||
|
|
||||||
Author: UserToTemplate(author, currentTheme),
|
Author: UserToTemplate(author),
|
||||||
// No content. A lot of the time we don't have this handy and don't need it. See AddContentVersion.
|
// No content. A lot of the time we don't have this handy and don't need it. See AddContentVersion.
|
||||||
PostDate: p.PostDate,
|
PostDate: p.PostDate,
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ func (p *Post) AddContentVersion(ver models.PostVersion, editor *models.User) {
|
||||||
p.IP = maybeIp(ver.IP)
|
p.IP = maybeIp(ver.IP)
|
||||||
|
|
||||||
if editor != nil {
|
if editor != nil {
|
||||||
editorTmpl := UserToTemplate(editor, "theme not required here")
|
editorTmpl := UserToTemplate(editor)
|
||||||
p.Editor = &editorTmpl
|
p.Editor = &editorTmpl
|
||||||
p.EditDate = ver.Date
|
p.EditDate = ver.Date
|
||||||
p.EditReason = ver.EditReason
|
p.EditReason = ver.EditReason
|
||||||
|
@ -61,15 +61,13 @@ var LifecycleBadgeStrings = map[models.ProjectLifecycle]string{
|
||||||
models.ProjectLifecycleLTS: "Complete",
|
models.ProjectLifecycleLTS: "Complete",
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectLogoUrl(p *models.Project, lightAsset *models.Asset, darkAsset *models.Asset, theme string) string {
|
// TODO(redesign): Remove one or the other of these from the database entirely.
|
||||||
if theme == "dark" {
|
func ProjectLogoUrl(p *models.Project, lightAsset *models.Asset, darkAsset *models.Asset) string {
|
||||||
if darkAsset != nil {
|
|
||||||
return hmnurl.BuildS3Asset(darkAsset.S3Key)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if lightAsset != nil {
|
if lightAsset != nil {
|
||||||
return hmnurl.BuildS3Asset(lightAsset.S3Key)
|
return hmnurl.BuildS3Asset(lightAsset.S3Key)
|
||||||
}
|
}
|
||||||
|
if darkAsset != nil {
|
||||||
|
return hmnurl.BuildS3Asset(darkAsset.S3Key)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -100,11 +98,11 @@ func ProjectToTemplate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectAndStuffToTemplate(p *hmndata.ProjectAndStuff, url string, theme string) Project {
|
func ProjectAndStuffToTemplate(p *hmndata.ProjectAndStuff, url string) Project {
|
||||||
res := ProjectToTemplate(&p.Project, url)
|
res := ProjectToTemplate(&p.Project, url)
|
||||||
res.Logo = ProjectLogoUrl(&p.Project, p.LogoLightAsset, p.LogoDarkAsset, theme)
|
res.Logo = ProjectLogoUrl(&p.Project, p.LogoLightAsset, p.LogoDarkAsset)
|
||||||
for _, o := range p.Owners {
|
for _, o := range p.Owners {
|
||||||
res.Owners = append(res.Owners, UserToTemplate(o, theme))
|
res.Owners = append(res.Owners, UserToTemplate(o))
|
||||||
}
|
}
|
||||||
if p.HeaderImage != nil {
|
if p.HeaderImage != nil {
|
||||||
res.HeaderImage = hmnurl.BuildS3Asset(p.HeaderImage.S3Key)
|
res.HeaderImage = hmnurl.BuildS3Asset(p.HeaderImage.S3Key)
|
||||||
|
@ -133,11 +131,10 @@ func ProjectToProjectSettings(
|
||||||
owners []*models.User,
|
owners []*models.User,
|
||||||
tag string,
|
tag string,
|
||||||
lightLogo, darkLogo, headerImage *models.Asset,
|
lightLogo, darkLogo, headerImage *models.Asset,
|
||||||
currentTheme string,
|
|
||||||
) ProjectSettings {
|
) ProjectSettings {
|
||||||
ownerUsers := make([]User, 0, len(owners))
|
ownerUsers := make([]User, 0, len(owners))
|
||||||
for _, owner := range owners {
|
for _, owner := range owners {
|
||||||
ownerUsers = append(ownerUsers, UserToTemplate(owner, currentTheme))
|
ownerUsers = append(ownerUsers, UserToTemplate(owner))
|
||||||
}
|
}
|
||||||
return ProjectSettings{
|
return ProjectSettings{
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
|
@ -187,28 +184,23 @@ func ThreadToTemplate(t *models.Thread) Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserAvatarDefaultUrl(currentTheme string) string {
|
func UserAvatarDefaultUrl(theme string) string {
|
||||||
return hmnurl.BuildTheme("empty-avatar.svg", currentTheme, true)
|
return hmnurl.BuildTheme("empty-avatar.svg", theme, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserAvatarUrl(u *models.User, currentTheme string) string {
|
func UserAvatarUrl(u *models.User) string {
|
||||||
if currentTheme == "" {
|
|
||||||
currentTheme = "light"
|
|
||||||
}
|
|
||||||
avatar := ""
|
avatar := ""
|
||||||
if u != nil && u.AvatarAsset != nil {
|
if u != nil && u.AvatarAsset != nil {
|
||||||
avatar = hmnurl.BuildS3Asset(u.AvatarAsset.S3Key)
|
avatar = hmnurl.BuildS3Asset(u.AvatarAsset.S3Key)
|
||||||
} else {
|
|
||||||
avatar = UserAvatarDefaultUrl(currentTheme)
|
|
||||||
}
|
}
|
||||||
return avatar
|
return avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
func UserToTemplate(u *models.User, currentTheme string) User {
|
func UserToTemplate(u *models.User) User {
|
||||||
if u == nil {
|
if u == nil {
|
||||||
return User{
|
return User{
|
||||||
Name: "Deleted user",
|
Name: "Deleted user",
|
||||||
AvatarUrl: UserAvatarUrl(nil, currentTheme),
|
AvatarUrl: UserAvatarUrl(nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,9 +223,8 @@ func UserToTemplate(u *models.User, currentTheme string) User {
|
||||||
Signature: u.Signature,
|
Signature: u.Signature,
|
||||||
DateJoined: u.DateJoined,
|
DateJoined: u.DateJoined,
|
||||||
ProfileUrl: hmnurl.BuildUserProfile(u.Username),
|
ProfileUrl: hmnurl.BuildUserProfile(u.Username),
|
||||||
AvatarUrl: UserAvatarUrl(u, currentTheme),
|
AvatarUrl: UserAvatarUrl(u),
|
||||||
|
|
||||||
DarkTheme: u.DarkTheme,
|
|
||||||
Timezone: u.Timezone,
|
Timezone: u.Timezone,
|
||||||
|
|
||||||
DiscordSaveShowcase: u.DiscordSaveShowcase,
|
DiscordSaveShowcase: u.DiscordSaveShowcase,
|
||||||
|
@ -246,7 +237,7 @@ func UserToTemplate(u *models.User, currentTheme string) User {
|
||||||
|
|
||||||
var UnknownUser = User{
|
var UnknownUser = User{
|
||||||
Name: "Unknown User",
|
Name: "Unknown User",
|
||||||
AvatarUrl: UserAvatarUrl(nil, ""),
|
AvatarUrl: UserAvatarUrl(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
// An online site/service for which we recognize the link
|
// An online site/service for which we recognize the link
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
{{ template "base.html" . }}
|
{{ template "base.html" . }}
|
||||||
|
|
||||||
{{ define "extrahead" }}
|
{{ define "extrahead" }}
|
||||||
<link rel="stylesheet" href="{{ static (eq .Theme "dark" | ternary "fishbowl-dark.css" "fishbowl-light.css") }}">
|
<!-- TODO(redesign): Adapt these stylesheets to use media queries and variables -->
|
||||||
|
<link rel="stylesheet" href="fishbowl-dark.css">
|
||||||
|
<!-- <link rel="stylesheet" href="fishbowl-light.css"> -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function scrollToMessage(event, id) {
|
function scrollToMessage(event, id) {
|
||||||
|
@ -40,15 +42,20 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.fishbowl-banner {
|
.fishbowl-banner {
|
||||||
background-color: {{ eq .Theme "dark" | ternary "#254464" "#a0c8f2" }};
|
/* TODO(redesign) */
|
||||||
background-image: url({{ static (eq .Theme "dark" | ternary "waterline-dark.svg" "waterline-light.svg") }});
|
background-color: #254464;
|
||||||
|
/* background-color: #a0c8f2; */
|
||||||
|
background-image: url({{ static "waterline-dark.svg" }});
|
||||||
|
/* background-image: url({{ static "waterline-light.svg" }}); */
|
||||||
background-size: 734px 30px;
|
background-size: 734px 30px;
|
||||||
background-repeat: repeat-x;
|
background-repeat: repeat-x;
|
||||||
padding-top: 30px;
|
padding-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fishbowl-banner a {
|
.fishbowl-banner a {
|
||||||
color: {{ eq .Theme "dark" | ternary "#9ad0ff" "#1f4f99" }};
|
/* TODO(redesign) */
|
||||||
|
color: #9ad0ff;
|
||||||
|
/* color: #1f4f99; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.fishbowl .chatlog__author a {
|
.fishbowl .chatlog__author a {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<script src="{{ static "js/showcase.js" }}"></script>
|
||||||
|
|
||||||
|
<template id="showcase_item">
|
||||||
|
<div data-tmpl="container" class="showcase-item ba b--theme flex-shrink-0 bg-dark-gray hide-child relative overflow-hidden pointer">
|
||||||
|
<div data-tmpl="thumbnail" class="absolute absolute--fill z-0 flex justify-start items-center bg-left cover"></div>
|
||||||
|
<div class="overlay absolute absolute--fill z-1 child">
|
||||||
|
<div class="gradient relative">
|
||||||
|
<div class="user-info flex pa2 white f7 lh-title items-center">
|
||||||
|
<div data-tmpl="avatar" class="br-100 w2 h2 cover flex-shrink-0"></div>
|
||||||
|
<div class="flex-grow-1 flex flex-column pl1">
|
||||||
|
<div data-tmpl="username">Unknown User</div>
|
||||||
|
<div data-tmpl="when" class="i f8">Unknown Time</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="timeline_modal">
|
||||||
|
<div data-tmpl="overlay" class="timeline-modal fixed absolute--fill bg-black-80 z-999 flex flex-column justify-center items-center">
|
||||||
|
<div data-tmpl="container" class="container timeline-item relative flex-shrink-0 shadow-1 flex flex-column items-stretch w-100 mh0 mh3-ns br2-ns overflow-hidden">
|
||||||
|
<div data-tmpl="asset_container" class="bg-dark-gray flex justify-center"></div>
|
||||||
|
<div class="bg--content pa3 overflow-y-auto">
|
||||||
|
<div class="timeline-user-info mb2 flex items-center">
|
||||||
|
<img class="avatar lite mr2" data-tmpl="avatar"/>
|
||||||
|
<a class="user" data-tmpl="userLink"></a>
|
||||||
|
<a data-tmpl="date" class="datetime tr" style="flex: 1 1 auto;"></a>
|
||||||
|
</div>
|
||||||
|
<div class="overflow-auto" data-tmpl="description">
|
||||||
|
Unknown description
|
||||||
|
</div>
|
||||||
|
<div data-tmpl="projects" class="pt2 flex g2"></div>
|
||||||
|
<div class="i f7 pt2">
|
||||||
|
<a data-tmpl="discord_link" target="_blank">View original message on Discord</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div data-tmpl="close" class="absolute right-0 top-0 w2 h2 flex justify-center items-center bg-black-80 white br-100 ma1 pointer svgicon svgicon-nofix">{{ svg "close" }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="project_link">
|
||||||
|
<a data-tmpl="root" class="snippet-project flex flex-row items-center bg-theme-dimmer ph2 pv1 br2">
|
||||||
|
<img data-tmpl="logo" class="db mr1 br1 h1-5" />
|
||||||
|
<div data-tmpl="name"></div>
|
||||||
|
</a>
|
||||||
|
</template>
|
|
@ -22,26 +22,6 @@
|
||||||
<link href='https://fonts.googleapis.com/css?family=Fira+Mono:300,400,500,700' rel='stylesheet' type='text/css'>
|
<link href='https://fonts.googleapis.com/css?family=Fira+Mono:300,400,500,700' rel='stylesheet' type='text/css'>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ static "style.css" }}" />
|
<link rel="stylesheet" type="text/css" href="{{ static "style.css" }}" />
|
||||||
|
|
||||||
{{/* TODO: These are the base64 encodings of bglight.png and bgdark.png. Rather than manually putting the encoding here, it would be nice to automatically calculate it when the server starts up and pass it in. */}}
|
|
||||||
{{ $bglight := "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAEGGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjcyIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNzIiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iNzIiCiAgIHRpZmY6SW1hZ2VMZW5ndGg9IjcyIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0aW9uPSI5Ni4wIgogICB0aWZmOllSZXNvbHV0aW9uPSI5Ni4wIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjcuMSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xMVQyMToyMjozMC0wNjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+NRFFrAAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZG/S0JRFMc/amGUYZBDQ4NENVmUgdTSoJQF1WAG/Vr05Y9A7fGeEdIatAoFUUu/hvoLag2ag6AogmgLmotaSl7n+QQl8l7OOZ/7vfcc7j0X7NGMktUbBiCby2uRcNA7v7Dodb7iwCXmwRNTdHV6djxK3fH1gM2Md31mrfrn/h0tKwldAVuT8KiiannhCeGpjbxq8q6wR0nHVoTPhX2aXFD43tTjFr+ZnLL4x2QtGgmBvU3Ym6rheA0raS0rLC+nO5tZVyr3MV/iSuTmZiV2iXWiEyFMEC+TjBEiwCAj4gP04adfVtTJHyjnz7AmuYp4lQIaq6RIk8cn6rpUT0hMip6QmaFg9v9vX/XkkN+q7gpC44thfPSAcwdKRcP4PjaM0gk4nuEqV81fO4LhT9GLVa37ENxbcHFd1eJ7cLkNHU9qTIuVJYeYPZmE9zNoXYD2W2hesnpW2ef0EaKb8lU3sH8AvXLevfwLEU5nv19tQRgAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAJOSURBVHic7ZtRksMgCIaTPOcI3v9MPYBHyHv2obOZTlIVFeSHyltnm38QCehXdo0xnkulHcex7Pue/OxJZ20JUE7Um86W+wKHM1w6IYRVw59sBqHtagihO+Nr/Xlk0GeE930nRTzlBIfOZ+bEGE9KJnH68wjQ/eHWxXHp3IPSGqRWf64A5R6uWRyXTi4oNUHq9ecKUOlh6uK4dEpBoQap159H0UM7m9wLc2uhbvVn1qCCJXdjtvi3JQ+K1AiXdpOqU/oONXNKOrX+dO2K1q6O1Nl6DnD34tnrzP9nJJ3NYmcZqfP1oJizUnBqDnC5RdUcTCV1tm9/TBklOJRMoiyK4s8InfX1ep3zNUvrzBpU0Olu095bfRdRpATHOpk0RRQ1ri3wRFGbTMLf5rWpACxRRCGTsEQRhUzCE0VtMjlrUMHMEEUtMtlNFLkJnrROLZnsuiagZQcUUUQngapEEa1DQRFFKySQS6eKKFoigVw6zUTRwuuhRhTRFwVFFJFbNIdO8qCoNROIppPNIO+8mWKPDNKeCUTTeQRIex4HTecKEMpMIJrOFSCUmUA0nUcR/qVfTSk6swYVLJkds8W/LXlQ1JoJ7NXhnpl0RRQlst4NUZSamXRxm5fsvOaJovTMpGmiOGJm0g1RlHrNZg0q+OOOKHK3evH/eh5JJiVmJofMKFq+tojNKHohk2LzQV6oAPuMojcyyT6j6I1Mis0oeiGTswYVTHxG0XKLX5YBM4pWyaRLoiih44YoSum4uM1L6pgnitI6poniCB03RFFK5w8yFS9yPecAUAAAAABJRU5ErkJggg==" }}
|
|
||||||
{{ $bgdark := "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAEGGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjcyIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNzIiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iNzIiCiAgIHRpZmY6SW1hZ2VMZW5ndGg9IjcyIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIgogICB0aWZmOlhSZXNvbHV0aW9uPSI5Ni4wIgogICB0aWZmOllSZXNvbHV0aW9uPSI5Ni4wIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InByb2R1Y2VkIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZmZpbml0eSBQaG90byAxLjcuMSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMS0wMy0xMVQyMToyMzoxNS0wNjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+87tjqAAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZG/S0JRFMc/amGUYZBDQ4NENVmUgdTSoJQF1WAG/Vr05Y9A7fGeEdIatAoFUUu/hvoLag2ag6AogmgLmotaSl7n+QQl8l7OOZ/7vfcc7j0X7NGMktUbBiCby2uRcNA7v7Dodb7iwCXmwRNTdHV6djxK3fH1gM2Md31mrfrn/h0tKwldAVuT8KiiannhCeGpjbxq8q6wR0nHVoTPhX2aXFD43tTjFr+ZnLL4x2QtGgmBvU3Ym6rheA0raS0rLC+nO5tZVyr3MV/iSuTmZiV2iXWiEyFMEC+TjBEiwCAj4gP04adfVtTJHyjnz7AmuYp4lQIaq6RIk8cn6rpUT0hMip6QmaFg9v9vX/XkkN+q7gpC44thfPSAcwdKRcP4PjaM0gk4nuEqV81fO4LhT9GLVa37ENxbcHFd1eJ7cLkNHU9qTIuVJYeYPZmE9zNoXYD2W2hesnpW2ef0EaKb8lU3sH8AvXLevfwLEU5nv19tQRgAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAJSSURBVHic7ZvBbsMgDIaTHKbtnNO0vf/bcW7VS3uoFlWhgAEb//bwrVrzyxjHhq/euu/7fam0z4+v5Xq7JD970llbApQT9aaz5b7A4QyXTghh1fAnm0FouxpC6M74Wn+iDHqN8PV2IUU85QSHzmvm7Pt+p2QSpz9RgM4Pty6OS+cclNYgtfpzBCj3cM3iuHRyQakJUq8/R4BKD1MXx6VTCgo1SL3+REUP7WxyLsythbrVn1mDCpbcjdnin5Y8KFIjXNpNqk7pO9TMKenU+tO1K1q7OlJn6znAnYtnrzN/n5F0NoudZaTO24NizkrBqTnA5RZVczCV1Nne/TFllOBQMomyKIo/I3TWn+/f+3zN0jqzBhV0utu091bfRRQpwbFOJk0RRY1rCzxR1CaT8Ld5bSoASxRRyCQsUUQhk/BEUZtMzhpUMDNEUYtMdhNFboInrVNLJruuCWjZAUUU0UmgKlFE61BQRNEKCeTSqSKKlkggl04zUbTweqgRRfRFQRFF5BbNoZM8KGrNBKLpZDPIO2+mWJRB2jOBaDpRgLTncdB0jgChzASi6RwBQpkJRNOJivB/+tWUojNrUMGS2TFb/NOSB0WtmcBeHe6ZSVdEUSLr3RBFqZlJF7d5yc5rnihKz0yaJoojZibdEEWp12zWoII/7ogid6sX/6/nkWRSYmZyyIyi5WuL2IyiFzIpNh/khQqwzyh6I5PsM4reyKTYjKIXMjlrUMHEZxQtt/hlGTCjaJVMuiSKEjpuiKKUjovbvKSOeaIorWOaKI7QcUMUpXQe+31Pc6xeN0AAAAAASUVORK5CYII=" }}
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
{{ if .BackgroundImage.Url }}
|
|
||||||
background-image: url("{{ .BackgroundImage.Url }}?v={{ .BackgroundImage.Size }}");
|
|
||||||
background-attachment: fixed;
|
|
||||||
{{ with .BackgroundImage.Size }}
|
|
||||||
background-size: "{{ . }}";
|
|
||||||
{{ end }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $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 }}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ .ProjectCSSUrl }}" />
|
<link rel="stylesheet" href="{{ .ProjectCSSUrl }}" />
|
||||||
<link rel="apple-touch-icon" sizes="400x400" href="{{ static "logo.png" }}">
|
<link rel="apple-touch-icon" sizes="400x400" href="{{ static "logo.png" }}">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ static "favicon-16x16.png" }}">
|
<link rel="icon" type="image/png" sizes="16x16" href="{{ static "favicon-16x16.png" }}">
|
||||||
|
|
|
@ -37,14 +37,15 @@
|
||||||
/* Copy-paste from project.css yay */
|
/* Copy-paste from project.css yay */
|
||||||
{{ $c := hex2color "C8217E" }}
|
{{ $c := hex2color "C8217E" }}
|
||||||
|
|
||||||
{{ $themeDim := eq .Theme "dark" | ternary (lightness 0.35 $c) (lightness 0.75 $c) | color2css }}
|
{{/* In the 2024 redesign, these were all forced to use the dark theme variants. */}}
|
||||||
{{ $themeDimmer := eq .Theme "dark" | ternary (lightness 0.3 $c) (lightness 0.8 $c) | color2css }}
|
{{ $themeDim := lightness 0.35 $c | color2css }}
|
||||||
{{ $themeDimmest := eq .Theme "dark" | ternary (lightness 0.2 $c) (lightness 0.85 $c) | color2css }}
|
{{ $themeDimmer := lightness 0.3 $c | color2css }}
|
||||||
|
{{ $themeDimmest := lightness 0.2 $c | color2css }}
|
||||||
|
|
||||||
{{ $themeDark := eq .Theme "dark" | ternary (lightness 0.30 $c) (lightness 0.35 $c) | color2css }}
|
{{ $themeDark := lightness 0.30 $c | color2css }}
|
||||||
|
|
||||||
{{ $linkColor := eq .Theme "dark" | ternary (lightness 0.55 $c) (lightness 0.35 $c) | color2css }}
|
{{ $linkColor := lightness 0.55 $c | color2css }}
|
||||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (lightness 0.65 $c) (lightness 0.45 $c) | color2css }}
|
{{ $linkHoverColor := lightness 0.65 $c | color2css }}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--content-background: #f8f8f8;
|
--content-background: #f8f8f8;
|
||||||
|
|
|
@ -37,14 +37,15 @@
|
||||||
/* Copy-paste from project.css yay */
|
/* Copy-paste from project.css yay */
|
||||||
{{ $c := hex2color "346ba6" }}
|
{{ $c := hex2color "346ba6" }}
|
||||||
|
|
||||||
{{ $themeDim := eq .Theme "dark" | ternary (lightness 0.35 $c) (lightness 0.75 $c) | color2css }}
|
{{/* In the 2024 redesign, these were all forced to use the dark theme variants. */}}
|
||||||
{{ $themeDimmer := eq .Theme "dark" | ternary (lightness 0.3 $c) (lightness 0.8 $c) | color2css }}
|
{{ $themeDim := lightness 0.35 $c | color2css }}
|
||||||
{{ $themeDimmest := eq .Theme "dark" | ternary (lightness 0.2 $c) (lightness 0.85 $c) | color2css }}
|
{{ $themeDimmer := lightness 0.3 $c | color2css }}
|
||||||
|
{{ $themeDimmest := lightness 0.2 $c | color2css }}
|
||||||
|
|
||||||
{{ $themeDark := eq .Theme "dark" | ternary (lightness 0.30 $c) (lightness 0.35 $c) | color2css }}
|
{{ $themeDark := lightness 0.30 $c | color2css }}
|
||||||
|
|
||||||
{{ $linkColor := eq .Theme "dark" | ternary (lightness 0.55 $c) (lightness 0.35 $c) | color2css }}
|
{{ $linkColor := lightness 0.55 $c | color2css }}
|
||||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (lightness 0.65 $c) (lightness 0.45 $c) | color2css }}
|
{{ $linkHoverColor := lightness 0.65 $c | color2css }}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--content-background: #f8f8f8;
|
--content-background: #f8f8f8;
|
||||||
|
|
|
@ -38,14 +38,15 @@
|
||||||
{{/* {{ $c := hex2color "23CE76" }} */}}
|
{{/* {{ $c := hex2color "23CE76" }} */}}
|
||||||
{{ $c := hex2color "1DB768" }}{{/* modified for contrast reasons */}}
|
{{ $c := hex2color "1DB768" }}{{/* modified for contrast reasons */}}
|
||||||
|
|
||||||
{{ $themeDim := eq .Theme "dark" | ternary (lightness 0.35 $c) (lightness 0.75 $c) | color2css }}
|
{{/* In the 2024 redesign, these were all forced to use the dark theme variants. */}}
|
||||||
{{ $themeDimmer := eq .Theme "dark" | ternary (lightness 0.3 $c) (lightness 0.8 $c) | color2css }}
|
{{ $themeDim := lightness 0.35 $c | color2css }}
|
||||||
{{ $themeDimmest := eq .Theme "dark" | ternary (lightness 0.2 $c) (lightness 0.85 $c) | color2css }}
|
{{ $themeDimmer := lightness 0.3 $c | color2css }}
|
||||||
|
{{ $themeDimmest := lightness 0.2 $c | color2css }}
|
||||||
|
|
||||||
{{ $themeDark := eq .Theme "dark" | ternary (lightness 0.30 $c) (lightness 0.35 $c) | color2css }}
|
{{ $themeDark := lightness 0.30 $c | color2css }}
|
||||||
|
|
||||||
{{ $linkColor := eq .Theme "dark" | ternary (lightness 0.55 $c) (lightness 0.35 $c) | color2css }}
|
{{ $linkColor := lightness 0.55 $c | color2css }}
|
||||||
{{ $linkHoverColor := eq .Theme "dark" | ternary (lightness 0.65 $c) (lightness 0.45 $c) | color2css }}
|
{{ $linkHoverColor := lightness 0.65 $c | color2css }}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--content-background: #f8f8f8;
|
--content-background: #f8f8f8;
|
||||||
|
|
|
@ -33,13 +33,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-form-row">
|
|
||||||
<div>Theme:</div>
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" name="darktheme" id="darktheme" {{ if .User.DarkTheme }}checked{{ end }} />
|
|
||||||
<label for="darktheme">Use dark theme</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="edit-form-row">
|
<div class="edit-form-row">
|
||||||
<div>Avatar:</div>
|
<div>Avatar:</div>
|
||||||
<div class="user_avatar">
|
<div class="user_avatar">
|
||||||
|
@ -52,7 +45,6 @@
|
||||||
document.querySelector("#user_form"),
|
document.querySelector("#user_form"),
|
||||||
avatarMaxFileSize,
|
avatarMaxFileSize,
|
||||||
document.querySelector(".user_avatar"),
|
document.querySelector(".user_avatar"),
|
||||||
{{ .DefaultAvatarUrl }}
|
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,6 @@ type BaseData struct {
|
||||||
CanonicalLink string
|
CanonicalLink string
|
||||||
OpenGraphItems []OpenGraphItem
|
OpenGraphItems []OpenGraphItem
|
||||||
BackgroundImage BackgroundImage
|
BackgroundImage BackgroundImage
|
||||||
Theme string
|
|
||||||
BodyClasses []string
|
BodyClasses []string
|
||||||
Breadcrumbs []Breadcrumb
|
Breadcrumbs []Breadcrumb
|
||||||
Notices []Notice
|
Notices []Notice
|
||||||
|
@ -205,7 +204,6 @@ type User struct {
|
||||||
AvatarUrl string
|
AvatarUrl string
|
||||||
ProfileUrl string
|
ProfileUrl string
|
||||||
|
|
||||||
DarkTheme bool
|
|
||||||
ShowEmail bool
|
ShowEmail bool
|
||||||
Timezone string
|
Timezone string
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@ func AdminAtomFeed(c *RequestContext) ResponseData {
|
||||||
&post.Author,
|
&post.Author,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
c.Theme,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
postItem.PostTypePrefix = fmt.Sprintf("ADMIN::UNAPPROVED: %s", postItem.PostTypePrefix)
|
postItem.PostTypePrefix = fmt.Sprintf("ADMIN::UNAPPROVED: %s", postItem.PostTypePrefix)
|
||||||
|
@ -177,7 +176,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
userData = unapprovedUsers[idx]
|
userData = unapprovedUsers[idx]
|
||||||
} else {
|
} else {
|
||||||
userData = &unapprovedUserData{
|
userData = &unapprovedUserData{
|
||||||
User: templates.UserToTemplate(s.Owner, c.Theme),
|
User: templates.UserToTemplate(s.Owner),
|
||||||
UserLinks: make([]templates.Link, 0, 10),
|
UserLinks: make([]templates.Link, 0, 10),
|
||||||
}
|
}
|
||||||
unapprovedUsers = append(unapprovedUsers, userData)
|
unapprovedUsers = append(unapprovedUsers, userData)
|
||||||
|
@ -187,7 +186,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
if s.Snippet.When.After(userData.Date) {
|
if s.Snippet.When.After(userData.Date) {
|
||||||
userData.Date = s.Snippet.When
|
userData.Date = s.Snippet.When
|
||||||
}
|
}
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.OwnerAvatarUrl = ""
|
timelineItem.OwnerAvatarUrl = ""
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
userData.Timeline = append(userData.Timeline, timelineItem)
|
userData.Timeline = append(userData.Timeline, timelineItem)
|
||||||
|
@ -199,7 +198,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
userData = unapprovedUsers[idx]
|
userData = unapprovedUsers[idx]
|
||||||
} else {
|
} else {
|
||||||
userData = &unapprovedUserData{
|
userData = &unapprovedUserData{
|
||||||
User: templates.UserToTemplate(&p.Author, c.Theme),
|
User: templates.UserToTemplate(&p.Author),
|
||||||
UserLinks: make([]templates.Link, 0, 10),
|
UserLinks: make([]templates.Link, 0, 10),
|
||||||
}
|
}
|
||||||
unapprovedUsers = append(unapprovedUsers, userData)
|
unapprovedUsers = append(unapprovedUsers, userData)
|
||||||
|
@ -209,7 +208,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
if p.Post.PostDate.After(userData.Date) {
|
if p.Post.PostDate.After(userData.Date) {
|
||||||
userData.Date = p.Post.PostDate
|
userData.Date = p.Post.PostDate
|
||||||
}
|
}
|
||||||
timelineItem := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, &p.Author, c.Theme)
|
timelineItem := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, &p.Author)
|
||||||
timelineItem.OwnerAvatarUrl = ""
|
timelineItem.OwnerAvatarUrl = ""
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
timelineItem.Description = template.HTML(p.CurrentVersion.TextParsed)
|
timelineItem.Description = template.HTML(p.CurrentVersion.TextParsed)
|
||||||
|
@ -222,7 +221,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
userData = unapprovedUsers[idx]
|
userData = unapprovedUsers[idx]
|
||||||
} else {
|
} else {
|
||||||
userData = &unapprovedUserData{
|
userData = &unapprovedUserData{
|
||||||
User: templates.UserToTemplate(p.User, c.Theme),
|
User: templates.UserToTemplate(p.User),
|
||||||
UserLinks: make([]templates.Link, 0, 10),
|
UserLinks: make([]templates.Link, 0, 10),
|
||||||
}
|
}
|
||||||
unapprovedUsers = append(unapprovedUsers, userData)
|
unapprovedUsers = append(unapprovedUsers, userData)
|
||||||
|
@ -237,7 +236,7 @@ func AdminApprovalQueue(c *RequestContext) ResponseData {
|
||||||
userData.Date = p.ProjectAndStuff.Project.DateCreated
|
userData.Date = p.ProjectAndStuff.Project.DateCreated
|
||||||
}
|
}
|
||||||
userData.ProjectsWithLinks = append(userData.ProjectsWithLinks, projectWithLinks{
|
userData.ProjectsWithLinks = append(userData.ProjectsWithLinks, projectWithLinks{
|
||||||
Project: templates.ProjectAndStuffToTemplate(p.ProjectAndStuff, hmndata.UrlContextForProject(&p.ProjectAndStuff.Project).BuildHomepage(), c.Theme),
|
Project: templates.ProjectAndStuffToTemplate(p.ProjectAndStuff, hmndata.UrlContextForProject(&p.ProjectAndStuff.Project).BuildHomepage()),
|
||||||
Links: projectLinks,
|
Links: projectLinks,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
||||||
var templateUser *templates.User
|
var templateUser *templates.User
|
||||||
var templateSession *templates.Session
|
var templateSession *templates.Session
|
||||||
if c.CurrentUser != nil {
|
if c.CurrentUser != nil {
|
||||||
u := templates.UserToTemplate(c.CurrentUser, c.Theme)
|
u := templates.UserToTemplate(c.CurrentUser)
|
||||||
s := templates.SessionToTemplate(c.CurrentSession)
|
s := templates.SessionToTemplate(c.CurrentSession)
|
||||||
templateUser = &u
|
templateUser = &u
|
||||||
templateSession = &s
|
templateSession = &s
|
||||||
|
@ -44,7 +44,6 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
||||||
}
|
}
|
||||||
|
|
||||||
baseData := templates.BaseData{
|
baseData := templates.BaseData{
|
||||||
Theme: c.Theme,
|
|
||||||
Title: title,
|
Title: title,
|
||||||
Breadcrumbs: breadcrumbs,
|
Breadcrumbs: breadcrumbs,
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ func BlogIndex(c *RequestContext) ResponseData {
|
||||||
entries = append(entries, blogIndexEntry{
|
entries = append(entries, blogIndexEntry{
|
||||||
Title: thread.Thread.Title,
|
Title: thread.Thread.Title,
|
||||||
Url: c.UrlContext.BuildBlogThread(thread.Thread.ID, thread.Thread.Title),
|
Url: c.UrlContext.BuildBlogThread(thread.Thread.ID, thread.Thread.Title),
|
||||||
Author: templates.UserToTemplate(thread.FirstPostAuthor, c.Theme),
|
Author: templates.UserToTemplate(thread.FirstPostAuthor),
|
||||||
Date: thread.FirstPost.PostDate,
|
Date: thread.FirstPost.PostDate,
|
||||||
Content: template.HTML(thread.FirstPostCurrentVersion.TextParsed),
|
Content: template.HTML(thread.FirstPostCurrentVersion.TextParsed),
|
||||||
})
|
})
|
||||||
|
@ -140,12 +140,12 @@ func BlogThread(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
var templatePosts []templates.Post
|
var templatePosts []templates.Post
|
||||||
for _, p := range posts {
|
for _, p := range posts {
|
||||||
post := templates.PostToTemplate(&p.Post, p.Author, c.Theme)
|
post := templates.PostToTemplate(&p.Post, p.Author)
|
||||||
post.AddContentVersion(p.CurrentVersion, p.Editor)
|
post.AddContentVersion(p.CurrentVersion, p.Editor)
|
||||||
addBlogUrlsToPost(c.UrlContext, &post, &p.Thread, p.Post.ID)
|
addBlogUrlsToPost(c.UrlContext, &post, &p.Thread, p.Post.ID)
|
||||||
|
|
||||||
if p.ReplyPost != nil {
|
if p.ReplyPost != nil {
|
||||||
reply := templates.PostToTemplate(p.ReplyPost, p.ReplyAuthor, c.Theme)
|
reply := templates.PostToTemplate(p.ReplyPost, p.ReplyAuthor)
|
||||||
addBlogUrlsToPost(c.UrlContext, &reply, &p.Thread, p.Post.ID)
|
addBlogUrlsToPost(c.UrlContext, &reply, &p.Thread, p.Post.ID)
|
||||||
post.ReplyPost = &reply
|
post.ReplyPost = &reply
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ func BlogPostReply(c *RequestContext) ResponseData {
|
||||||
BlogThreadBreadcrumbs(c.UrlContext, &post.Thread),
|
BlogThreadBreadcrumbs(c.UrlContext, &post.Thread),
|
||||||
)
|
)
|
||||||
|
|
||||||
replyPost := templates.PostToTemplate(&post.Post, post.Author, c.Theme)
|
replyPost := templates.PostToTemplate(&post.Post, post.Author)
|
||||||
replyPost.AddContentVersion(post.CurrentVersion, post.Editor)
|
replyPost.AddContentVersion(post.CurrentVersion, post.Editor)
|
||||||
|
|
||||||
editData := getEditorDataForNew(c.UrlContext, c.CurrentUser, baseData, &replyPost)
|
editData := getEditorDataForNew(c.UrlContext, c.CurrentUser, baseData, &replyPost)
|
||||||
|
@ -479,7 +479,7 @@ func BlogPostDelete(c *RequestContext) ResponseData {
|
||||||
BlogThreadBreadcrumbs(c.UrlContext, &post.Thread),
|
BlogThreadBreadcrumbs(c.UrlContext, &post.Thread),
|
||||||
)
|
)
|
||||||
|
|
||||||
templatePost := templates.PostToTemplate(&post.Post, post.Author, c.Theme)
|
templatePost := templates.PostToTemplate(&post.Post, post.Author)
|
||||||
templatePost.AddContentVersion(post.CurrentVersion, post.Editor)
|
templatePost.AddContentVersion(post.CurrentVersion, post.Editor)
|
||||||
|
|
||||||
type blogPostDeleteData struct {
|
type blogPostDeleteData struct {
|
||||||
|
|
|
@ -49,7 +49,7 @@ func loadCommonData(h Handler) Handler {
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.CurrentProject = &dbProject.Project
|
c.CurrentProject = &dbProject.Project
|
||||||
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset, c.Theme)
|
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset)
|
||||||
owners = dbProject.Owners
|
owners = dbProject.Owners
|
||||||
} else {
|
} else {
|
||||||
if errors.Is(err, db.NotFound) {
|
if errors.Is(err, db.NotFound) {
|
||||||
|
@ -69,7 +69,7 @@ func loadCommonData(h Handler) Handler {
|
||||||
panic(oops.New(err, "failed to fetch HMN project"))
|
panic(oops.New(err, "failed to fetch HMN project"))
|
||||||
}
|
}
|
||||||
c.CurrentProject = &dbProject.Project
|
c.CurrentProject = &dbProject.Project
|
||||||
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset, c.Theme)
|
c.CurrentProjectLogoUrl = templates.ProjectLogoUrl(&dbProject.Project, dbProject.LogoLightAsset, dbProject.LogoDarkAsset)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.CurrentProject == nil {
|
if c.CurrentProject == nil {
|
||||||
|
@ -80,11 +80,6 @@ func loadCommonData(h Handler) Handler {
|
||||||
|
|
||||||
c.UrlContext = hmndata.UrlContextForProject(c.CurrentProject)
|
c.UrlContext = hmndata.UrlContextForProject(c.CurrentProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Theme = "light"
|
|
||||||
if c.CurrentUser != nil && c.CurrentUser.DarkTheme {
|
|
||||||
c.Theme = "dark"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c.Perf.EndBlock()
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ func AtomFeed(c *RequestContext) ResponseData {
|
||||||
templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
templateProject := templates.ProjectToTemplate(&p.Project, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
templateProject.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(templateProject.Url)).URN()
|
templateProject.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(templateProject.Url)).URN()
|
||||||
for _, owner := range p.Owners {
|
for _, owner := range p.Owners {
|
||||||
templateProject.Owners = append(templateProject.Owners, templates.UserToTemplate(owner, ""))
|
templateProject.Owners = append(templateProject.Owners, templates.UserToTemplate(owner))
|
||||||
}
|
}
|
||||||
|
|
||||||
feedData.Projects = append(feedData.Projects, templateProject)
|
feedData.Projects = append(feedData.Projects, templateProject)
|
||||||
|
@ -216,7 +216,6 @@ func fetchAllPosts(c *RequestContext, offset int, limit int) ([]templates.PostLi
|
||||||
postAndStuff.Author,
|
postAndStuff.Author,
|
||||||
postAndStuff.Unread,
|
postAndStuff.Unread,
|
||||||
true,
|
true,
|
||||||
c.Theme,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
|
postItem.UUID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(postItem.Url)).URN()
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func FollowingTest(c *RequestContext) ResponseData {
|
func FollowingTest(c *RequestContext) ResponseData {
|
||||||
timelineItems, err := FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser, c.Theme)
|
timelineItems, err := FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, err)
|
return c.ErrorResponse(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,9 +124,9 @@ func Forum(c *RequestContext) ResponseData {
|
||||||
return templates.ThreadListItem{
|
return templates.ThreadListItem{
|
||||||
Title: row.Thread.Title,
|
Title: row.Thread.Title,
|
||||||
Url: c.UrlContext.BuildForumThread(cd.LineageBuilder.GetSubforumLineageSlugs(*row.Thread.SubforumID), row.Thread.ID, row.Thread.Title, 1),
|
Url: c.UrlContext.BuildForumThread(cd.LineageBuilder.GetSubforumLineageSlugs(*row.Thread.SubforumID), row.Thread.ID, row.Thread.Title, 1),
|
||||||
FirstUser: templates.UserToTemplate(row.FirstPostAuthor, c.Theme),
|
FirstUser: templates.UserToTemplate(row.FirstPostAuthor),
|
||||||
FirstDate: row.FirstPost.PostDate,
|
FirstDate: row.FirstPost.PostDate,
|
||||||
LastUser: templates.UserToTemplate(row.LastPostAuthor, c.Theme),
|
LastUser: templates.UserToTemplate(row.LastPostAuthor),
|
||||||
LastDate: row.LastPost.PostDate,
|
LastDate: row.LastPost.PostDate,
|
||||||
Unread: row.Unread,
|
Unread: row.Unread,
|
||||||
}
|
}
|
||||||
|
@ -391,12 +391,12 @@ func ForumThread(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
var posts []templates.Post
|
var posts []templates.Post
|
||||||
for _, p := range postsAndStuff {
|
for _, p := range postsAndStuff {
|
||||||
post := templates.PostToTemplate(&p.Post, p.Author, c.Theme)
|
post := templates.PostToTemplate(&p.Post, p.Author)
|
||||||
post.AddContentVersion(p.CurrentVersion, p.Editor)
|
post.AddContentVersion(p.CurrentVersion, p.Editor)
|
||||||
addForumUrlsToPost(c.UrlContext, &post, currentSubforumSlugs, thread.ID, post.ID)
|
addForumUrlsToPost(c.UrlContext, &post, currentSubforumSlugs, thread.ID, post.ID)
|
||||||
|
|
||||||
if p.ReplyPost != nil {
|
if p.ReplyPost != nil {
|
||||||
reply := templates.PostToTemplate(p.ReplyPost, p.ReplyAuthor, c.Theme)
|
reply := templates.PostToTemplate(p.ReplyPost, p.ReplyAuthor)
|
||||||
addForumUrlsToPost(c.UrlContext, &reply, currentSubforumSlugs, thread.ID, reply.ID)
|
addForumUrlsToPost(c.UrlContext, &reply, currentSubforumSlugs, thread.ID, reply.ID)
|
||||||
post.ReplyPost = &reply
|
post.ReplyPost = &reply
|
||||||
}
|
}
|
||||||
|
@ -587,7 +587,7 @@ func ForumPostReply(c *RequestContext) ResponseData {
|
||||||
ForumThreadBreadcrumbs(c.UrlContext, cd.LineageBuilder, &post.Thread),
|
ForumThreadBreadcrumbs(c.UrlContext, cd.LineageBuilder, &post.Thread),
|
||||||
)
|
)
|
||||||
|
|
||||||
replyPost := templates.PostToTemplate(&post.Post, post.Author, c.Theme)
|
replyPost := templates.PostToTemplate(&post.Post, post.Author)
|
||||||
replyPost.AddContentVersion(post.CurrentVersion, post.Editor)
|
replyPost.AddContentVersion(post.CurrentVersion, post.Editor)
|
||||||
|
|
||||||
editData := getEditorDataForNew(c.UrlContext, c.CurrentUser, baseData, &replyPost)
|
editData := getEditorDataForNew(c.UrlContext, c.CurrentUser, baseData, &replyPost)
|
||||||
|
@ -779,7 +779,7 @@ func ForumPostDelete(c *RequestContext) ResponseData {
|
||||||
ForumThreadBreadcrumbs(c.UrlContext, cd.LineageBuilder, &post.Thread),
|
ForumThreadBreadcrumbs(c.UrlContext, cd.LineageBuilder, &post.Thread),
|
||||||
)
|
)
|
||||||
|
|
||||||
templatePost := templates.PostToTemplate(&post.Post, post.Author, c.Theme)
|
templatePost := templates.PostToTemplate(&post.Post, post.Author)
|
||||||
templatePost.AddContentVersion(post.CurrentVersion, post.Editor)
|
templatePost.AddContentVersion(post.CurrentVersion, post.Editor)
|
||||||
|
|
||||||
type forumPostDeleteData struct {
|
type forumPostDeleteData struct {
|
||||||
|
|
|
@ -57,7 +57,7 @@ func JamSaveTheDate(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
tmpl := TemplateData{
|
tmpl := TemplateData{
|
||||||
BaseData: getBaseDataAutocrumb(c, "Upcoming Jams"),
|
BaseData: getBaseDataAutocrumb(c, "Upcoming Jams"),
|
||||||
UserAvatarUrl: templates.UserAvatarUrl(c.CurrentUser, "dark"),
|
UserAvatarUrl: templates.UserAvatarUrl(c.CurrentUser),
|
||||||
JamsUrl: hmnurl.BuildJamsIndex(),
|
JamsUrl: hmnurl.BuildJamsIndex(),
|
||||||
Visibility2023Url: hmnurl.BuildJamIndex2023_Visibility(),
|
Visibility2023Url: hmnurl.BuildJamIndex2023_Visibility(),
|
||||||
WRJ2023Url: hmnurl.BuildJamIndex2023(),
|
WRJ2023Url: hmnurl.BuildJamIndex2023(),
|
||||||
|
@ -221,7 +221,7 @@ func getLJ2024BaseData(c *RequestContext) (JamBaseDataLJ2024, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.CurrentUser != nil {
|
if c.CurrentUser != nil {
|
||||||
tmpl.UserAvatarUrl = templates.UserAvatarUrl(c.CurrentUser, "dark")
|
tmpl.UserAvatarUrl = templates.UserAvatarUrl(c.CurrentUser)
|
||||||
projects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
projects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
||||||
OwnerIDs: []int{c.CurrentUser.ID},
|
OwnerIDs: []int{c.CurrentUser.ID},
|
||||||
JamSlugs: []string{hmndata.LJ2024.Slug},
|
JamSlugs: []string{hmndata.LJ2024.Slug},
|
||||||
|
@ -252,7 +252,7 @@ func getLJ2024FeedData(c *RequestContext, maxTimelineItems int) (JamFeedDataLJ20
|
||||||
for _, jp := range jamProjects {
|
for _, jp := range jamProjects {
|
||||||
urlContext := hmndata.UrlContextForProject(&jp.Project)
|
urlContext := hmndata.UrlContextForProject(&jp.Project)
|
||||||
projectUrl := urlContext.BuildHomepage()
|
projectUrl := urlContext.BuildHomepage()
|
||||||
projects = append(projects, templates.ProjectAndStuffToTemplate(&jp, projectUrl, c.Theme))
|
projects = append(projects, templates.ProjectAndStuffToTemplate(&jp, projectUrl))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectIds := make([]int, 0, len(jamProjects))
|
projectIds := make([]int, 0, len(jamProjects))
|
||||||
|
@ -272,7 +272,7 @@ func getLJ2024FeedData(c *RequestContext, maxTimelineItems int) (JamFeedDataLJ20
|
||||||
|
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ func JamIndex2023(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectIds := make([]int, 0, len(jamProjects))
|
projectIds := make([]int, 0, len(jamProjects))
|
||||||
|
@ -385,7 +385,7 @@ func JamIndex2023(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
if timelineItem.CanShowcase {
|
if timelineItem.CanShowcase {
|
||||||
showcaseItems = append(showcaseItems, timelineItem)
|
showcaseItems = append(showcaseItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ func JamFeed2023(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -460,7 +460,7 @@ func JamFeed2023(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
type JamFeedData struct {
|
type JamFeedData struct {
|
||||||
|
@ -553,7 +553,7 @@ func JamIndex2023_Visibility(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectIds := make([]int, 0, len(jamProjects))
|
projectIds := make([]int, 0, len(jamProjects))
|
||||||
|
@ -571,7 +571,7 @@ func JamIndex2023_Visibility(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
if timelineItem.CanShowcase {
|
if timelineItem.CanShowcase {
|
||||||
showcaseItems = append(showcaseItems, timelineItem)
|
showcaseItems = append(showcaseItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ func JamFeed2023_Visibility(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -628,7 +628,7 @@ func JamFeed2023_Visibility(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
type JamFeedData struct {
|
type JamFeedData struct {
|
||||||
|
@ -681,7 +681,7 @@ func JamRecap2023_Visibility(c *RequestContext) ResponseData {
|
||||||
var ben templates.User
|
var ben templates.User
|
||||||
benUser, err := hmndata.FetchUserByUsername(c, c.Conn, c.CurrentUser, "bvisness", hmndata.UsersQuery{})
|
benUser, err := hmndata.FetchUserByUsername(c, c.Conn, c.CurrentUser, "bvisness", hmndata.UsersQuery{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ben = templates.UserToTemplate(benUser, c.Theme)
|
ben = templates.UserToTemplate(benUser)
|
||||||
} else if err == db.NotFound {
|
} else if err == db.NotFound {
|
||||||
ben = templates.UnknownUser
|
ben = templates.UnknownUser
|
||||||
} else {
|
} else {
|
||||||
|
@ -767,7 +767,7 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
projectIds := make([]int, 0, len(jamProjects))
|
projectIds := make([]int, 0, len(jamProjects))
|
||||||
|
@ -785,7 +785,7 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
showcaseItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
if timelineItem.CanShowcase {
|
if timelineItem.CanShowcase {
|
||||||
showcaseItems = append(showcaseItems, timelineItem)
|
showcaseItems = append(showcaseItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -833,7 +833,7 @@ func JamFeed2022(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
timelineItems = make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
timelineItem.SmallInfo = true
|
timelineItem.SmallInfo = true
|
||||||
timelineItems = append(timelineItems, timelineItem)
|
timelineItems = append(timelineItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
@ -841,7 +841,7 @@ func JamFeed2022(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||||
for _, p := range jamProjects {
|
for _, p := range jamProjects {
|
||||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
type JamFeedData struct {
|
type JamFeedData struct {
|
||||||
|
@ -901,7 +901,7 @@ func JamIndex2021(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
showcaseItems := make([]templates.TimelineItem, 0, len(snippets))
|
showcaseItems := make([]templates.TimelineItem, 0, len(snippets))
|
||||||
for _, s := range snippets {
|
for _, s := range snippets {
|
||||||
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, false)
|
timelineItem := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, false)
|
||||||
if timelineItem.CanShowcase {
|
if timelineItem.CanShowcase {
|
||||||
showcaseItems = append(showcaseItems, timelineItem)
|
showcaseItems = append(showcaseItems, timelineItem)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ func Index(c *RequestContext) ResponseData {
|
||||||
|
|
||||||
var timelineItems []templates.TimelineItem
|
var timelineItems []templates.TimelineItem
|
||||||
|
|
||||||
|
FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser)
|
||||||
|
|
||||||
// This is essentially an alternate for feed page 1.
|
// This is essentially an alternate for feed page 1.
|
||||||
posts, err := hmndata.FetchPosts(c, c.Conn, c.CurrentUser, hmndata.PostsQuery{
|
posts, err := hmndata.FetchPosts(c, c.Conn, c.CurrentUser, hmndata.PostsQuery{
|
||||||
ThreadTypes: feedThreadTypes,
|
ThreadTypes: feedThreadTypes,
|
||||||
|
@ -54,7 +56,7 @@ func Index(c *RequestContext) ResponseData {
|
||||||
continue // ignore news posts et. al.
|
continue // ignore news posts et. al.
|
||||||
}
|
}
|
||||||
|
|
||||||
item := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, p.Author, c.Theme)
|
item := PostToTimelineItem(hmndata.UrlContextForProject(&p.Project), lineageBuilder, &p.Post, &p.Thread, p.Author)
|
||||||
if p.Thread.Type == models.ThreadTypeProjectBlogPost && p.Post.ID == p.Thread.FirstID {
|
if p.Thread.Type == models.ThreadTypeProjectBlogPost && p.Post.ID == p.Thread.FirstID {
|
||||||
// blog post
|
// blog post
|
||||||
item.Description = template.HTML(p.CurrentVersion.TextParsed)
|
item.Description = template.HTML(p.CurrentVersion.TextParsed)
|
||||||
|
@ -75,7 +77,7 @@ func Index(c *RequestContext) ResponseData {
|
||||||
var newsPostItem *templates.TimelineItem
|
var newsPostItem *templates.TimelineItem
|
||||||
if len(newsThreads) > 0 {
|
if len(newsThreads) > 0 {
|
||||||
t := newsThreads[0]
|
t := newsThreads[0]
|
||||||
item := PostToTimelineItem(hmndata.UrlContextForProject(&t.Project), lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor, c.Theme)
|
item := PostToTimelineItem(hmndata.UrlContextForProject(&t.Project), lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor)
|
||||||
item.Breadcrumbs = nil
|
item.Breadcrumbs = nil
|
||||||
item.TypeTitle = ""
|
item.TypeTitle = ""
|
||||||
item.AllowTitleWrap = true
|
item.AllowTitleWrap = true
|
||||||
|
|
|
@ -85,14 +85,13 @@ func MakePostListItem(
|
||||||
user *models.User,
|
user *models.User,
|
||||||
unread bool,
|
unread bool,
|
||||||
includeBreadcrumbs bool,
|
includeBreadcrumbs bool,
|
||||||
currentTheme string,
|
|
||||||
) templates.PostListItem {
|
) templates.PostListItem {
|
||||||
var result templates.PostListItem
|
var result templates.PostListItem
|
||||||
|
|
||||||
urlContext := hmndata.UrlContextForProject(project)
|
urlContext := hmndata.UrlContextForProject(project)
|
||||||
|
|
||||||
result.Title = thread.Title
|
result.Title = thread.Title
|
||||||
result.User = templates.UserToTemplate(user, currentTheme)
|
result.User = templates.UserToTemplate(user)
|
||||||
result.Date = post.PostDate
|
result.Date = post.PostDate
|
||||||
result.Unread = unread
|
result.Unread = unread
|
||||||
result.Url = UrlForGenericPost(urlContext, thread, post, lineageBuilder)
|
result.Url = UrlForGenericPost(urlContext, thread, post, lineageBuilder)
|
||||||
|
|
|
@ -238,7 +238,7 @@ func getShuffledOfficialProjects(c *RequestContext) ([]templates.Project, error)
|
||||||
var restProjects []templates.Project
|
var restProjects []templates.Project
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for _, p := range official {
|
for _, p := range official {
|
||||||
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme)
|
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
|
|
||||||
if p.Project.Slug == "hero" {
|
if p.Project.Slug == "hero" {
|
||||||
// NOTE(asaf): Handmade Hero gets special treatment. Must always be first in the list.
|
// NOTE(asaf): Handmade Hero gets special treatment. Must always be first in the list.
|
||||||
|
@ -297,7 +297,7 @@ func getPersonalProjects(c *RequestContext, jamSlug string) ([]templates.Project
|
||||||
|
|
||||||
var personalProjects []templates.Project
|
var personalProjects []templates.Project
|
||||||
for _, p := range projects {
|
for _, p := range projects {
|
||||||
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme)
|
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
personalProjects = append(personalProjects, templateProject)
|
personalProjects = append(personalProjects, templateProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,9 +410,9 @@ func ProjectHomepage(c *RequestContext) ResponseData {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project details"))
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project details"))
|
||||||
}
|
}
|
||||||
templateData.Project = templates.ProjectAndStuffToTemplate(&p, c.UrlContext.BuildHomepage(), c.Theme)
|
templateData.Project = templates.ProjectAndStuffToTemplate(&p, c.UrlContext.BuildHomepage())
|
||||||
for _, owner := range owners {
|
for _, owner := range owners {
|
||||||
templateData.Owners = append(templateData.Owners, templates.UserToTemplate(owner, c.Theme))
|
templateData.Owners = append(templateData.Owners, templates.UserToTemplate(owner))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.CurrentProject.Hidden {
|
if c.CurrentProject.Hidden {
|
||||||
|
@ -467,7 +467,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templateData.RecentActivity, err = FetchTimeline(c, c.Conn, c.CurrentUser, c.Theme, TimelineQuery{
|
templateData.RecentActivity, err = FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
||||||
ProjectIDs: []int{c.CurrentProject.ID},
|
ProjectIDs: []int{c.CurrentProject.ID},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -486,12 +486,12 @@ func ProjectHomepage(c *RequestContext) ResponseData {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user projects"))
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user projects"))
|
||||||
}
|
}
|
||||||
templateProjects := make([]templates.Project, 0, len(userProjects))
|
templateProjects := make([]templates.Project, 0, len(userProjects))
|
||||||
templateProjects = append(templateProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
templateProjects = append(templateProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage()))
|
||||||
for _, p := range userProjects {
|
for _, p := range userProjects {
|
||||||
if p.Project.ID == c.CurrentProject.ID {
|
if p.Project.ID == c.CurrentProject.ID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme)
|
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
templateProjects = append(templateProjects, templateProject)
|
templateProjects = append(templateProjects, templateProject)
|
||||||
}
|
}
|
||||||
templateData.SnippetEdit = templates.SnippetEdit{
|
templateData.SnippetEdit = templates.SnippetEdit{
|
||||||
|
@ -550,7 +550,7 @@ func ProjectNew(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
var project templates.ProjectSettings
|
var project templates.ProjectSettings
|
||||||
project.Owners = append(project.Owners, templates.UserToTemplate(c.CurrentUser, c.Theme))
|
project.Owners = append(project.Owners, templates.UserToTemplate(c.CurrentUser))
|
||||||
project.Personal = true
|
project.Personal = true
|
||||||
|
|
||||||
var currentJam *hmndata.Jam
|
var currentJam *hmndata.Jam
|
||||||
|
@ -696,7 +696,6 @@ func ProjectEdit(c *RequestContext) ResponseData {
|
||||||
p.Owners,
|
p.Owners,
|
||||||
p.TagText(),
|
p.TagText(),
|
||||||
p.LogoLightAsset, p.LogoDarkAsset, p.HeaderImage,
|
p.LogoLightAsset, p.LogoDarkAsset, p.HeaderImage,
|
||||||
c.Theme,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
projectSettings.LinksJSON = string(utils.Must1(json.Marshal(templates.LinksToTemplate(projectLinks))))
|
projectSettings.LinksJSON = string(utils.Must1(json.Marshal(templates.LinksToTemplate(projectLinks))))
|
||||||
|
|
|
@ -190,7 +190,6 @@ type RequestContext struct {
|
||||||
CurrentProjectLogoUrl string
|
CurrentProjectLogoUrl string
|
||||||
CurrentUser *models.User
|
CurrentUser *models.User
|
||||||
CurrentSession *models.Session
|
CurrentSession *models.Session
|
||||||
Theme string
|
|
||||||
UrlContext *hmnurl.UrlContext
|
UrlContext *hmnurl.UrlContext
|
||||||
|
|
||||||
CurrentUserCanEditCurrentProject bool
|
CurrentUserCanEditCurrentProject bool
|
||||||
|
|
|
@ -57,7 +57,7 @@ func Snippet(c *RequestContext) ResponseData {
|
||||||
c.Perf.EndBlock()
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
canEdit := (c.CurrentUser != nil && (c.CurrentUser.IsStaff || c.CurrentUser.ID == s.Owner.ID))
|
canEdit := (c.CurrentUser != nil && (c.CurrentUser.IsStaff || c.CurrentUser.ID == s.Owner.ID))
|
||||||
snippet := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, c.Theme, canEdit)
|
snippet := SnippetToTimelineItem(&s.Snippet, s.Asset, s.DiscordMessage, s.Projects, s.Owner, canEdit)
|
||||||
snippet.SmallInfo = true
|
snippet.SmallInfo = true
|
||||||
|
|
||||||
opengraph := []templates.OpenGraphItem{
|
opengraph := []templates.OpenGraphItem{
|
||||||
|
@ -114,7 +114,7 @@ func Snippet(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
templateProjects := make([]templates.Project, 0, len(userProjects))
|
templateProjects := make([]templates.Project, 0, len(userProjects))
|
||||||
for _, p := range userProjects {
|
for _, p := range userProjects {
|
||||||
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme)
|
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
templateProjects = append(templateProjects, templateProject)
|
templateProjects = append(templateProjects, templateProject)
|
||||||
}
|
}
|
||||||
snippetEdit = templates.SnippetEdit{
|
snippetEdit = templates.SnippetEdit{
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"git.handmade.network/hmn/hmn/src/templates"
|
"git.handmade.network/hmn/hmn/src/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
func FetchFollowTimelineForUser(ctx context.Context, conn db.ConnOrTx, user *models.User, theme string) ([]templates.TimelineItem, error) {
|
func FetchFollowTimelineForUser(ctx context.Context, conn db.ConnOrTx, user *models.User) ([]templates.TimelineItem, error) {
|
||||||
perf := perf.ExtractPerf(ctx)
|
perf := perf.ExtractPerf(ctx)
|
||||||
type Follower struct {
|
type Follower struct {
|
||||||
UserID int `db:"user_id"`
|
UserID int `db:"user_id"`
|
||||||
|
@ -50,7 +50,7 @@ func FetchFollowTimelineForUser(ctx context.Context, conn db.ConnOrTx, user *mod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timelineItems, err := FetchTimeline(ctx, conn, user, theme, TimelineQuery{
|
timelineItems, err := FetchTimeline(ctx, conn, user, TimelineQuery{
|
||||||
UserIDs: userIDs,
|
UserIDs: userIDs,
|
||||||
ProjectIDs: projectIDs,
|
ProjectIDs: projectIDs,
|
||||||
})
|
})
|
||||||
|
@ -64,7 +64,7 @@ type TimelineQuery struct {
|
||||||
ProjectIDs []int
|
ProjectIDs []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.User, theme string, q TimelineQuery) ([]templates.TimelineItem, error) {
|
func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.User, q TimelineQuery) ([]templates.TimelineItem, error) {
|
||||||
perf := perf.ExtractPerf(ctx)
|
perf := perf.ExtractPerf(ctx)
|
||||||
var users []*models.User
|
var users []*models.User
|
||||||
var projects []hmndata.ProjectAndStuff
|
var projects []hmndata.ProjectAndStuff
|
||||||
|
@ -159,7 +159,6 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
&post.Post,
|
&post.Post,
|
||||||
&post.Thread,
|
&post.Thread,
|
||||||
post.Author,
|
post.Author,
|
||||||
theme,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +170,6 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
s.DiscordMessage,
|
s.DiscordMessage,
|
||||||
s.Projects,
|
s.Projects,
|
||||||
s.Owner,
|
s.Owner,
|
||||||
theme,
|
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
item.SmallInfo = true
|
item.SmallInfo = true
|
||||||
|
@ -188,7 +186,7 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
if streamer.UserID != nil {
|
if streamer.UserID != nil {
|
||||||
for _, u := range users {
|
for _, u := range users {
|
||||||
if u.ID == *streamer.UserID {
|
if u.ID == *streamer.UserID {
|
||||||
ownerAvatarUrl = templates.UserAvatarUrl(u, theme)
|
ownerAvatarUrl = templates.UserAvatarUrl(u)
|
||||||
ownerName = u.BestName()
|
ownerName = u.BestName()
|
||||||
ownerUrl = hmnurl.BuildUserProfile(u.Username)
|
ownerUrl = hmnurl.BuildUserProfile(u.Username)
|
||||||
break
|
break
|
||||||
|
@ -197,7 +195,7 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
} else if streamer.ProjectID != nil {
|
} else if streamer.ProjectID != nil {
|
||||||
for _, p := range projects {
|
for _, p := range projects {
|
||||||
if p.Project.ID == *streamer.ProjectID {
|
if p.Project.ID == *streamer.ProjectID {
|
||||||
ownerAvatarUrl = templates.ProjectLogoUrl(&p.Project, p.LogoLightAsset, p.LogoDarkAsset, theme)
|
ownerAvatarUrl = templates.ProjectLogoUrl(&p.Project, p.LogoLightAsset, p.LogoDarkAsset)
|
||||||
ownerName = p.Project.Name
|
ownerName = p.Project.Name
|
||||||
ownerUrl = hmndata.UrlContextForProject(&p.Project).BuildHomepage()
|
ownerUrl = hmndata.UrlContextForProject(&p.Project).BuildHomepage()
|
||||||
}
|
}
|
||||||
|
@ -207,9 +205,6 @@ func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.Us
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ownerAvatarUrl == "" {
|
|
||||||
ownerAvatarUrl = templates.UserAvatarDefaultUrl(theme)
|
|
||||||
}
|
|
||||||
item := TwitchStreamToTimelineItem(s, ownerAvatarUrl, ownerName, ownerUrl)
|
item := TwitchStreamToTimelineItem(s, ownerAvatarUrl, ownerName, ownerUrl)
|
||||||
timelineItems = append(timelineItems, item)
|
timelineItems = append(timelineItems, item)
|
||||||
}
|
}
|
||||||
|
@ -241,7 +236,6 @@ func PostToTimelineItem(
|
||||||
post *models.Post,
|
post *models.Post,
|
||||||
thread *models.Thread,
|
thread *models.Thread,
|
||||||
owner *models.User,
|
owner *models.User,
|
||||||
currentTheme string,
|
|
||||||
) templates.TimelineItem {
|
) templates.TimelineItem {
|
||||||
item := templates.TimelineItem{
|
item := templates.TimelineItem{
|
||||||
Date: post.PostDate,
|
Date: post.PostDate,
|
||||||
|
@ -249,7 +243,7 @@ func PostToTimelineItem(
|
||||||
Breadcrumbs: GenericThreadBreadcrumbs(urlContext, lineageBuilder, thread),
|
Breadcrumbs: GenericThreadBreadcrumbs(urlContext, lineageBuilder, thread),
|
||||||
Url: UrlForGenericPost(urlContext, thread, post, lineageBuilder),
|
Url: UrlForGenericPost(urlContext, thread, post, lineageBuilder),
|
||||||
|
|
||||||
OwnerAvatarUrl: templates.UserAvatarUrl(owner, currentTheme),
|
OwnerAvatarUrl: templates.UserAvatarUrl(owner),
|
||||||
OwnerName: owner.BestName(),
|
OwnerName: owner.BestName(),
|
||||||
OwnerUrl: hmnurl.BuildUserProfile(owner.Username),
|
OwnerUrl: hmnurl.BuildUserProfile(owner.Username),
|
||||||
}
|
}
|
||||||
|
@ -313,7 +307,6 @@ func SnippetToTimelineItem(
|
||||||
discordMessage *models.DiscordMessage,
|
discordMessage *models.DiscordMessage,
|
||||||
projects []*hmndata.ProjectAndStuff,
|
projects []*hmndata.ProjectAndStuff,
|
||||||
owner *models.User,
|
owner *models.User,
|
||||||
currentTheme string,
|
|
||||||
editable bool,
|
editable bool,
|
||||||
) templates.TimelineItem {
|
) templates.TimelineItem {
|
||||||
item := templates.TimelineItem{
|
item := templates.TimelineItem{
|
||||||
|
@ -322,7 +315,7 @@ func SnippetToTimelineItem(
|
||||||
FilterTitle: "Snippets",
|
FilterTitle: "Snippets",
|
||||||
Url: hmnurl.BuildSnippet(snippet.ID),
|
Url: hmnurl.BuildSnippet(snippet.ID),
|
||||||
|
|
||||||
OwnerAvatarUrl: templates.UserAvatarUrl(owner, currentTheme),
|
OwnerAvatarUrl: templates.UserAvatarUrl(owner),
|
||||||
OwnerName: owner.BestName(),
|
OwnerName: owner.BestName(),
|
||||||
OwnerUrl: hmnurl.BuildUserProfile(owner.Username),
|
OwnerUrl: hmnurl.BuildUserProfile(owner.Username),
|
||||||
|
|
||||||
|
@ -366,7 +359,7 @@ func SnippetToTimelineItem(
|
||||||
return projects[i].Project.Name < projects[j].Project.Name
|
return projects[i].Project.Name < projects[j].Project.Name
|
||||||
})
|
})
|
||||||
for _, proj := range projects {
|
for _, proj := range projects {
|
||||||
item.Projects = append(item.Projects, templates.ProjectAndStuffToTemplate(proj, hmndata.UrlContextForProject(&proj.Project).BuildHomepage(), currentTheme))
|
item.Projects = append(item.Projects, templates.ProjectAndStuffToTemplate(proj, hmndata.UrlContextForProject(&proj.Project).BuildHomepage()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
|
@ -106,7 +106,7 @@ func UserProfile(c *RequestContext) ResponseData {
|
||||||
templateProjects := make([]templates.Project, 0, len(projectsAndStuff))
|
templateProjects := make([]templates.Project, 0, len(projectsAndStuff))
|
||||||
numPersonalProjects := 0
|
numPersonalProjects := 0
|
||||||
for _, p := range projectsAndStuff {
|
for _, p := range projectsAndStuff {
|
||||||
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme)
|
templateProject := templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage())
|
||||||
templateProjects = append(templateProjects, templateProject)
|
templateProjects = append(templateProjects, templateProject)
|
||||||
|
|
||||||
if p.Project.Personal {
|
if p.Project.Personal {
|
||||||
|
@ -115,14 +115,14 @@ func UserProfile(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
c.Perf.EndBlock()
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
timelineItems, err := FetchTimeline(c, c.Conn, c.CurrentUser, c.Theme, TimelineQuery{
|
timelineItems, err := FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
||||||
UserIDs: []int{profileUser.ID},
|
UserIDs: []int{profileUser.ID},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.ErrorResponse(http.StatusInternalServerError, err)
|
return c.ErrorResponse(http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
templateUser := templates.UserToTemplate(profileUser, c.Theme)
|
templateUser := templates.UserToTemplate(profileUser)
|
||||||
|
|
||||||
baseData := getBaseDataAutocrumb(c, templateUser.Name)
|
baseData := getBaseDataAutocrumb(c, templateUser.Name)
|
||||||
|
|
||||||
|
@ -183,7 +183,6 @@ func UserSettings(c *RequestContext) ResponseData {
|
||||||
templates.BaseData
|
templates.BaseData
|
||||||
|
|
||||||
AvatarMaxFileSize int
|
AvatarMaxFileSize int
|
||||||
DefaultAvatarUrl string
|
|
||||||
|
|
||||||
User templates.User
|
User templates.User
|
||||||
Avatar *templates.Asset
|
Avatar *templates.Asset
|
||||||
|
@ -254,14 +253,13 @@ func UserSettings(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templateUser := templates.UserToTemplate(c.CurrentUser, c.Theme)
|
templateUser := templates.UserToTemplate(c.CurrentUser)
|
||||||
|
|
||||||
baseData := getBaseDataAutocrumb(c, templateUser.Name)
|
baseData := getBaseDataAutocrumb(c, templateUser.Name)
|
||||||
|
|
||||||
res.MustWriteTemplate("user_settings.html", UserSettingsTemplateData{
|
res.MustWriteTemplate("user_settings.html", UserSettingsTemplateData{
|
||||||
BaseData: baseData,
|
BaseData: baseData,
|
||||||
AvatarMaxFileSize: UserAvatarMaxFileSize,
|
AvatarMaxFileSize: UserAvatarMaxFileSize,
|
||||||
DefaultAvatarUrl: templates.UserAvatarDefaultUrl(c.Theme),
|
|
||||||
User: templateUser,
|
User: templateUser,
|
||||||
Avatar: templates.AssetToTemplate(c.CurrentUser.AvatarAsset),
|
Avatar: templates.AssetToTemplate(c.CurrentUser.AvatarAsset),
|
||||||
Email: c.CurrentUser.Email,
|
Email: c.CurrentUser.Email,
|
||||||
|
@ -319,7 +317,6 @@ func UserSettingsSave(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
|
|
||||||
showEmail := form.Get("showemail") != ""
|
showEmail := form.Get("showemail") != ""
|
||||||
darkTheme := form.Get("darktheme") != ""
|
|
||||||
|
|
||||||
blurb := form.Get("shortbio")
|
blurb := form.Get("shortbio")
|
||||||
signature := form.Get("signature")
|
signature := form.Get("signature")
|
||||||
|
@ -336,7 +333,6 @@ func UserSettingsSave(c *RequestContext) ResponseData {
|
||||||
name = $?,
|
name = $?,
|
||||||
email = $?,
|
email = $?,
|
||||||
showemail = $?,
|
showemail = $?,
|
||||||
darktheme = $?,
|
|
||||||
blurb = $?,
|
blurb = $?,
|
||||||
signature = $?,
|
signature = $?,
|
||||||
bio = $?
|
bio = $?
|
||||||
|
@ -344,7 +340,6 @@ func UserSettingsSave(c *RequestContext) ResponseData {
|
||||||
name,
|
name,
|
||||||
email,
|
email,
|
||||||
showEmail,
|
showEmail,
|
||||||
darkTheme,
|
|
||||||
blurb,
|
blurb,
|
||||||
signature,
|
signature,
|
||||||
bio,
|
bio,
|
||||||
|
|
|
@ -54,3 +54,5 @@
|
||||||
- Threads?
|
- Threads?
|
||||||
- TikTok?
|
- TikTok?
|
||||||
- Trello?
|
- Trello?
|
||||||
|
- [ ] Handle empty avatar URLs correctly in various places (render as theme-dependent default)
|
||||||
|
- [ ] Resolve TODO(redesign) comments
|
||||||
|
|
Loading…
Reference in New Issue