Skip to content

Commit 4d30b30

Browse files
committed
Added manual sorting to featured projects.
1 parent 4bcaf3b commit 4d30b30

6 files changed

Lines changed: 66 additions & 13 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package migrations
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"git.handmade.network/hmn/hmn/src/migration/types"
8+
"github.com/jackc/pgx/v5"
9+
)
10+
11+
func init() {
12+
registerMigration(AddSortScore{})
13+
}
14+
15+
type AddSortScore struct{}
16+
17+
func (m AddSortScore) Version() types.MigrationVersion {
18+
return types.MigrationVersion(time.Date(2025, 12, 30, 17, 59, 1, 0, time.UTC))
19+
}
20+
21+
func (m AddSortScore) Name() string {
22+
return "AddSortScore"
23+
}
24+
25+
func (m AddSortScore) Description() string {
26+
return "Add sort score to project for manual sorting on the project page"
27+
}
28+
29+
func (m AddSortScore) Up(ctx context.Context, tx pgx.Tx) error {
30+
_, err := tx.Exec(ctx,
31+
`
32+
ALTER TABLE project
33+
ADD COLUMN sort_score INTEGER NOT NULL DEFAULT 0;
34+
`,
35+
)
36+
return err
37+
}
38+
39+
func (m AddSortScore) Down(ctx context.Context, tx pgx.Tx) error {
40+
_, err := tx.Exec(ctx,
41+
`
42+
ALTER TABLE project
43+
DROP COLUMN sort_score;
44+
`,
45+
)
46+
return err
47+
}

src/models/project.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type Project struct {
7575
Hidden bool `db:"hidden"`
7676
Featured bool `db:"featured"`
7777
JamHidden bool `db:"jam_hidden"`
78+
SortScore int `db:"sort_score"`
7879
DateApproved time.Time `db:"date_approved"`
7980
DateCreated time.Time `db:"date_created"`
8081
AllLastUpdated time.Time `db:"all_last_updated"`

src/templates/mapping.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ func ProjectToProjectSettings(
157157
Logo: AssetToTemplate(logo),
158158
HeaderImage: AssetToTemplate(headerImage),
159159
JamHidden: p.JamHidden,
160+
SortScore: p.SortScore,
160161
}
161162
}
162163

src/templates/src/project_edit.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,11 @@ <h1 class="f3">
244244
<input type="text" id="slug_aliases" name="slug_aliases" class="textbox" value="{{ .ProjectSettings.SlugAliases }}">
245245
<div class="f6">Add any alternate slugs for this project, separated by commas.</div>
246246
</div>
247+
<div class="input-group">
248+
<label for="sort_score">Sort Score</label>
249+
<input type="number" id="sort_score" name="sort_score" class="textbox" value="{{ .ProjectSettings.SortScore }}" />
250+
<div class="f6">Higher score sorts first. Only affects <b>featured</b> projects!</div>
251+
</div>
247252
</div>
248253
</div>
249254
{{ end }}

src/templates/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ type ProjectSettings struct {
180180
Tag string
181181
JamParticipation []ProjectJamParticipation
182182
JamHidden bool
183+
SortScore int
183184

184185
Blurb string
185186
Description string

src/website/projects.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"net/http"
1212
"path"
1313
"sort"
14+
"strconv"
1415
"strings"
1516
"time"
1617

@@ -65,15 +66,9 @@ func getShuffledOfficialProjects(c *RequestContext) ([]templates.Project, error)
6566

6667
defer c.Perf.StartBlock("PROJECT", "Grouping and sorting").End()
6768

68-
var handmadeHero hmndata.ProjectAndStuff
6969
var featuredProjects []hmndata.ProjectAndStuff
7070
var restProjects []hmndata.ProjectAndStuff
7171
for _, p := range official {
72-
if p.Project.Slug == "hero" {
73-
// NOTE(asaf): Handmade Hero gets special treatment. Must always be first in the list.
74-
handmadeHero = p
75-
continue
76-
}
7772
if p.Project.Featured {
7873
featuredProjects = append(featuredProjects, p)
7974
} else {
@@ -82,17 +77,13 @@ func getShuffledOfficialProjects(c *RequestContext) ([]templates.Project, error)
8277
}
8378

8479
sort.Slice(featuredProjects, func(i, j int) bool {
85-
return featuredProjects[i].Project.AllLastUpdated.After(featuredProjects[j].Project.AllLastUpdated)
80+
return featuredProjects[i].Project.SortScore > featuredProjects[j].Project.SortScore
8681
})
8782
sort.Slice(restProjects, func(i, j int) bool {
8883
return restProjects[i].Project.AllLastUpdated.After(restProjects[j].Project.AllLastUpdated)
8984
})
9085

91-
projects := make([]templates.Project, 0, 1+len(featuredProjects)+len(restProjects))
92-
if handmadeHero.Project.ID != 0 {
93-
// NOTE(asaf): As mentioned above, inserting HMH first.
94-
projects = append(projects, templates.ProjectAndStuffToTemplate(&handmadeHero))
95-
}
86+
projects := make([]templates.Project, 0, len(featuredProjects)+len(restProjects))
9687
for _, p := range featuredProjects {
9788
projects = append(projects, templates.ProjectAndStuffToTemplate(&p))
9889
}
@@ -662,6 +653,7 @@ type ProjectPayload struct {
662653
Tag string
663654
JamParticipationSlugs []string
664655
JamHidden bool
656+
SortScore int
665657

666658
Slug string
667659
SlugAliases string // comma-separated
@@ -749,6 +741,9 @@ func ParseProjectEditForm(c *RequestContext) ProjectEditFormResult {
749741
jamParticipationSlugs := c.Req.Form["jam_participation"]
750742
jamHidden := c.Req.Form.Has("jam_hidden")
751743

744+
sortScoreStr := c.Req.Form.Get("sort_score")
745+
sortScore, _ := strconv.Atoi(sortScoreStr)
746+
752747
res.Payload = ProjectPayload{
753748
Name: projectName,
754749
Blurb: shortDesc,
@@ -767,6 +762,7 @@ func ParseProjectEditForm(c *RequestContext) ProjectEditFormResult {
767762
SlugAliases: slugAliases,
768763
Personal: !official,
769764
Featured: featured,
765+
SortScore: sortScore,
770766
}
771767

772768
return res
@@ -860,7 +856,8 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
860856
personal = $4,
861857
hidden = $5,
862858
slug_aliases = $6,
863-
jam_hidden = $7
859+
jam_hidden = $7,
860+
sort_score = $8
864861
WHERE
865862
id = $1
866863
`,
@@ -871,6 +868,7 @@ func updateProject(ctx context.Context, tx pgx.Tx, user *models.User, payload *P
871868
payload.Hidden,
872869
slugAliases,
873870
payload.JamHidden,
871+
payload.SortScore,
874872
)
875873
if err != nil {
876874
return oops.New(err, "Failed to update project with admin fields")

0 commit comments

Comments
 (0)