From 92009db2a95e65539b6c2da48b941ceda061cff3 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Thu, 23 Apr 2026 15:47:36 +0100 Subject: [PATCH] appview/db: fix up nits with newsletter handlers Signed-off-by: oppiliappan --- appview/db/db.go | 24 ++++----- appview/db/newsletter.go | 5 +- appview/db/star.go | 2 +- .../timeline/fragments/newsletterForm.html | 16 ++---- .../timeline/fragments/trendingSidebar.html | 6 +-- .../pages/templates/timeline/timeline.html | 52 ++++--------------- appview/state/state.go | 7 +++ flake.lock | 4 +- 8 files changed, 35 insertions(+), 81 deletions(-) diff --git a/appview/db/db.go b/appview/db/db.go index bed57875..58ba0428 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -652,6 +652,14 @@ func Make(ctx context.Context, dbPath string) (*DB, error) { hide_others integer default 0 ); + create table if not exists newsletter_preferences ( + id integer primary key autoincrement, + user_did text not null unique, + status text not null check (status in ('subscribed', 'dismissed')), + email text, + updated_at text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) + ); + -- indexes for better performance create index if not exists idx_notifications_recipient_created on notifications(recipient_did, created desc); create index if not exists idx_notifications_recipient_read on notifications(recipient_did, read); @@ -660,6 +668,7 @@ func Make(ctx context.Context, dbPath string) (*DB, error) { create index if not exists idx_webhooks_repo_at on webhooks(repo_at); create index if not exists idx_webhook_deliveries_webhook_id on webhook_deliveries(webhook_id); create index if not exists idx_site_deploys_repo_at on site_deploys(repo_at); + create index if not exists idx_newsletter_prefs_user_did on newsletter_preferences(user_did); `) if err != nil { return nil, err @@ -1409,21 +1418,6 @@ func Make(ctx context.Context, dbPath string) (*DB, error) { return err }) - orm.RunMigration(conn, logger, "add-newsletter-preferences", func(tx *sql.Tx) error { - _, err := tx.Exec(` - create table if not exists newsletter_preferences ( - id integer primary key autoincrement, - user_did text not null unique, - status text not null check (status in ('subscribed', 'dismissed')), - email text, - updated_at text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) - ); - create index if not exists idx_newsletter_prefs_user_did - on newsletter_preferences(user_did); - `) - return err - }) - return &DB{ db, logger, diff --git a/appview/db/newsletter.go b/appview/db/newsletter.go index b60a914f..f9289728 100644 --- a/appview/db/newsletter.go +++ b/appview/db/newsletter.go @@ -47,10 +47,7 @@ func GetNewsletterPref(e Execer, did string) (*NewsletterPref, error) { if email.Valid { pref.Email = email.String } - // Best-effort: the column's default format is ISO-8601, but older rows - // (or manual inserts) might use other layouts. A parse failure is not - // fatal — the zero time is acceptable for a UI gating check. - if t, perr := time.Parse("2006-01-02T15:04:05Z", updatedAt); perr == nil { + if t, perr := time.Parse(time.RFC3339, updatedAt); perr == nil { pref.UpdatedAt = t } diff --git a/appview/db/star.go b/appview/db/star.go index 0285c819..6c7ae052 100644 --- a/appview/db/star.go +++ b/appview/db/star.go @@ -304,7 +304,7 @@ func GetTopStarredReposLastWeek(e Execer) ([]models.Repo, error) { select rsc.subject_at from repo_star_counts rsc order by rsc.stars_gained_last_week desc - limit 8 + limit 5 ` rows, err := e.Query(query) diff --git a/appview/pages/templates/timeline/fragments/newsletterForm.html b/appview/pages/templates/timeline/fragments/newsletterForm.html index 11a4630d..0e37ae57 100644 --- a/appview/pages/templates/timeline/fragments/newsletterForm.html +++ b/appview/pages/templates/timeline/fragments/newsletterForm.html @@ -1,13 +1,3 @@ -{{/* - Shared newsletter signup form. Variants style the form differently, but the - POST target, response-target id and request plumbing stay identical. - - Params (dict): - Id string - unique id suffix (e.g. "widget", "home"); used to build - the response span's id so multiple signup forms can - coexist on one page without colliding. - Variant string - "card" (compact sidebar card) | "hero" (large CTA) -*/}} {{ define "timeline/fragments/newsletterForm" }} {{ $id := .Id }} {{ $variant := .Variant }} @@ -38,14 +28,14 @@ hx-target="#newsletter-msg-{{ $id }}" hx-swap="outerHTML" hx-vals='{"target":"{{ $id }}"}'> - + - diff --git a/appview/pages/templates/timeline/fragments/trendingSidebar.html b/appview/pages/templates/timeline/fragments/trendingSidebar.html index 5d8dd35d..e8f9875c 100644 --- a/appview/pages/templates/timeline/fragments/trendingSidebar.html +++ b/appview/pages/templates/timeline/fragments/trendingSidebar.html @@ -1,13 +1,13 @@ {{ define "timeline/fragments/trendingSidebar" }} -
+

