Some tweaks
This commit is contained in:
parent
97ed892ce3
commit
48490d83a9
|
@ -28,7 +28,7 @@ var WRJ2021 = Jam{
|
|||
var WRJ2022 = Jam{
|
||||
Name: "Wheel Reinvention Jam 2022",
|
||||
Slug: "WRJ2022",
|
||||
StartTime: time.Date(2022, 8, 3, 8, 0, 0, 0, utils.Must1(time.LoadLocation("America/Los_Angeles"))),
|
||||
StartTime: time.Date(2022, 8, 15, 8, 0, 0, 0, utils.Must1(time.LoadLocation("America/Los_Angeles"))),
|
||||
EndTime: time.Date(2022, 8, 22, 8, 0, 0, 0, utils.Must1(time.LoadLocation("America/Los_Angeles"))),
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,20 @@
|
|||
<img class="h3" src="{{ static "wheeljam2022/logo.svg" }}">
|
||||
<div id="jam-title-container" class="flex flex-column pl3-m pl4-l pv3 pv0-ns">
|
||||
<h3 id="jam-title">Wheel Reinvention Jam</h3>
|
||||
<div id="jam-details">August 15 - 21. Change the status quo.</div>
|
||||
<div id="jam-details">
|
||||
August 15 - 21.
|
||||
{{ if gt .JamDaysUntilEnd 0 }}
|
||||
{{ if eq .JamDaysUntilStart 0 }}
|
||||
<b>Happening now.</b>
|
||||
{{ else if eq .JamDaysUntilStart 1 }}
|
||||
<b>Starting tomorrow.</b>
|
||||
{{ else }}
|
||||
<b>In {{ .JamDaysUntilStart }} days.</b>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<b>See the results.</b>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1"></div>
|
||||
<div id="jam-learn-more">
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
<meta name="theme-color" content="#346ba6">
|
||||
|
||||
<script src="{{ static "js/templates.js" }}"></script>
|
||||
<script src="{{ static "js/showcase.js" }}"></script>
|
||||
|
||||
<link rel="stylesheet" href="{{ static "fonts/mohave/stylesheet.css" }}">
|
||||
<link href='https://fonts.googleapis.com/css?family=Fira+Sans:300,400,500,600' rel='stylesheet' type='text/css'>
|
||||
|
@ -264,6 +263,31 @@
|
|||
margin-top: 1.6rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3.mt0 {
|
||||
margin-top: 0; /* ugh seriously */
|
||||
}
|
||||
|
||||
.back-to-normal * {
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
}
|
||||
|
||||
.back-to-normal h1,
|
||||
.back-to-normal h2,
|
||||
.back-to-normal h3,
|
||||
.back-to-normal h4,
|
||||
.back-to-normal h5
|
||||
{
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
.back-to-normal a {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="{{ static "js/carousel.js" }}"></script>
|
||||
|
|
|
@ -90,16 +90,15 @@
|
|||
{{ if .ProjectSettings.JamParticipation }}
|
||||
<div class="edit-form-row">
|
||||
<div class="pt-input-ns">Jam Participation</div>
|
||||
</div>
|
||||
<div class="pt-input-ns">
|
||||
{{ range .ProjectSettings.JamParticipation }}
|
||||
<div class="edit-form-row">
|
||||
<div>{{ .JamName }}:</div>
|
||||
<div>
|
||||
<div class="pb1">
|
||||
<input id="jam_{{ .JamSlug }}" type="checkbox" name="jam_participation" value="{{ .JamSlug }}" {{ if .Participating }}checked{{ end }} />
|
||||
<label for="jam_{{ .JamSlug }}">Participating</label>
|
||||
</div>
|
||||
<label for="jam_{{ .JamSlug }}">{{ .JamName }}</label>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if and .Editing .User.IsStaff }}
|
||||
<div class="edit-form-row">
|
||||
|
|
|
@ -5,39 +5,6 @@
|
|||
#title {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h3.mt0 {
|
||||
margin-top: 0; /* ugh seriously */
|
||||
}
|
||||
|
||||
.back-to-normal * {
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
}
|
||||
|
||||
.back-to-normal h1,
|
||||
.back-to-normal h2,
|
||||
.back-to-normal h3,
|
||||
.back-to-normal h4,
|
||||
.back-to-normal h5
|
||||
{
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.25em;
|
||||
}
|
||||
|
||||
.back-to-normal a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 30em) {
|
||||
/* not small styles */
|
||||
}
|
||||
|
||||
@media screen and (min-width: 30em) {
|
||||
/* large styles */
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="top-container" class="flex flex-column items-center ph3">
|
||||
|
@ -50,7 +17,7 @@
|
|||
|
||||
<div class="section bg-black-20 pt4 pb3 pb4-ns">
|
||||
<div class="mw8 margin-center ph3 ph4-l flex flex-column flex-row-ns g3">
|
||||
<div>
|
||||
<div class="flex-grow-1">
|
||||
{{ if eq .DaysUntilEnd 0 }}
|
||||
<h3 class="mt0 mb3">Project updates</h3>
|
||||
{{ else }}
|
||||
|
|
|
@ -3,6 +3,21 @@
|
|||
{{ define "content" }}
|
||||
{{ $discordInviteURL := "https://discord.gg/zFt8Rf59?event=1004511448107602031" }}
|
||||
|
||||
<style>
|
||||
.projects {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 30em) {
|
||||
/* not small styles */
|
||||
|
||||
.projects {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="top-container" class="flex flex-column items-center ph3">
|
||||
<img id="logo" src="{{ static "wheeljam2022/logo.svg" }}">
|
||||
<h1 id="title">Wheel Reinvention Jam</h1>
|
||||
|
@ -22,14 +37,14 @@
|
|||
<div class="actions flex justify-center">
|
||||
{{ if gt .DaysUntilStart 0 }}
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns" target="_blank" href="https://github.com/HandmadeNetwork/wishlist/discussions">Find a project</a>
|
||||
{{ else }}
|
||||
{{ if gt .DaysUntilEnd 0 }}
|
||||
{{ else if gt .DaysUntilEnd 0 }}
|
||||
{{ if .SubmittedProjectUrl }}
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns" target="_blank" href="{{ .SubmittedProjectUrl }}">Share your progress</a>
|
||||
{{ else }}
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" target="_blank" href="{{ .ProjectSubmissionUrl }}">Create your project</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" href="{{ .ShowcaseFeedUrl }}">See the results</a>
|
||||
{{ end }}
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" target="_blank" href="{{ $discordInviteURL }}">Join the Discord</a>
|
||||
</div>
|
||||
|
@ -50,13 +65,27 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
{{ if not (eq .ShowcaseJson "[]") }}
|
||||
{{ if eq .DaysUntilEnd 0 }}
|
||||
<div class="section bg-black-20 pv4 overflow-hidden">
|
||||
<div class="mw8 margin-center ph3 ph4-l">
|
||||
<h2>Submitted projects</h2>
|
||||
<div class="mt3 projects g3 back-to-normal">
|
||||
{{ range .JamProjects }}
|
||||
{{ template "project_card.html" projectcarddata . "" }}
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="actions flex justify-center">
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" href="{{ .ShowcaseFeedUrl }}">See all updates</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ else if and (eq .DaysUntilStart 0) (not (eq .ShowcaseJson "[]")) }}
|
||||
<div id="showcase-outer-container" class="bg-black-20 pt4 pb3 pb4-ns">
|
||||
<div class="section mw8 margin-center ph3 ph4-l">
|
||||
{{ if gt .DaysUntilEnd 0 }}
|
||||
<h2>Recent updates</h2>
|
||||
<p>
|
||||
These screenshots and videos were shared by jam participants in <b>#project-showcase</b> on our <a href="{{ $discordInviteURL }}" target="_blank">Discord</a>. Join us and share what you're working on!
|
||||
These screenshots and videos were shared by jam participants in <b>#project-showcase</b> on our <a href="{{ $discordInviteURL }}" target="_blank">Discord</a>. Join us and share what you're working on! <a class="b" href="{{ .ShowcaseFeedUrl }}">See all ➜</a>
|
||||
</p>
|
||||
{{ else }}
|
||||
<h2>Community showcase</h2>
|
||||
|
@ -66,10 +95,114 @@
|
|||
{{ end }}
|
||||
<div id="showcase-container" class="mw8 center-layout mh2 mh0-ns"></div>
|
||||
<div class="actions flex justify-center">
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" target="_blank" href="{{ .ShowcaseFeedUrl }}">See more</a>
|
||||
<a class="ba b--white br2 pv2 pv3-ns ph3 ph4-ns ml3" target="_blank" href="{{ .ShowcaseFeedUrl }}">See all</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "showcase_templates.html" }}
|
||||
<!-- Copy-pasted and mangled from showcase.html -->
|
||||
<script>
|
||||
const ROW_HEIGHT = 300;
|
||||
const ITEM_SPACING = 4;
|
||||
|
||||
const showcaseItems = JSON.parse("{{ .ShowcaseJson }}");
|
||||
const addThumbnailFuncs = new Array(showcaseItems.length);
|
||||
|
||||
const showcaseOuterContainer = document.querySelector('#showcase-outer-container');
|
||||
let showcaseContainer = document.querySelector('#showcase-container');
|
||||
|
||||
// showcaseOuterContainer.classList.toggle('dn', showcaseItems.length === 0);
|
||||
|
||||
const itemElements = []; // array of arrays
|
||||
for (let i = 0; i < showcaseItems.length; i++) {
|
||||
const item = showcaseItems[i];
|
||||
|
||||
const [itemEl, addThumbnail] = makeShowcaseItem(item);
|
||||
itemEl.container.setAttribute('data-index', i);
|
||||
itemEl.container.setAttribute('data-date', item.date);
|
||||
|
||||
addThumbnailFuncs[i] = addThumbnail;
|
||||
|
||||
itemElements.push(itemEl.container);
|
||||
}
|
||||
|
||||
function layout() {
|
||||
const width = showcaseContainer.getBoundingClientRect().width;
|
||||
showcaseContainer = emptyElement(showcaseContainer);
|
||||
|
||||
function addRow(itemEls, rowWidth, container) {
|
||||
const totalSpacing = ITEM_SPACING * (itemEls.length - 1);
|
||||
const scaleFactor = (width / Math.max(rowWidth, width));
|
||||
|
||||
const row = document.createElement('div');
|
||||
row.classList.add('flex');
|
||||
row.classList.toggle('justify-between', rowWidth >= width);
|
||||
row.style.marginBottom = `${ITEM_SPACING}px`;
|
||||
|
||||
for (const itemEl of itemEls) {
|
||||
const index = parseInt(itemEl.getAttribute('data-index'), 10);
|
||||
const item = showcaseItems[index];
|
||||
|
||||
const aspect = item.width / item.height;
|
||||
const baseWidth = (aspect * ROW_HEIGHT) * scaleFactor;
|
||||
const actualWidth = baseWidth - (totalSpacing / itemEls.length);
|
||||
|
||||
itemEl.style.width = `${actualWidth}px`;
|
||||
itemEl.style.height = `${scaleFactor * ROW_HEIGHT}px`;
|
||||
itemEl.style.marginRight = `${ITEM_SPACING}px`;
|
||||
|
||||
row.appendChild(itemEl);
|
||||
}
|
||||
|
||||
container.appendChild(row);
|
||||
}
|
||||
|
||||
let rowItemEls = [];
|
||||
let rowWidth = 0;
|
||||
let numRows = 0;
|
||||
|
||||
for (const itemEl of itemElements) {
|
||||
const index = parseInt(itemEl.getAttribute('data-index'), 10);
|
||||
const item = showcaseItems[index];
|
||||
|
||||
const aspect = item.width / item.height;
|
||||
rowWidth += aspect * ROW_HEIGHT;
|
||||
|
||||
rowItemEls.push(itemEl);
|
||||
|
||||
if (rowWidth > width) {
|
||||
addRow(rowItemEls, rowWidth, showcaseContainer);
|
||||
numRows += 1;
|
||||
if (numRows == 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
rowItemEls = [];
|
||||
rowWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
addRow(rowItemEls, rowWidth, showcaseContainer);
|
||||
}
|
||||
|
||||
function loadImages() {
|
||||
const items = showcaseContainer.querySelectorAll('.showcase-item');
|
||||
for (const item of items) {
|
||||
const i = parseInt(item.getAttribute('data-index'), 10);
|
||||
addThumbnailFuncs[i]();
|
||||
}
|
||||
}
|
||||
|
||||
layout();
|
||||
layout(); // scrollbars are fun!!
|
||||
|
||||
loadImages();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
layout();
|
||||
});
|
||||
</script>
|
||||
{{ else }}
|
||||
<div class="section bg-black-20 pv4 overflow-hidden">
|
||||
<div class="mw8 margin-center ph3 ph4-l">
|
||||
|
@ -230,110 +363,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{ template "showcase_templates.html" }}
|
||||
<!-- Copy-pasted and mangled from showcase.html -->
|
||||
<script>
|
||||
const ROW_HEIGHT = 300;
|
||||
const ITEM_SPACING = 4;
|
||||
|
||||
const showcaseItems = JSON.parse("{{ .ShowcaseJson }}");
|
||||
const addThumbnailFuncs = new Array(showcaseItems.length);
|
||||
|
||||
const showcaseOuterContainer = document.querySelector('#showcase-outer-container');
|
||||
let showcaseContainer = document.querySelector('#showcase-container');
|
||||
|
||||
// showcaseOuterContainer.classList.toggle('dn', showcaseItems.length === 0);
|
||||
|
||||
const itemElements = []; // array of arrays
|
||||
for (let i = 0; i < showcaseItems.length; i++) {
|
||||
const item = showcaseItems[i];
|
||||
|
||||
const [itemEl, addThumbnail] = makeShowcaseItem(item);
|
||||
itemEl.container.setAttribute('data-index', i);
|
||||
itemEl.container.setAttribute('data-date', item.date);
|
||||
|
||||
addThumbnailFuncs[i] = addThumbnail;
|
||||
|
||||
itemElements.push(itemEl.container);
|
||||
}
|
||||
|
||||
function layout() {
|
||||
const width = showcaseContainer.getBoundingClientRect().width;
|
||||
showcaseContainer = emptyElement(showcaseContainer);
|
||||
|
||||
function addRow(itemEls, rowWidth, container) {
|
||||
const totalSpacing = ITEM_SPACING * (itemEls.length - 1);
|
||||
const scaleFactor = (width / Math.max(rowWidth, width));
|
||||
|
||||
const row = document.createElement('div');
|
||||
row.classList.add('flex');
|
||||
row.classList.toggle('justify-between', rowWidth >= width);
|
||||
row.style.marginBottom = `${ITEM_SPACING}px`;
|
||||
|
||||
for (const itemEl of itemEls) {
|
||||
const index = parseInt(itemEl.getAttribute('data-index'), 10);
|
||||
const item = showcaseItems[index];
|
||||
|
||||
const aspect = item.width / item.height;
|
||||
const baseWidth = (aspect * ROW_HEIGHT) * scaleFactor;
|
||||
const actualWidth = baseWidth - (totalSpacing / itemEls.length);
|
||||
|
||||
itemEl.style.width = `${actualWidth}px`;
|
||||
itemEl.style.height = `${scaleFactor * ROW_HEIGHT}px`;
|
||||
itemEl.style.marginRight = `${ITEM_SPACING}px`;
|
||||
|
||||
row.appendChild(itemEl);
|
||||
}
|
||||
|
||||
container.appendChild(row);
|
||||
}
|
||||
|
||||
let rowItemEls = [];
|
||||
let rowWidth = 0;
|
||||
let numRows = 0;
|
||||
|
||||
for (const itemEl of itemElements) {
|
||||
const index = parseInt(itemEl.getAttribute('data-index'), 10);
|
||||
const item = showcaseItems[index];
|
||||
|
||||
const aspect = item.width / item.height;
|
||||
rowWidth += aspect * ROW_HEIGHT;
|
||||
|
||||
rowItemEls.push(itemEl);
|
||||
|
||||
if (rowWidth > width) {
|
||||
addRow(rowItemEls, rowWidth, showcaseContainer);
|
||||
numRows += 1;
|
||||
if (numRows == 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
rowItemEls = [];
|
||||
rowWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
addRow(rowItemEls, rowWidth, showcaseContainer);
|
||||
}
|
||||
|
||||
function loadImages() {
|
||||
const items = showcaseContainer.querySelectorAll('.showcase-item');
|
||||
for (const item of items) {
|
||||
const i = parseInt(item.getAttribute('data-index'), 10);
|
||||
addThumbnailFuncs[i]();
|
||||
}
|
||||
}
|
||||
|
||||
layout();
|
||||
layout(); // scrollbars are fun!!
|
||||
|
||||
loadImages();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
layout();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
const carouselContainer = document.querySelector('.carousel-container');
|
||||
if (carouselContainer) {
|
||||
|
|
|
@ -30,15 +30,18 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
|||
templates.BaseData
|
||||
DaysUntilStart, DaysUntilEnd int
|
||||
StartTimeUnix, EndTimeUnix int64
|
||||
|
||||
SubmittedProjectUrl string
|
||||
ProjectSubmissionUrl string
|
||||
ShowcaseFeedUrl string
|
||||
ShowcaseJson string
|
||||
|
||||
JamProjects []templates.Project
|
||||
}
|
||||
|
||||
var showcaseItems []templates.TimelineItem
|
||||
submittedProjectUrl := ""
|
||||
if daysUntilStart <= 0 && daysUntilEnd > 0 {
|
||||
|
||||
if c.CurrentUser != nil {
|
||||
projects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{
|
||||
OwnerIDs: []int{c.CurrentUser.ID},
|
||||
|
@ -61,6 +64,11 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
|||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch jam projects for current user"))
|
||||
}
|
||||
|
||||
pageProjects := make([]templates.Project, 0, len(jamProjects))
|
||||
for _, p := range jamProjects {
|
||||
pageProjects = append(pageProjects, templates.ProjectAndStuffToTemplate(&p, hmndata.UrlContextForProject(&p.Project).BuildHomepage(), c.Theme))
|
||||
}
|
||||
|
||||
projectIds := make([]int, 0, len(jamProjects))
|
||||
for _, jp := range jamProjects {
|
||||
projectIds = append(projectIds, jp.Project.ID)
|
||||
|
@ -82,7 +90,7 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showcaseJson := templates.TimelineItemsToJSON(showcaseItems)
|
||||
|
||||
res.MustWriteTemplate("wheeljam_2022_index.html", JamPageData{
|
||||
|
@ -95,6 +103,7 @@ func JamIndex2022(c *RequestContext) ResponseData {
|
|||
SubmittedProjectUrl: submittedProjectUrl,
|
||||
ShowcaseFeedUrl: hmnurl.BuildJamFeed2022(),
|
||||
ShowcaseJson: showcaseJson,
|
||||
JamProjects: pageProjects,
|
||||
}, c.Perf)
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ type LandingTemplateData struct {
|
|||
MarkAllReadUrl string
|
||||
|
||||
JamUrl string
|
||||
JamDaysUntilStart, JamDaysUntilEnd int
|
||||
}
|
||||
|
||||
func Index(c *RequestContext) ResponseData {
|
||||
|
@ -150,6 +151,8 @@ func Index(c *RequestContext) ResponseData {
|
|||
MarkAllReadUrl: hmnurl.HMNProjectContext.BuildForumMarkRead(0),
|
||||
|
||||
JamUrl: hmnurl.BuildJamIndex(),
|
||||
JamDaysUntilStart: daysUntil(hmndata.WRJ2022.StartTime),
|
||||
JamDaysUntilEnd: daysUntil(hmndata.WRJ2022.EndTime),
|
||||
}, c.Perf)
|
||||
if err != nil {
|
||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render landing page template"))
|
||||
|
|
Loading…
Reference in New Issue