diff options
author | Gabe Kangas <gabek@real-ity.com> | 2022-02-11 13:37:55 -0800 |
---|---|---|
committer | Gabe Kangas <gabek@real-ity.com> | 2022-02-11 13:37:55 -0800 |
commit | f0435fc7cda1b20935fc1500fa0a67c5d8b5914d (patch) | |
tree | 017f445164303ad524b3475a9cf5ec64ab6c33c1 | |
parent | 63dd625f91f034e3dd1a86a72e8dab44a953915a (diff) |
Use Paginated API for followers tab on frontendgek/paginate-federated-actions-admin
-rw-r--r-- | activitypub/controllers/followers.go | 2 | ||||
-rw-r--r-- | activitypub/outbox/outbox.go | 2 | ||||
-rw-r--r-- | activitypub/persistence/followers.go | 12 | ||||
-rw-r--r-- | controllers/followers.go | 10 | ||||
-rw-r--r-- | router/router.go | 4 | ||||
-rw-r--r-- | webroot/js/components/federation/followers.js | 40 |
6 files changed, 39 insertions, 31 deletions
diff --git a/activitypub/controllers/followers.go b/activitypub/controllers/followers.go index 11193f51a..9a1ba7bdf 100644 --- a/activitypub/controllers/followers.go +++ b/activitypub/controllers/followers.go @@ -98,7 +98,7 @@ func getFollowersPage(page string, r *http.Request) (vocab.ActivityStreamsOrdere return nil, errors.Wrap(err, "unable to get follower count") } - followers, err := persistence.GetFederationFollowers(followersPageSize, (pageInt-1)*followersPageSize) + followers, _, err := persistence.GetFederationFollowers(followersPageSize, (pageInt-1)*followersPageSize) if err != nil { return nil, errors.Wrap(err, "unable to get federation followers") } diff --git a/activitypub/outbox/outbox.go b/activitypub/outbox/outbox.go index cf9c2da46..ce79fbe06 100644 --- a/activitypub/outbox/outbox.go +++ b/activitypub/outbox/outbox.go @@ -171,7 +171,7 @@ func getHashtagLinkHTMLFromTagString(baseHashtag string) string { func SendToFollowers(payload []byte) error { localActor := apmodels.MakeLocalIRIForAccount(data.GetDefaultFederationUsername()) - followers, err := persistence.GetFederationFollowers(-1, 0) + followers, _, err := persistence.GetFederationFollowers(-1, 0) if err != nil { log.Errorln("unable to fetch followers to send to", err) return errors.New("unable to fetch followers to send payload to") diff --git a/activitypub/persistence/followers.go b/activitypub/persistence/followers.go index 77863038e..df40c581f 100644 --- a/activitypub/persistence/followers.go +++ b/activitypub/persistence/followers.go @@ -6,6 +6,7 @@ import ( "github.com/owncast/owncast/db" "github.com/owncast/owncast/models" "github.com/owncast/owncast/utils" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" ) @@ -44,14 +45,19 @@ func GetFollowerCount() (int64, error) { } // GetFederationFollowers will return a slice of the followers we keep track of locally. -func GetFederationFollowers(limit int, offset int) ([]models.Follower, error) { +func GetFederationFollowers(limit int, offset int) ([]models.Follower, int, error) { ctx := context.Background() + total, err := _datastore.GetQueries().GetFollowerCount(ctx) + if err != nil { + return nil, 0, errors.Wrap(err, "unable to fetch total number of followers") + } + followersResult, err := _datastore.GetQueries().GetFederationFollowersWithOffset(ctx, db.GetFederationFollowersWithOffsetParams{ Limit: int32(limit), Offset: int32(offset), }) if err != nil { - return nil, err + return nil, 0, err } followers := make([]models.Follower, 0) @@ -69,7 +75,7 @@ func GetFederationFollowers(limit int, offset int) ([]models.Follower, error) { followers = append(followers, singleFollower) } - return followers, nil + return followers, int(total), nil } // GetPendingFollowRequests will return pending follow requests. diff --git a/controllers/followers.go b/controllers/followers.go index 8561d25a4..0f9c98eaa 100644 --- a/controllers/followers.go +++ b/controllers/followers.go @@ -7,12 +7,16 @@ import ( ) // GetFollowers will handle an API request to fetch the list of followers (non-activitypub response). -func GetFollowers(w http.ResponseWriter, r *http.Request) { - followers, err := persistence.GetFederationFollowers(-1, 0) +func GetFollowers(offset int, limit int, w http.ResponseWriter, r *http.Request) { + followers, total, err := persistence.GetFederationFollowers(limit, offset) if err != nil { WriteSimpleResponse(w, false, "unable to fetch followers") return } - WriteResponse(w, followers) + response := PaginatedResponse{ + Total: total, + Results: followers, + } + WriteResponse(w, response) } diff --git a/router/router.go b/router/router.go index 6f881d8ba..55d3f94c5 100644 --- a/router/router.go +++ b/router/router.go @@ -77,7 +77,7 @@ func Start() error { http.HandleFunc("/api/remotefollow", controllers.RemoteFollow) // return followers - http.HandleFunc("/api/followers", controllers.GetFollowers) + http.HandleFunc("/api/followers", middleware.HandlePagination(controllers.GetFollowers)) // Authenticated admin requests @@ -127,7 +127,7 @@ func Start() error { http.HandleFunc("/api/admin/chat/users/moderators", middleware.RequireAdminAuth(admin.GetModerators)) // return followers - http.HandleFunc("/api/admin/followers", middleware.RequireAdminAuth(controllers.GetFollowers)) + http.HandleFunc("/api/admin/followers", middleware.RequireAdminAuth(middleware.HandlePagination(controllers.GetFollowers))) // Get a list of pending follow requests http.HandleFunc("/api/admin/followers/pending", middleware.RequireAdminAuth(admin.GetPendingFollowRequests)) diff --git a/webroot/js/components/federation/followers.js b/webroot/js/components/federation/followers.js index 6bd6a08b8..89825af62 100644 --- a/webroot/js/components/federation/followers.js +++ b/webroot/js/components/federation/followers.js @@ -2,7 +2,6 @@ import { h, Component } from '/js/web_modules/preact.js'; import htm from '/js/web_modules/htm.js'; import { URL_FOLLOWERS } from '/js/utils/constants.js'; const html = htm.bind(h); -import { paginateArray } from '../../utils/helpers.js'; export default class FollowerList extends Component { constructor(props) { super(props); @@ -10,6 +9,8 @@ export default class FollowerList extends Component { this.state = { followers: [], followersPage: 0, + currentPage: 0, + total: 0, }; } @@ -22,23 +23,26 @@ export default class FollowerList extends Component { } async getFollowers() { - const response = await fetch(URL_FOLLOWERS); + const { currentPage } = this.state; + const limit = 16; + const offset = currentPage * limit; + const u = `${URL_FOLLOWERS}?offset=${offset}&limit=${limit}`; + const response = await fetch(u); const followers = await response.json(); this.setState({ - followers: followers, + followers: followers.results, + total: response.total, }); } changeFollowersPage(page) { - this.setState({ followersPage: page }); + this.setState({ currentPage: page }); + this.getFollowers(); } render() { - const FOLLOWER_PAGE_SIZE = 16; - const { followersPage } = this.state; - - const { followers } = this.state; + const { followers, total, currentPage } = this.state; if (!followers) { return null; } @@ -57,21 +61,15 @@ export default class FollowerList extends Component { </p> </div>`; - const paginatedFollowers = paginateArray( - followers, - followersPage + 1, - FOLLOWER_PAGE_SIZE - ); - const paginationControls = - paginatedFollowers.totalPages > 1 && - Array(paginatedFollowers.totalPages) + total > 1 && + Array(total) .fill() .map((x, n) => { const activePageClass = - n === followersPage && + n === currentPage && 'bg-indigo-600 rounded-full shadow-md focus:shadow-md text-white'; - return html` <li class="page-item active"> + return html` <li class="page-item active w-10"> <a class="page-link relative block cursor-pointer hover:no-underline py-1.5 px-3 border-0 rounded-full hover:text-gray-800 hover:bg-gray-200 outline-none transition-all duration-300 ${activePageClass}" onClick=${() => this.changeFollowersPage(n)} @@ -85,13 +83,13 @@ export default class FollowerList extends Component { <div> <div class="flex flex-wrap"> ${followers.length === 0 && noFollowersInfo} - ${paginatedFollowers.items.map((follower) => { + ${followers.map((follower) => { return html` <${SingleFollower} user=${follower} /> `; })} </div> <div class="flex"> - <nav aria-label="Page navigation example"> - <ul class="flex list-style-none"> + <nav aria-label="Tab pages"> + <ul class="flex list-style-none flex-wrap"> ${paginationControls} </ul> </nav> |