Trending {{ i "trending-up" "size-4 flex-shrink-0" }}

{{ if .Repos }} -
+
{{ range $index, $repo := .Repos }} -
+
{{ template "user/fragments/repoCard" (list $ $repo true) }}
{{ end }} diff --git a/appview/pages/templates/timeline/timeline.html b/appview/pages/templates/timeline/timeline.html index 03466cbd..9a73f72c 100644 --- a/appview/pages/templates/timeline/timeline.html +++ b/appview/pages/templates/timeline/timeline.html @@ -9,51 +9,25 @@ {{ define "mainLayout" }}
-
+
{{ block "content" . }}{{ end }}
{{ end }} {{ define "content" }} -{{/* - Single responsive grid. Every fragment is rendered once, with CSS alone - handling the mobile → desktop reflow. Only trending has two variants - (horizontal scroll for mobile, vertical sidebar for desktop); both are - present in the DOM and toggled via utility classes. +
- Desktop grid (lg+): - row 1: [ gfi-banner (col-span-2) ] [ newsletter (col 3) ] - row 2: [ timeline (col-span-2) ] [ trendingSidebar (col 3) ] - - When the newsletter is hidden (server-side via .ShowNewsletter, or - client-side via the dismiss button + localStorage), the gfi-banner - widens to col-span-3. -*/}} -
- - {{ if .ShowNewsletter }} -
- {{ template "timeline/fragments/newsletterWidget" . }} -
- {{ end }} - -
- {{ template "timeline/fragments/goodfirstissues" . }} -
- -
+
{{ template "timeline/fragments/timeline" . }}
-
- {{ template "timeline/fragments/trending" . }} -
- - @@ -63,15 +37,8 @@ (function() { var DISMISS_KEY = 'newsletter-dismissed'; var newsletterCol = document.getElementById('newsletter-col'); - var gfi = document.getElementById('gfi-banner'); if (!newsletterCol) return; - function widenGfi() { - if (!gfi) return; - gfi.classList.remove('lg:col-span-2'); - gfi.classList.add('lg:col-span-3', 'lg:max-w-4xl', 'lg:mx-auto'); - } - // hide removes the widget from the DOM without persisting anything. // Used when this browser's localStorage says we already dismissed in a // past session — the server has already told us .ShowNewsletter is true @@ -80,7 +47,6 @@ // device after this localStorage entry was set. function hide() { newsletterCol.remove(); - widenGfi(); } // dismiss is the user-initiated path. Persists both locally and (for diff --git a/appview/state/state.go b/appview/state/state.go index 9ac1abfc..b6d60199 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -362,6 +362,13 @@ func (s *State) NewsletterSignup(w http.ResponseWriter, r *http.Request) { s.logger.Error("failed to add newsletter contact", "error", err) } }() + } else { + s.logger.Error( + "failed to add newsletter contact, missing resend config", + "isKeyPresent", s.config.Resend.ApiKey != "", + "isSegmentIdPresent", s.config.Resend.NewsletterSegmentId != "", + "emailAddr", emailAddr, + ) } s.pages.NewsletterResponse(w, pages.NewsletterResponseParams{Id: target}) diff --git a/flake.lock b/flake.lock index 6570b0b3..ea4a2361 100644 --- a/flake.lock +++ b/flake.lock @@ -120,11 +120,11 @@ "lastModified": 1731402384, "narHash": "sha256-OwUmrPfEehLDz0fl2ChYLK8FQM2p0G1+EMrGsYEq+6g=", "type": "tarball", - "url": "https://github.com/IBM/plex/releases/download/@ibm/plex-mono@1.1.0/ibm-plex-mono.zip" + "url": "https://github.com/IBM/plex/releases/download/@ibm%2Fplex-mono@1.1.0/ibm-plex-mono.zip" }, "original": { "type": "tarball", - "url": "https://github.com/IBM/plex/releases/download/@ibm/plex-mono@1.1.0/ibm-plex-mono.zip" + "url": "https://github.com/IBM/plex/releases/download/@ibm%2Fplex-mono@1.1.0/ibm-plex-mono.zip" } }, "indigo": { -- 2.51.2