From 33e5d932def1e3f8d0c51d5580d604c033ea6a69 Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Sat, 14 Sep 2019 12:24:39 -0700 Subject: [PATCH] Add support for reordering sponsor slides. --- .../20140823193501_CreateSponsorSlides.sql | 3 +- model/sponsor_slide.go | 9 ++- model/sponsor_slide_test.go | 8 ++- templates/setup_sponsor_slides.html | 16 ++++- web/api_test.go | 4 +- web/setup_lower_thirds.go | 3 +- web/setup_sponsor_slides.go | 67 ++++++++++++++++++- web/setup_sponsor_slides_test.go | 22 +++++- 8 files changed, 117 insertions(+), 15 deletions(-) diff --git a/db/migrations/20140823193501_CreateSponsorSlides.sql b/db/migrations/20140823193501_CreateSponsorSlides.sql index 4e23097..d31a51f 100644 --- a/db/migrations/20140823193501_CreateSponsorSlides.sql +++ b/db/migrations/20140823193501_CreateSponsorSlides.sql @@ -5,7 +5,8 @@ CREATE TABLE sponsor_slides ( line1 VARCHAR(255), line2 VARCHAR(255), image VARCHAR(255), - displaytimesec int + displaytimesec int, + displayorder int ); -- +goose Down diff --git a/model/sponsor_slide.go b/model/sponsor_slide.go index 237e4e1..e28fc23 100644 --- a/model/sponsor_slide.go +++ b/model/sponsor_slide.go @@ -12,6 +12,7 @@ type SponsorSlide struct { Line2 string Image string DisplayTimeSec int + DisplayOrder int } func (database *Database) CreateSponsorSlide(sponsorSlide *SponsorSlide) error { @@ -44,6 +45,12 @@ func (database *Database) TruncateSponsorSlides() error { func (database *Database) GetAllSponsorSlides() ([]SponsorSlide, error) { var sponsorSlides []SponsorSlide - err := database.sponsorSlideMap.Select(&sponsorSlides, "SELECT * FROM sponsor_slides ORDER BY id") + err := database.sponsorSlideMap.Select(&sponsorSlides, "SELECT * FROM sponsor_slides ORDER BY displayorder") return sponsorSlides, err } + +func (database *Database) GetNextSponsorSlideDisplayOrder() int { + var count int + _ = database.sponsorSlideMap.SelectOne(&count, "SELECT MAX(displayorder) + 1 FROM sponsor_slides") + return count +} diff --git a/model/sponsor_slide_test.go b/model/sponsor_slide_test.go index 42c373d..b1c150d 100644 --- a/model/sponsor_slide_test.go +++ b/model/sponsor_slide_test.go @@ -19,11 +19,14 @@ func TestGetNonexistentSponsorSlide(t *testing.T) { func TestSponsorSlideCrud(t *testing.T) { db := setupTestDb(t) - sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10} + assert.Equal(t, 0, db.GetNextSponsorSlideDisplayOrder()) + + sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10, 0} db.CreateSponsorSlide(&sponsorSlide) sponsorSlide2, err := db.GetSponsorSlideById(1) assert.Nil(t, err) assert.Equal(t, sponsorSlide, *sponsorSlide2) + assert.Equal(t, 1, db.GetNextSponsorSlideDisplayOrder()) sponsorSlide.Line1 = "Blorpy" db.SaveSponsorSlide(&sponsorSlide) @@ -40,10 +43,11 @@ func TestSponsorSlideCrud(t *testing.T) { func TestTruncateSponsorSlides(t *testing.T) { db := setupTestDb(t) - sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10} + sponsorSlide := SponsorSlide{0, "Subtitle", "Line 1", "Line 2", "", 10, 0} db.CreateSponsorSlide(&sponsorSlide) db.TruncateSponsorSlides() sponsorSlide2, err := db.GetSponsorSlideById(1) assert.Nil(t, err) assert.Nil(t, sponsorSlide2) + assert.Equal(t, 0, db.GetNextSponsorSlideDisplayOrder()) } diff --git a/templates/setup_sponsor_slides.html b/templates/setup_sponsor_slides.html index a9888ea..c026e4f 100644 --- a/templates/setup_sponsor_slides.html +++ b/templates/setup_sponsor_slides.html @@ -11,7 +11,7 @@
Sponsor Slides Configuration

Place images in /static/img/sponsors/

- {{range $sponsorSlide := .SponsorSlides}} + {{range $i, $sponsorSlide := .SponsorSlides}}
@@ -54,8 +54,18 @@
-
- + {{if lt $i (add (len $.SponsorSlides) -1) }} + +
+ + + {{end}}
diff --git a/web/api_test.go b/web/api_test.go index 86f1e45..9e677a7 100644 --- a/web/api_test.go +++ b/web/api_test.go @@ -84,8 +84,8 @@ func TestRankingsApi(t *testing.T) { func TestSponsorSlidesApi(t *testing.T) { web := setupTestWeb(t) - slide1 := model.SponsorSlide{1, "subtitle", "line1", "line2", "image", 2} - slide2 := model.SponsorSlide{2, "Chezy Sponsaur", "Teh", "Chezy Pofs", "ejface.jpg", 54} + slide1 := model.SponsorSlide{1, "subtitle", "line1", "line2", "image", 2, 0} + slide2 := model.SponsorSlide{2, "Chezy Sponsaur", "Teh", "Chezy Pofs", "ejface.jpg", 54, 1} web.arena.Database.CreateSponsorSlide(&slide1) web.arena.Database.CreateSponsorSlide(&slide2) diff --git a/web/setup_lower_thirds.go b/web/setup_lower_thirds.go index f9c5525..06ddb49 100644 --- a/web/setup_lower_thirds.go +++ b/web/setup_lower_thirds.go @@ -160,6 +160,7 @@ func (web *Web) saveLowerThird(lowerThird *model.LowerThird) error { return nil } +// Swaps the lower third having the given ID with the one immediately above or below it. func (web *Web) reorderLowerThird(id int, moveUp bool) error { lowerThird, err := web.arena.Database.GetLowerThirdById(id) if err != nil { @@ -187,7 +188,7 @@ func (web *Web) reorderLowerThird(id int, moveUp bool) error { // The one to move is already at the limit; return an error to prevent a page reload. return fmt.Errorf("Already at the limit.") } - adjacentLowerThird, err := web.arena.Database.GetLowerThirdById(lowerThirds[lowerThirdIndex].Id) + adjacentLowerThird := &lowerThirds[lowerThirdIndex] if err != nil { return err } diff --git a/web/setup_sponsor_slides.go b/web/setup_sponsor_slides.go index d3401e9..019fa65 100644 --- a/web/setup_sponsor_slides.go +++ b/web/setup_sponsor_slides.go @@ -54,18 +54,21 @@ func (web *Web) sponsorSlidesPostHandler(w http.ResponseWriter, r *http.Request) handleWebErr(w, err) return } - if r.PostFormValue("action") == "delete" { + switch r.PostFormValue("action") { + case "delete": err := web.arena.Database.DeleteSponsorSlide(sponsorSlide) if err != nil { handleWebErr(w, err) return } - } else { + case "save": displayTimeSec, _ := strconv.Atoi(r.PostFormValue("displayTimeSec")) if sponsorSlide == nil { sponsorSlide = &model.SponsorSlide{Subtitle: r.PostFormValue("subtitle"), Line1: r.PostFormValue("line1"), Line2: r.PostFormValue("line2"), - Image: r.PostFormValue("image"), DisplayTimeSec: displayTimeSec} + Image: r.PostFormValue("image"), DisplayTimeSec: displayTimeSec, + DisplayOrder: web.arena.Database.GetNextSponsorSlideDisplayOrder(), + } err = web.arena.Database.CreateSponsorSlide(sponsorSlide) } else { sponsorSlide.Subtitle = r.PostFormValue("subtitle") @@ -79,7 +82,65 @@ func (web *Web) sponsorSlidesPostHandler(w http.ResponseWriter, r *http.Request) handleWebErr(w, err) return } + case "reorderUp": + if err = web.reorderSponsorSlide(sponsorSlideId, true); err != nil { + handleWebErr(w, err) + return + } + case "reorderDown": + if err = web.reorderSponsorSlide(sponsorSlideId, false); err != nil { + handleWebErr(w, err) + return + } } http.Redirect(w, r, "/setup/sponsor_slides", 303) } + +// Swaps the sponsor slide having the given ID with the one immediately above or below it. +func (web *Web) reorderSponsorSlide(id int, moveUp bool) error { + sponsorSlide, err := web.arena.Database.GetSponsorSlideById(id) + if err != nil { + return err + } + + // Get the sponsor slide to swap positions with. + sponsorSlides, err := web.arena.Database.GetAllSponsorSlides() + if err != nil { + return err + } + var sponsorSlideIndex int + for i, slide := range sponsorSlides { + if slide.Id == sponsorSlide.Id { + sponsorSlideIndex = i + break + } + } + if moveUp { + sponsorSlideIndex-- + } else { + sponsorSlideIndex++ + } + if sponsorSlideIndex < 0 || sponsorSlideIndex == len(sponsorSlides) { + // The one to move is already at the limit; do nothing. + return nil + } + adjacentSponsorSlide := &sponsorSlides[sponsorSlideIndex] + if err != nil { + return err + } + + // Swap their display orders and save. + sponsorSlide.DisplayOrder, adjacentSponsorSlide.DisplayOrder = + adjacentSponsorSlide.DisplayOrder, sponsorSlide.DisplayOrder + err = web.arena.Database.SaveSponsorSlide(sponsorSlide) + if err != nil { + return err + } + err = web.arena.Database.SaveSponsorSlide(adjacentSponsorSlide) + if err != nil { + return err + } + + return nil +} diff --git a/web/setup_sponsor_slides_test.go b/web/setup_sponsor_slides_test.go index 03b409f..5e72399 100644 --- a/web/setup_sponsor_slides_test.go +++ b/web/setup_sponsor_slides_test.go @@ -12,8 +12,10 @@ import ( func TestSetupSponsorSlides(t *testing.T) { web := setupTestWeb(t) - web.arena.Database.CreateSponsorSlide(&model.SponsorSlide{0, "Subtitle", "Sponsor Line 1", "Sponsor Line 2", "", 10}) - web.arena.Database.CreateSponsorSlide(&model.SponsorSlide{0, "Subtitle", "", "", "Image.gif", 10}) + web.arena.Database.CreateSponsorSlide(&model.SponsorSlide{0, "Subtitle", "Sponsor Line 1", "Sponsor Line 2", "", 10, + 0}) + web.arena.Database.CreateSponsorSlide(&model.SponsorSlide{0, "Subtitle", "", "", "Image.gif", 10, + 1}) recorder := web.getHttpResponse("/setup/sponsor_slides") assert.Equal(t, 200, recorder.Code) @@ -43,4 +45,20 @@ func TestSetupSponsorSlides(t *testing.T) { assert.Contains(t, recorder.Body.String(), "Image2.gif") sponsorSlide, _ = web.arena.Database.GetSponsorSlideById(3) assert.NotNil(t, sponsorSlide) + + sponsorSlides1, _ := web.arena.Database.GetAllSponsorSlides() + recorder = web.postHttpResponse("/setup/sponsor_slides", "action=reorderUp&id=3") + assert.Equal(t, 303, recorder.Code) + sponsorSlides2, _ := web.arena.Database.GetAllSponsorSlides() + if assert.Equal(t, 2, len(sponsorSlides1)) && assert.Equal(t, 2, len(sponsorSlides2)) { + assert.Equal(t, sponsorSlides1[0].Id, sponsorSlides2[1].Id) + assert.Equal(t, sponsorSlides1[1].Id, sponsorSlides2[0].Id) + } + recorder = web.postHttpResponse("/setup/sponsor_slides", "action=reorderDown&id=3") + assert.Equal(t, 303, recorder.Code) + sponsorSlides3, _ := web.arena.Database.GetAllSponsorSlides() + if assert.Equal(t, 2, len(sponsorSlides1)) && assert.Equal(t, 2, len(sponsorSlides2)) { + assert.Equal(t, sponsorSlides1[0].Id, sponsorSlides3[0].Id) + assert.Equal(t, sponsorSlides1[1].Id, sponsorSlides3[1].Id) + } }