168 lines
5.2 KiB
Go
168 lines
5.2 KiB
Go
package website
|
|
|
|
import (
|
|
"html/template"
|
|
"net/http"
|
|
|
|
"git.handmade.network/hmn/hmn/src/hmndata"
|
|
"git.handmade.network/hmn/hmn/src/hmnurl"
|
|
"git.handmade.network/hmn/hmn/src/models"
|
|
"git.handmade.network/hmn/hmn/src/oops"
|
|
"git.handmade.network/hmn/hmn/src/templates"
|
|
"git.handmade.network/hmn/hmn/src/utils"
|
|
)
|
|
|
|
func Index(c *RequestContext) ResponseData {
|
|
const maxPostsPerTab = 60
|
|
|
|
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
|
subforumTree := models.GetFullSubforumTree(c, c.Conn)
|
|
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
|
c.Perf.EndBlock()
|
|
|
|
type LandingTemplateData struct {
|
|
templates.BaseData
|
|
|
|
FollowingItems []templates.TimelineItem
|
|
FeaturedItems []templates.TimelineItem
|
|
RecentItems []templates.TimelineItem
|
|
NewsItems []templates.TimelineItem
|
|
|
|
UserProjects []templates.Project
|
|
Following []templates.Follow
|
|
|
|
ManifestoUrl string
|
|
AboutUrl string
|
|
PodcastUrl string
|
|
AtomFeedUrl string
|
|
MarkAllReadUrl string
|
|
NewProjectUrl string
|
|
|
|
JamUrl string
|
|
JamDaysUntilStart, JamDaysUntilEnd int
|
|
|
|
HMSDaysUntilStart, HMSDaysUntilEnd int
|
|
HMBostonDaysUntilStart, HMBostonDaysUntilEnd int
|
|
}
|
|
|
|
var err error
|
|
var followingItems []templates.TimelineItem
|
|
var featuredItems []templates.TimelineItem
|
|
var recentItems []templates.TimelineItem
|
|
var newsItems []templates.TimelineItem
|
|
|
|
if c.CurrentUser != nil {
|
|
followingItems, err = FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser, lineageBuilder)
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch following feed")
|
|
}
|
|
}
|
|
|
|
featuredProjects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
|
FeaturedOnly: true,
|
|
})
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch featured projects")
|
|
}
|
|
var featuredProjectIDs []int
|
|
for _, p := range featuredProjects {
|
|
featuredProjectIDs = append(featuredProjectIDs, p.Project.ID)
|
|
}
|
|
featuredItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, lineageBuilder, hmndata.TimelineQuery{
|
|
ProjectIDs: featuredProjectIDs,
|
|
Limit: maxPostsPerTab,
|
|
})
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch featured feed")
|
|
}
|
|
|
|
recentItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, lineageBuilder, hmndata.TimelineQuery{
|
|
Limit: maxPostsPerTab,
|
|
})
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch recent feed")
|
|
}
|
|
|
|
newsThreads, err := hmndata.FetchThreads(c, c.Conn, c.CurrentUser, hmndata.ThreadsQuery{
|
|
ProjectIDs: []int{models.HMNProjectID},
|
|
ThreadTypes: []models.ThreadType{models.ThreadTypeProjectBlogPost},
|
|
Limit: maxPostsPerTab,
|
|
OrderByCreated: true,
|
|
})
|
|
if err != nil {
|
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news threads"))
|
|
}
|
|
for _, t := range newsThreads {
|
|
item := PostToTimelineItem(c.UrlContext, lineageBuilder, &t.FirstPost, &t.Thread, t.FirstPostAuthor)
|
|
item.Breadcrumbs = nil
|
|
item.TypeTitle = ""
|
|
item.Description = template.HTML(t.FirstPostCurrentVersion.TextParsed)
|
|
item.AllowTitleWrap = true
|
|
item.TruncateDescription = true
|
|
newsItems = append(newsItems, item)
|
|
}
|
|
|
|
var projects []templates.Project
|
|
if c.CurrentUser != nil {
|
|
projectsDb, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
|
OwnerIDs: []int{c.CurrentUser.ID},
|
|
})
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch user projects")
|
|
}
|
|
|
|
for _, p := range projectsDb {
|
|
projects = append(projects, templates.ProjectAndStuffToTemplate(&p))
|
|
}
|
|
}
|
|
|
|
var follows []templates.Follow
|
|
if c.CurrentUser != nil {
|
|
follows, err = FetchFollows(c, c.Conn, c.CurrentUser, c.CurrentUser.ID)
|
|
if err != nil {
|
|
c.Logger.Warn().Err(err).Msg("failed to fetch user follows")
|
|
}
|
|
}
|
|
|
|
baseData := getBaseData(c, "", nil)
|
|
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
|
Property: "og:description",
|
|
Value: "A community of low-level programmers with high-level goals, working to correct the course of the software industry.",
|
|
})
|
|
|
|
var res ResponseData
|
|
err = res.WriteTemplate("landing.html", LandingTemplateData{
|
|
BaseData: baseData,
|
|
|
|
FollowingItems: followingItems,
|
|
FeaturedItems: featuredItems,
|
|
RecentItems: recentItems,
|
|
NewsItems: newsItems,
|
|
|
|
UserProjects: projects,
|
|
Following: follows,
|
|
|
|
ManifestoUrl: hmnurl.BuildManifesto(),
|
|
AboutUrl: hmnurl.BuildAbout(),
|
|
PodcastUrl: hmnurl.BuildPodcast(),
|
|
AtomFeedUrl: hmnurl.BuildAtomFeed(),
|
|
MarkAllReadUrl: hmnurl.HMNProjectContext.BuildForumMarkRead(0),
|
|
NewProjectUrl: hmnurl.BuildProjectNew(),
|
|
|
|
JamUrl: hmnurl.BuildJamIndex2024_Learning(),
|
|
JamDaysUntilStart: utils.DaysUntil(hmndata.LJ2024.StartTime),
|
|
JamDaysUntilEnd: utils.DaysUntil(hmndata.LJ2024.EndTime),
|
|
|
|
HMSDaysUntilStart: utils.DaysUntil(hmndata.HMS2024.StartTime),
|
|
HMSDaysUntilEnd: utils.DaysUntil(hmndata.HMS2024.EndTime),
|
|
|
|
HMBostonDaysUntilStart: utils.DaysUntil(hmndata.HMBoston2024.StartTime),
|
|
HMBostonDaysUntilEnd: utils.DaysUntil(hmndata.HMBoston2024.EndTime),
|
|
}, c.Perf)
|
|
if err != nil {
|
|
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render landing page template"))
|
|
}
|
|
|
|
return res
|
|
}
|