From 82e7dcd3f3253780836c420b6c5683e124e4dae4 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 25 Sep 2023 16:55:57 -0400 Subject: [PATCH 1/3] Add Subscribers page - Shows all fediverse followers and email subscribers - Shows number of email subscribers on Stats page - Links to Subscribers page from Stats page Requires running `make ui` to regenerate stylesheet. Ref T826 --- account.go | 85 +++++++++++++++++++++++++---- collections.go | 8 +++ less/admin.less | 29 ++++++++++ routes.go | 1 + templates/user/include/nav.tmpl | 1 + templates/user/stats.tmpl | 12 +++-- templates/user/subscribers.tmpl | 96 +++++++++++++++++++++++++++++++++ 7 files changed, 217 insertions(+), 15 deletions(-) create mode 100644 templates/user/subscribers.tmpl diff --git a/account.go b/account.go index e902b5b..ecd02e3 100644 --- a/account.go +++ b/account.go @@ -1059,17 +1059,20 @@ func viewStats(app *App, u *User, w http.ResponseWriter, r *http.Request) error } obj := struct { *UserPage - VisitsBlog string - Collection *Collection - TopPosts *[]PublicPost - APFollowers int - Silenced bool + VisitsBlog string + Collection *Collection + TopPosts *[]PublicPost + APFollowers int + EmailEnabled bool + EmailSubscribers int + Silenced bool }{ - UserPage: NewUserPage(app, r, u, titleStats+"Stats", flashes), - VisitsBlog: alias, - Collection: c, - TopPosts: topPosts, - Silenced: silenced, + UserPage: NewUserPage(app, r, u, titleStats+"Stats", flashes), + VisitsBlog: alias, + Collection: c, + TopPosts: topPosts, + EmailEnabled: app.cfg.Email.Enabled(), + Silenced: silenced, } obj.UserPage.CollAlias = c.Alias if app.cfg.App.Federation { @@ -1079,11 +1082,73 @@ func viewStats(app *App, u *User, w http.ResponseWriter, r *http.Request) error } obj.APFollowers = len(*folls) } + if obj.EmailEnabled { + subs, err := app.db.GetEmailSubscribers(c.ID, true) + if err != nil { + return err + } + obj.EmailSubscribers = len(subs) + } showUserPage(w, "stats", obj) return nil } +func handleViewSubscribers(app *App, u *User, w http.ResponseWriter, r *http.Request) error { + vars := mux.Vars(r) + c, err := app.db.GetCollection(vars["collection"]) + if err != nil { + return err + } + + filter := r.FormValue("filter") + + flashes, _ := getSessionFlashes(app, w, r, nil) + obj := struct { + *UserPage + Collection CollectionNav + EmailSubs []*EmailSubscriber + Followers *[]RemoteUser + Silenced bool + + Filter string + FederationEnabled bool + CanEmailSub bool + CanAddSubs bool + EmailSubsEnabled bool + }{ + UserPage: NewUserPage(app, r, u, c.DisplayTitle()+" Subscribers", flashes), + Collection: CollectionNav{ + Collection: c, + Path: r.URL.Path, + SingleUser: app.cfg.App.SingleUser, + }, + Silenced: u.IsSilenced(), + Filter: filter, + FederationEnabled: app.cfg.App.Federation, + CanEmailSub: app.cfg.Email.Enabled(), + EmailSubsEnabled: c.EmailSubsEnabled(), + } + + obj.Followers, err = app.db.GetAPFollowers(c) + if err != nil { + return err + } + + obj.EmailSubs, err = app.db.GetEmailSubscribers(c.ID, true) + if err != nil { + return err + } + + if obj.Filter == "" { + // Set permission to add email subscribers + //obj.CanAddSubs = app.db.GetUserAttribute(c.OwnerID, userAttrCanAddEmailSubs) == "1" + } + + showUserPage(w, "subscribers", obj) + return nil +} + func viewSettings(app *App, u *User, w http.ResponseWriter, r *http.Request) error { fullUser, err := app.db.GetUserByID(u.ID) if err != nil { diff --git a/collections.go b/collections.go index b95c20d..8368447 100644 --- a/collections.go +++ b/collections.go @@ -84,6 +84,14 @@ type ( TotalPages int Silenced bool } + + CollectionNav struct { + *Collection + Path string + SingleUser bool + CanPost bool + } + SubmittedCollection struct { // Data used for updating a given collection ID int64 diff --git a/less/admin.less b/less/admin.less index 86dc9ff..673a03b 100644 --- a/less/admin.less +++ b/less/admin.less @@ -60,6 +60,35 @@ nav#admin { background: #ccc; } } + + &.sub { + margin: 1em 0 2em; + a:not(.toggle) { + border: 0; + border-bottom: 2px transparent solid; + .rounded(0); + padding: 0.5em; + margin-left: 0.5em; + margin-right: 0.5em; + + &:hover { + color: @primary; + background: transparent; + } + &.selected { + color: @primary; + background: transparent; + border-bottom-color: @primary; + } + &+a { + margin-left: 1em; + } + } + a.toggle { + margin-top: -0.5em; + float: right; + } + } } .admin-actions { diff --git a/routes.go b/routes.go index 407d245..f17a72d 100644 --- a/routes.go +++ b/routes.go @@ -99,6 +99,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router { me.HandleFunc("/c/", handler.User(viewCollections)).Methods("GET") me.HandleFunc("/c/{collection}", handler.User(viewEditCollection)).Methods("GET") me.HandleFunc("/c/{collection}/stats", handler.User(viewStats)).Methods("GET") + me.HandleFunc("/c/{collection}/subscribers", handler.User(handleViewSubscribers)).Methods("GET") me.Path("/delete").Handler(csrf.Protect(apper.App().keys.CSRFKey)(handler.User(handleUserDelete))).Methods("POST") me.HandleFunc("/posts", handler.Redirect("/me/posts/", UserLevelUser)).Methods("GET") me.HandleFunc("/posts/", handler.User(viewArticles)).Methods("GET") diff --git a/templates/user/include/nav.tmpl b/templates/user/include/nav.tmpl index 057fc3c..735019d 100644 --- a/templates/user/include/nav.tmpl +++ b/templates/user/include/nav.tmpl @@ -9,6 +9,7 @@ {{if .CanPost}}New Post{{end}} Customize Stats + Subscribers View Blog → diff --git a/templates/user/stats.tmpl b/templates/user/stats.tmpl index 0791f77..b7f3322 100644 --- a/templates/user/stats.tmpl +++ b/templates/user/stats.tmpl @@ -30,15 +30,17 @@ td.none { {{end}}

Stats for all time.

- - {{if .Federation}} -

Fediverse stats

+ + {{if or .Federation .EmailEnabled}} +

Subscribers

- + {{if .Federation}}{{end}} + {{if .EmailEnabled}}{{end}} - + {{if .Federation}}{{end}} + {{if .EmailEnabled}}{{end}}
FollowersFediverse FollowersEmail Subscribers
{{.APFollowers}}{{.APFollowers}}{{.EmailSubscribers}}
{{end}} diff --git a/templates/user/subscribers.tmpl b/templates/user/subscribers.tmpl new file mode 100644 index 0000000..2f21474 --- /dev/null +++ b/templates/user/subscribers.tmpl @@ -0,0 +1,96 @@ +{{define "subscribers"}} +{{template "header" .}} + + + +
+ {{if .Silenced}} + {{template "user-silenced"}} + {{end}} + +{{if .Collection.Collection}}{{template "collection-breadcrumbs" .}}{{end}} + +

Subscribers

+{{if .Collection.Collection}} + {{template "collection-nav" .Collection}} + + +{{end}} + + {{if .Flashes}}{{end}} + + {{ if eq .Filter "fediverse" }} + + + + + + + {{if and (gt (len .Followers) 0) (not .FederationEnabled)}} +
+

Federation is disabled on this server, so followers won't receive any new posts.

+
+ {{end}} + {{ if gt (len .Followers) 0 }} + {{range $el := .Followers}} + + + + + {{end}} + {{ else }} + + + + {{ end }} +
UsernameSince
@{{.EstimatedHandle}}{{.CreatedFriendly}}
No followers yet.
+ {{ else }} + {{if or .CanEmailSub .EmailSubs}} + {{if not .CanEmailSub}} +
+

Email subscriptions are disabled on this server, so no new emails will be sent out.

+
+ {{end}} + {{if not .EmailSubsEnabled}} +
+

Email subscriptions are disabled. {{if .EmailSubs}}No new emails will be sent out.{{end}} To enable email subscriptions, turn the option on from your blog's Customize page.

+
+ {{end}} + + + + + + + {{ if .EmailSubs }} + {{range $el := .EmailSubs}} + + + + + {{end}} + {{ else }} + + + + {{ end }} +
Email AddressSince
{{.Email.String}}{{.SubscribedFriendly}}
No subscribers yet.
+ {{end}} + {{ end }} + +
+ +{{template "foot" .}} + +{{template "body-end" .}} +{{end}} From c75507ca8f96dc0f4ef9c1d9b29b5cb1bb7dca43 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 25 Sep 2023 17:04:08 -0400 Subject: [PATCH 2/3] Add Subscribers navigation for single-user instances Ref T826 --- templates/collection.tmpl | 1 + templates/user/include/header.tmpl | 1 + 2 files changed, 2 insertions(+) diff --git a/templates/collection.tmpl b/templates/collection.tmpl index 8380910..93a01c5 100644 --- a/templates/collection.tmpl +++ b/templates/collection.tmpl @@ -54,6 +54,7 @@ {{if .SimpleNav}}
  • New Post
  • {{end}}
  • Customize
  • Stats
  • +
  • Subscribers

  • {{if not .SingleUser}}
  • View Blogs
  • {{end}}
  • View Drafts
  • diff --git a/templates/user/include/header.tmpl b/templates/user/include/header.tmpl index 66a2a84..9b6912b 100644 --- a/templates/user/include/header.tmpl +++ b/templates/user/include/header.tmpl @@ -18,6 +18,7 @@ From b232e7efd71ef1c12d7c7486323b0cb76984ed6b Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Tue, 3 Oct 2023 10:56:23 -0400 Subject: [PATCH 3/3] Fix indentation in subscribers.tmpl --- templates/user/subscribers.tmpl | 40 +++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/templates/user/subscribers.tmpl b/templates/user/subscribers.tmpl index 2f21474..1e79ddb 100644 --- a/templates/user/subscribers.tmpl +++ b/templates/user/subscribers.tmpl @@ -13,21 +13,23 @@ {{template "user-silenced"}} {{end}} -{{if .Collection.Collection}}{{template "collection-breadcrumbs" .}}{{end}} + {{if .Collection.Collection}}{{template "collection-breadcrumbs" .}}{{end}} -

    Subscribers

    -{{if .Collection.Collection}} - {{template "collection-nav" .Collection}} +

    Subscribers

    + {{if .Collection.Collection}} + {{template "collection-nav" .Collection}} - -{{end}} + + {{end}} - {{if .Flashes}}
      - {{range .Flashes}}
    • {{.}}
    • {{end}} -
    {{end}} + {{if .Flashes -}} +
      + {{range .Flashes}}
    • {{.}}
    • {{end}} +
    + {{- end}} {{ if eq .Filter "fediverse" }} @@ -36,23 +38,23 @@ - {{if and (gt (len .Followers) 0) (not .FederationEnabled)}} + {{if and (gt (len .Followers) 0) (not .FederationEnabled)}}

    Federation is disabled on this server, so followers won't receive any new posts.

    - {{end}} - {{ if gt (len .Followers) 0 }} - {{range $el := .Followers}} + {{end}} + {{ if gt (len .Followers) 0 }} + {{range $el := .Followers}} - {{end}} - {{ else }} + {{end}} + {{ else }} - {{ end }} + {{ end }}
    Since
    @{{.EstimatedHandle}} {{.CreatedFriendly}}
    No followers yet.
    {{ else }} {{if or .CanEmailSub .EmailSubs}}