Start scaffolding landing page
This commit is contained in:
parent
d242c71a2b
commit
7144db58ed
|
@ -7412,6 +7412,15 @@ pre,
|
||||||
.f8 {
|
.f8 {
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
}
|
}
|
||||||
|
.w6 {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
.w7 {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
.w8 {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
.mw-site {
|
.mw-site {
|
||||||
max-width: var(--site-width);
|
max-width: var(--site-width);
|
||||||
}
|
}
|
||||||
|
@ -7557,6 +7566,15 @@ pre,
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 35em) {
|
@media screen and (min-width: 35em) {
|
||||||
|
.w6-ns {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
.w7-ns {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
.w8-ns {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
.bi-avoid-ns {
|
.bi-avoid-ns {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
@ -7613,6 +7631,15 @@ pre,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 35em) and (max-width: 60em) {
|
@media screen and (min-width: 35em) and (max-width: 60em) {
|
||||||
|
.w6-m {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
.w7-m {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
.w8-m {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
.bi-avoid-m {
|
.bi-avoid-m {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
@ -7666,6 +7693,15 @@ pre,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 60em) {
|
@media screen and (min-width: 60em) {
|
||||||
|
.w6-l {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
.w7-l {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
.w8-l {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
.bi-avoid-l {
|
.bi-avoid-l {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,12 @@ const (
|
||||||
ThreadTypePersonalBlogPost
|
ThreadTypePersonalBlogPost
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ValidThreadTypes = []ThreadType{
|
||||||
|
ThreadTypeProjectBlogPost,
|
||||||
|
ThreadTypeForumPost,
|
||||||
|
ThreadTypePersonalBlogPost,
|
||||||
|
}
|
||||||
|
|
||||||
type Thread struct {
|
type Thread struct {
|
||||||
ID int `db:"id"`
|
ID int `db:"id"`
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,18 @@ pre,
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w6 {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w7 {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w8 {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
|
|
||||||
.mw-site {
|
.mw-site {
|
||||||
max-width: var(--site-width);
|
max-width: var(--site-width);
|
||||||
}
|
}
|
||||||
|
@ -422,6 +434,18 @@ pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 35em) {
|
@media screen and (min-width: 35em) {
|
||||||
|
.w6-ns {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w7-ns {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w8-ns {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
|
|
||||||
.bi-avoid-ns {
|
.bi-avoid-ns {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
@ -496,6 +520,18 @@ pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 35em) and (max-width: 60em) {
|
@media screen and (min-width: 35em) and (max-width: 60em) {
|
||||||
|
.w6-m {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w7-m {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w8-m {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
|
|
||||||
.bi-avoid-m {
|
.bi-avoid-m {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
@ -566,6 +602,18 @@ pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 60em) {
|
@media screen and (min-width: 60em) {
|
||||||
|
.w6-l {
|
||||||
|
width: var(--width-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w7-l {
|
||||||
|
width: var(--width-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w8-l {
|
||||||
|
width: var(--width-8);
|
||||||
|
}
|
||||||
|
|
||||||
.bi-avoid-l {
|
.bi-avoid-l {
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,40 @@
|
||||||
-->
|
-->
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
wowoaohaoh
|
<div class="flex justify-center pa3">
|
||||||
|
<div class="w-100 mw-site flex g3">
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div class="w5 flex flex-column g2">
|
||||||
|
<div class="bg--card pa2">
|
||||||
|
<div class="pb2 flex justify-between items-center">
|
||||||
|
<span class="f7">Your projects</span>
|
||||||
|
<span class="svgicon f8">{{ svg "chevron-down" }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
You have not created any projects.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bg--card pa2">
|
||||||
|
<div class="pb2 flex justify-between items-center">
|
||||||
|
<span class="f7">Following</span>
|
||||||
|
<span class="svgicon f8">{{ svg "chevron-down" }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
You are not following anything yet.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Feed -->
|
||||||
|
<div class="flex flex-column flex-grow-1">
|
||||||
|
<div class="timeline flex flex-column g3">
|
||||||
|
{{ range .RecentItems }}
|
||||||
|
{{ template "timeline_item.html" . }}
|
||||||
|
{{ end }}
|
||||||
|
TODO: READ MORE LINK
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -11,58 +11,30 @@ import (
|
||||||
"git.handmade.network/hmn/hmn/src/templates"
|
"git.handmade.network/hmn/hmn/src/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LandingTemplateData struct {
|
|
||||||
templates.BaseData
|
|
||||||
|
|
||||||
NewsPost *templates.TimelineItem
|
|
||||||
FollowingItems []templates.TimelineItem
|
|
||||||
FeaturedItems []templates.TimelineItem
|
|
||||||
RecentItems []templates.TimelineItem
|
|
||||||
NewsItems []templates.TimelineItem
|
|
||||||
|
|
||||||
ManifestoUrl string
|
|
||||||
PodcastUrl string
|
|
||||||
AtomFeedUrl string
|
|
||||||
MarkAllReadUrl string
|
|
||||||
|
|
||||||
JamUrl string
|
|
||||||
JamDaysUntilStart, JamDaysUntilEnd int
|
|
||||||
|
|
||||||
HMSDaysUntilStart, HMSDaysUntilEnd int
|
|
||||||
HMBostonDaysUntilStart, HMBostonDaysUntilEnd int
|
|
||||||
}
|
|
||||||
|
|
||||||
func Index(c *RequestContext) ResponseData {
|
func Index(c *RequestContext) ResponseData {
|
||||||
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
c.Perf.StartBlock("SQL", "Fetch subforum tree")
|
||||||
subforumTree := models.GetFullSubforumTree(c, c.Conn)
|
subforumTree := models.GetFullSubforumTree(c, c.Conn)
|
||||||
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
lineageBuilder := models.MakeSubforumLineageBuilder(subforumTree)
|
||||||
c.Perf.EndBlock()
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
var timelineItems []templates.TimelineItem
|
var err error
|
||||||
|
var followingItems []templates.TimelineItem
|
||||||
|
var featuredItems []templates.TimelineItem
|
||||||
|
var recentItems []templates.TimelineItem
|
||||||
|
var newsItems []templates.TimelineItem
|
||||||
|
|
||||||
FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser)
|
if c.CurrentUser != nil {
|
||||||
|
followingItems, err = FetchFollowTimelineForUser(c, c.Conn, c.CurrentUser)
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Warn().Err(err).Msg("failed to fetch following feed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is essentially an alternate for feed page 1.
|
recentItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, TimelineQuery{
|
||||||
posts, err := hmndata.FetchPosts(c, c.Conn, c.CurrentUser, hmndata.PostsQuery{
|
Limit: 100,
|
||||||
ThreadTypes: feedThreadTypes,
|
|
||||||
Limit: feedPostsPerPage,
|
|
||||||
SortDescending: true,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Warn().Err(err).Msg("failed to fetch latest posts")
|
c.Logger.Warn().Err(err).Msg("failed to fetch recent feed")
|
||||||
}
|
|
||||||
for _, p := range posts {
|
|
||||||
if p.Project.IsHMN() {
|
|
||||||
continue // ignore news posts et. al.
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
// blog post
|
|
||||||
item.Description = template.HTML(p.CurrentVersion.TextParsed)
|
|
||||||
item.TruncateDescription = true
|
|
||||||
}
|
|
||||||
timelineItems = append(timelineItems, item)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Perf.StartBlock("SQL", "Get news")
|
c.Perf.StartBlock("SQL", "Get news")
|
||||||
|
@ -87,6 +59,27 @@ func Index(c *RequestContext) ResponseData {
|
||||||
}
|
}
|
||||||
c.Perf.EndBlock()
|
c.Perf.EndBlock()
|
||||||
|
|
||||||
|
type LandingTemplateData struct {
|
||||||
|
templates.BaseData
|
||||||
|
|
||||||
|
NewsPost *templates.TimelineItem
|
||||||
|
FollowingItems []templates.TimelineItem
|
||||||
|
FeaturedItems []templates.TimelineItem
|
||||||
|
RecentItems []templates.TimelineItem
|
||||||
|
NewsItems []templates.TimelineItem
|
||||||
|
|
||||||
|
ManifestoUrl string
|
||||||
|
PodcastUrl string
|
||||||
|
AtomFeedUrl string
|
||||||
|
MarkAllReadUrl string
|
||||||
|
|
||||||
|
JamUrl string
|
||||||
|
JamDaysUntilStart, JamDaysUntilEnd int
|
||||||
|
|
||||||
|
HMSDaysUntilStart, HMSDaysUntilEnd int
|
||||||
|
HMBostonDaysUntilStart, HMBostonDaysUntilEnd int
|
||||||
|
}
|
||||||
|
|
||||||
baseData := getBaseData(c, "", nil)
|
baseData := getBaseData(c, "", nil)
|
||||||
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
baseData.OpenGraphItems = append(baseData.OpenGraphItems, templates.OpenGraphItem{
|
||||||
Property: "og:description",
|
Property: "og:description",
|
||||||
|
@ -98,7 +91,10 @@ func Index(c *RequestContext) ResponseData {
|
||||||
BaseData: baseData,
|
BaseData: baseData,
|
||||||
|
|
||||||
NewsPost: newsPostItem,
|
NewsPost: newsPostItem,
|
||||||
FollowingItems: timelineItems,
|
FollowingItems: followingItems,
|
||||||
|
FeaturedItems: featuredItems,
|
||||||
|
RecentItems: recentItems,
|
||||||
|
NewsItems: newsItems,
|
||||||
|
|
||||||
ManifestoUrl: hmnurl.BuildManifesto(),
|
ManifestoUrl: hmnurl.BuildManifesto(),
|
||||||
PodcastUrl: hmnurl.BuildPodcast(),
|
PodcastUrl: hmnurl.BuildPodcast(),
|
||||||
|
|
|
@ -62,6 +62,8 @@ func FetchFollowTimelineForUser(ctx context.Context, conn db.ConnOrTx, user *mod
|
||||||
type TimelineQuery struct {
|
type TimelineQuery struct {
|
||||||
UserIDs []int
|
UserIDs []int
|
||||||
ProjectIDs []int
|
ProjectIDs []int
|
||||||
|
|
||||||
|
Limit int
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.User, q TimelineQuery) ([]templates.TimelineItem, error) {
|
func FetchTimeline(ctx context.Context, conn db.ConnOrTx, currentUser *models.User, q TimelineQuery) ([]templates.TimelineItem, error) {
|
||||||
|
|
Loading…
Reference in New Issue