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}} -Followers | + {{if .Federation}}Fediverse Followers | {{end}} + {{if .EmailEnabled}}Email Subscribers | {{end}}
---|---|---|
{{.APFollowers}} | + {{if .Federation}}{{.APFollowers}} | {{end}} + {{if .EmailEnabled}}{{.EmailSubscribers}} | {{end}}
Username | +Since | +|
---|---|---|
@{{.EstimatedHandle}} | +{{.CreatedFriendly}} | +|
No followers yet. | +
Email subscriptions are disabled on this server, so no new emails will be sent out.
+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.
+Email Address | +Since | +|
---|---|---|
{{.Email.String}} | +{{.SubscribedFriendly}} | +|
No subscribers yet. | +