From 6c53688e069bff5a532314da032b38a14da3e40c Mon Sep 17 00:00:00 2001 From: Asaf Gartner Date: Thu, 8 Jul 2021 10:40:30 +0300 Subject: [PATCH] Project page --- public/style.css | 94 +++---- src/hmnurl/hmnurl_test.go | 4 + src/hmnurl/urls.go | 8 + src/rawdata/scss/_carousel.scss | 74 ++++++ src/rawdata/scss/_projects.scss | 70 ----- src/rawdata/scss/style.scss | 1 + src/templates/mapping.go | 25 +- src/templates/src/include/header.html | 7 +- src/templates/src/include/timeline_item.html | 33 +++ src/templates/src/project_homepage.html | 108 ++++++++ src/templates/src/project_index.html | 26 +- src/templates/src/user_profile.html | 37 +-- src/templates/types.go | 14 +- src/website/forums.go | 2 +- src/website/projects.go | 260 +++++++++++++++++++ src/website/requesthandling.go | 11 - src/website/routes.go | 34 ++- 17 files changed, 609 insertions(+), 199 deletions(-) create mode 100644 src/rawdata/scss/_carousel.scss create mode 100644 src/templates/src/include/timeline_item.html create mode 100644 src/templates/src/project_homepage.html diff --git a/public/style.css b/public/style.css index 548fb10..3d0b8df 100644 --- a/public/style.css +++ b/public/style.css @@ -3231,7 +3231,7 @@ code, .code { .w1 { width: 1rem; } -.w2, .project-carousel-container .project-carousel-button.active { +.w2, .carousel-container .carousel-button.active { width: 2rem; } .w3 { @@ -9288,52 +9288,6 @@ span.icon-rss::before { background-color: #aa7d30; background-color: var(--notice-lts-reqd-color); } -.project-carousel-container { - width: 50rem; } - .project-carousel-container .project-carousel { - box-sizing: content-box; - position: relative; - height: 12rem; } - @media screen and (min-width: 60em) { - .project-carousel-container .project-carousel { - height: 16rem; } } - .project-carousel-container .project-carousel-item { - position: absolute; - top: 0; - left: 0; } - .project-carousel-container .project-carousel-item:not(.active) { - display: none; } - .project-carousel-container .project-carousel-item br { - line-height: 0.6em; } - .project-carousel-container .project-carousel-description { - max-height: 14rem; - overflow: hidden; } - .project-carousel-container .project-carousel-fade { - position: absolute; - left: 0; - right: 0; - bottom: 0; - height: 30px; - background: linear-gradient( rgba(240, 240, 240, 0) , #f0f0f0 ); - background: linear-gradient( var(--dim-background-transparent) , var(--dim-background) ); } - .project-carousel-container .project-carousel-item-small:not(.active) { - display: none; } - .project-carousel-container .project-carousel-button { - border: 1px solid; - border-color: #999; - border-color: var(--dimmer-color); - cursor: pointer; - transition: all 100ms ease-in-out; } - .project-carousel-container .project-carousel-button:hover { - background-color: #bbb; - background-color: var(--dimmest-color); } - .project-carousel-container .project-carousel-button.active { - border-color: #666; - border-color: var(--theme-color); } - .project-carousel-container .project-carousel-button.active:hover { - background-color: #ccc; - background-color: var(--theme-color-dimmest); } - .project-card { color: black; color: var(--fg-font-color); @@ -9546,3 +9500,49 @@ span.icon-rss::before { .timeline-modal .container { width: auto; max-height: calc(100vh - 2rem); } } + +.carousel-container { + width: 50rem; } + .carousel-container .carousel { + box-sizing: content-box; + position: relative; } + .carousel-container .carousel-item { + position: absolute; + top: 0; + left: 0; } + .carousel-container .carousel-item:not(.active) { + display: none; } + .carousel-container .carousel-item br { + line-height: 0.6em; } + .carousel-container .carousel-description { + max-height: 14rem; + overflow: hidden; } + .carousel-container .carousel-fade { + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 30px; + background: linear-gradient( rgba(240, 240, 240, 0) , #f0f0f0 ); + background: linear-gradient( var(--dim-background-transparent) , var(--dim-background) ); } + .carousel-container .carousel-item-small { + position: absolute; + top: 0; + left: 0; } + .carousel-container .carousel-item-small:not(.active) { + display: none; } + .carousel-container .carousel-button { + border: 1px solid; + border-color: #999; + border-color: var(--dimmer-color); + cursor: pointer; + transition: all 100ms ease-in-out; } + .carousel-container .carousel-button:hover { + background-color: #bbb; + background-color: var(--dimmest-color); } + .carousel-container .carousel-button.active { + border-color: #666; + border-color: var(--theme-color); } + .carousel-container .carousel-button.active:hover { + background-color: #ccc; + background-color: var(--theme-color-dimmest); } diff --git a/src/hmnurl/hmnurl_test.go b/src/hmnurl/hmnurl_test.go index 3176495..b14cecb 100644 --- a/src/hmnurl/hmnurl_test.go +++ b/src/hmnurl/hmnurl_test.go @@ -112,6 +112,10 @@ func TestProjectNotApproved(t *testing.T) { AssertRegexMatch(t, BuildProjectNotApproved("test"), RegexProjectNotApproved, map[string]string{"slug": "test"}) } +func TestProjectEdit(t *testing.T) { + AssertRegexMatch(t, BuildProjectEdit("test", "foo"), RegexProjectEdit, map[string]string{"slug": "test"}) +} + func TestPodcast(t *testing.T) { AssertRegexMatch(t, BuildPodcast(""), RegexPodcast, nil) AssertSubdomain(t, BuildPodcast(""), "") diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 6a0cf44..3cb9360 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -232,6 +232,14 @@ func BuildProjectNotApproved(slug string) string { return Url(fmt.Sprintf("/p/%s", slug), nil) } +var RegexProjectEdit = regexp.MustCompile("^/p/(?P.+)/edit$") + +func BuildProjectEdit(slug string, section string) string { + defer CatchPanic() + + return ProjectUrlWithFragment(fmt.Sprintf("/p/%s/edit", slug), nil, "", section) +} + /* * Podcast */ diff --git a/src/rawdata/scss/_carousel.scss b/src/rawdata/scss/_carousel.scss new file mode 100644 index 0000000..ca1eacd --- /dev/null +++ b/src/rawdata/scss/_carousel.scss @@ -0,0 +1,74 @@ +.carousel-container { + width: 50rem; + + .carousel { + box-sizing: content-box; + position: relative; + // height: 12rem; + + @media #{$breakpoint-large} { + // height: $height-5; + } + } + + .carousel-item { + position: absolute; + top: 0; + left: 0; + + &:not(.active) { + display: none; + } + + br { + line-height: 0.6em; + } + } + + .carousel-description { + max-height: 14rem; + overflow: hidden; + } + + .carousel-fade { + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: 30px; + + @include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")") + } + + .carousel-item-small { + position: absolute; + top: 0; + left: 0; + + &:not(.active) { + display: none; + } + } + + .carousel-button { + border: 1px solid; + @include usevar(border-color, dimmer-color); + cursor: pointer; + + transition: all 100ms ease-in-out; + + &:hover { + @include usevar(background-color, dimmest-color); + } + + &.active { + @include usevar(border-color, theme-color); + @extend .w2; + + &:hover { + @include usevar(background-color, theme-color-dimmest); + } + } + } +} + diff --git a/src/rawdata/scss/_projects.scss b/src/rawdata/scss/_projects.scss index 7c45efe..09f0444 100644 --- a/src/rawdata/scss/_projects.scss +++ b/src/rawdata/scss/_projects.scss @@ -93,76 +93,6 @@ @include usevar(background-color, notice-lts-reqd-color); } -.project-carousel-container { - width: 50rem; - - .project-carousel { - box-sizing: content-box; - position: relative; - height: 12rem; - - @media #{$breakpoint-large} { - height: $height-5; - } - } - - .project-carousel-item { - position: absolute; - top: 0; - left: 0; - - &:not(.active) { - display: none; - } - - br { - line-height: 0.6em; - } - } - - .project-carousel-description { - max-height: 14rem; - overflow: hidden; - } - - .project-carousel-fade { - position: absolute; - left: 0; - right: 0; - bottom: 0; - height: 30px; - - @include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")") - } - - .project-carousel-item-small { - &:not(.active) { - display: none; - } - } - - .project-carousel-button { - border: 1px solid; - @include usevar(border-color, dimmer-color); - cursor: pointer; - - transition: all 100ms ease-in-out; - - &:hover { - @include usevar(background-color, dimmest-color); - } - - &.active { - @include usevar(border-color, theme-color); - @extend .w2; - - &:hover { - @include usevar(background-color, theme-color-dimmest); - } - } - } -} - .project-card { @include usevar(color, 'fg-font-color'); @include usevar(background-color, 'card-background'); diff --git a/src/rawdata/scss/style.scss b/src/rawdata/scss/style.scss index e9460cc..17733b2 100644 --- a/src/rawdata/scss/style.scss +++ b/src/rawdata/scss/style.scss @@ -23,3 +23,4 @@ @import 'showcase'; @import 'streams'; @import 'timeline'; +@import 'carousel'; diff --git a/src/templates/mapping.go b/src/templates/mapping.go index a9fa260..a7df12b 100644 --- a/src/templates/mapping.go +++ b/src/templates/mapping.go @@ -216,16 +216,25 @@ func ParseKnownServicesForLink(link *models.Link) (serviceName string, userData func LinkToTemplate(link *models.Link) Link { name := "" - if link.Name != nil { - name = *link.Name - } + /* + // NOTE(asaf): While Name and Key are separate things, Name is almost always the same as Key in the db, which looks weird. + // So we're just going to ignore Name until we decide it's worth reusing. + if link.Name != nil { + name = *link.Name + } + */ serviceName, serviceUserData := ParseKnownServicesForLink(link) + if serviceUserData != "" { + name = serviceUserData + } + if name == "" { + name = link.Value + } return Link{ - Key: link.Key, - ServiceName: serviceName, - ServiceUserData: serviceUserData, - Name: name, - Value: link.Value, + Key: link.Key, + Name: name, + Icon: serviceName, + Url: link.Value, } } diff --git a/src/templates/src/include/header.html b/src/templates/src/include/header.html index 62ccc24..8db3973 100644 --- a/src/templates/src/include/header.html +++ b/src/templates/src/include/header.html @@ -64,10 +64,9 @@ {{ if false }} Episode Guide {{ end }} - {{/* {% if showEditLink == True %} */}} - {{/* {{ if false }} - 0 Settings - {{ end }} */}} + {{ if .Header.EditUrl }} + 0 Settings + {{ end }}
diff --git a/src/templates/src/include/timeline_item.html b/src/templates/src/include/timeline_item.html new file mode 100644 index 0000000..7b374f4 --- /dev/null +++ b/src/templates/src/include/timeline_item.html @@ -0,0 +1,33 @@ +{{ if timelinepostitem . }} +
+ +
+ {{ template "breadcrumbs.html" .Breadcrumbs }} +
{{ .TypeTitle }}: {{ .Title }}
+
+ {{ .OwnerName }} — {{ timehtml (relativedate .Date) .Date }} +
+
+
+{{ else if timelinesnippetitem . }} +
+ +

{{ .Description }}

+
+ {{ if snippetvideo . }} +
+
+{{ end }} + diff --git a/src/templates/src/project_homepage.html b/src/templates/src/project_homepage.html new file mode 100644 index 0000000..f002798 --- /dev/null +++ b/src/templates/src/project_homepage.html @@ -0,0 +1,108 @@ +{{ template "base.html" . }} + +{{ define "extrahead" }} + {{ range .Screenshots }} + + {{ end }} +{{ end }} + +{{ define "content" }} +
+
+ {{ range .Notices }} +
+ {{ .Content }} +
+ {{ end }} + {{ with .Screenshots }} + + {{ end }} +
+ {{ .Project.ParsedDescription }} +
+ {{ with .RecentActivity }} +
+

Recent Activity

+
+ {{ range . }} + {{ template "timeline_item.html" . }} + {{ end }} +
+
+ {{ end }} + {{/* TODO(asaf): Add timeline items for project */}} +
+ +
+ +{{ end }} diff --git a/src/templates/src/project_index.html b/src/templates/src/project_index.html index 32cd839..829df2a 100644 --- a/src/templates/src/project_index.html +++ b/src/templates/src/project_index.html @@ -3,19 +3,19 @@ {{ define "content" }}
{{ with .CarouselProjects }} -