From aeb65bceae97611b8931de2e954df18afedd812f Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Fri, 12 Jul 2024 20:36:03 +0200 Subject: [feature/frontend] Better visual separation between "main" thread and "replies" (#3093) * [feature/frontend] Better web threading model * fix test * bwap * tweaks * more tweaks to wording * typo * indenting * adjust wording * aaa --- internal/api/client/statuses/statuscontext.go | 10 ++--- internal/api/model/context.go | 28 ------------ internal/api/model/status.go | 36 ++++++++------- internal/api/model/statuscontext.go | 64 +++++++++++++++++++++++++++ internal/api/util/opengraph.go | 2 +- 5 files changed, 91 insertions(+), 49 deletions(-) delete mode 100644 internal/api/model/context.go create mode 100644 internal/api/model/statuscontext.go (limited to 'internal/api') diff --git a/internal/api/client/statuses/statuscontext.go b/internal/api/client/statuses/statuscontext.go index 6441eb738..0eea50819 100644 --- a/internal/api/client/statuses/statuscontext.go +++ b/internal/api/client/statuses/statuscontext.go @@ -27,7 +27,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/oauth" ) -// StatusContextGETHandler swagger:operation GET /api/v1/statuses/{id}/context statusContext +// StatusContextGETHandler swagger:operation GET /api/v1/statuses/{id}/context threadContext // // Return ancestors and descendants of the given status. // @@ -55,9 +55,9 @@ import ( // responses: // '200': // name: statuses -// description: Status context object. +// description: Thread context object. // schema: -// "$ref": "#/definitions/statusContext" +// "$ref": "#/definitions/threadContext" // '400': // description: bad request // '401': @@ -89,11 +89,11 @@ func (m *Module) StatusContextGETHandler(c *gin.Context) { return } - statusContext, errWithCode := m.processor.Status().ContextGet(c.Request.Context(), authed.Account, targetStatusID) + threadContext, errWithCode := m.processor.Status().ContextGet(c.Request.Context(), authed.Account, targetStatusID) if errWithCode != nil { apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) return } - c.JSON(http.StatusOK, statusContext) + c.JSON(http.StatusOK, threadContext) } diff --git a/internal/api/model/context.go b/internal/api/model/context.go deleted file mode 100644 index 69bbc6345..000000000 --- a/internal/api/model/context.go +++ /dev/null @@ -1,28 +0,0 @@ -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package model - -// Context models the tree around a given status. -// -// swagger:model statusContext -type Context struct { - // Parents in the thread. - Ancestors []Status `json:"ancestors"` - // Children in the thread. - Descendants []Status `json:"descendants"` -} diff --git a/internal/api/model/status.go b/internal/api/model/status.go index 0d925d211..00be868f1 100644 --- a/internal/api/model/status.go +++ b/internal/api/model/status.go @@ -102,28 +102,34 @@ type Status struct { Text string `json:"text,omitempty"` // A list of filters that matched this status and why they matched, if there are any such filters. Filtered []FilterResult `json:"filtered,omitempty"` +} - // Additional fields not exposed via JSON - // (used only internally for templating etc). +// WebStatus is like *model.Status, but contains +// additional fields used only for HTML templating. +// +// swagger:ignore +type WebStatus struct { + *Status - // Template-ready language tag + string, based - // on *status.Language. Nil for non-web statuses. - // - // swagger:ignore - LanguageTag *language.Language `json:"-"` + // Template-ready language tag and + // string, based on *status.Language. + LanguageTag *language.Language // Template-ready poll options with vote shares // calculated as a percentage of total votes. - // Nil for non-web statuses. - // - // swagger:ignore - WebPollOptions []WebPollOption `json:"-"` + PollOptions []WebPollOption // Status is from a local account. - // Always false for non-web statuses. - // - // swagger:ignore - Local bool `json:"-"` + Local bool + + // Level of indentation at which to + // display this status in the web view. + Indent int + + // This status is the first status after + // the "main" thread, so it and everything + // below it can be considered "replies". + ThreadFirstReply bool } /* diff --git a/internal/api/model/statuscontext.go b/internal/api/model/statuscontext.go new file mode 100644 index 000000000..205672dc8 --- /dev/null +++ b/internal/api/model/statuscontext.go @@ -0,0 +1,64 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package model + +// ThreadContext models the tree or +// "thread" around a given status. +// +// swagger:model threadContext +type ThreadContext struct { + // Parents in the thread. + Ancestors []Status `json:"ancestors"` + // Children in the thread. + Descendants []Status `json:"descendants"` +} + +type WebThreadContext struct { + // Parents in the thread. + Ancestors []*WebStatus `json:"ancestors"` + + // Children in the thread. + Descendants []*WebStatus `json:"descendants"` + + // The status around which the ancestors + // + descendants context was constructed. + Status *WebStatus `json:"-"` + + // Total length of + // the main thread. + ThreadLength int + + // Number of entries in + // the main thread shown. + ThreadShown int + + // Number of statuses hidden + // from the main thread (not + // visible to requester etc). + ThreadHidden int + + // Total number of replies + // in the replies section. + ThreadReplies int + + // Number of replies shown. + ThreadRepliesShown int + + // Number of replies hidden. + ThreadRepliesHidden int +} diff --git a/internal/api/util/opengraph.go b/internal/api/util/opengraph.go index 185dc8132..062151836 100644 --- a/internal/api/util/opengraph.go +++ b/internal/api/util/opengraph.go @@ -105,7 +105,7 @@ func (og *OGMeta) WithAccount(account *apimodel.Account) *OGMeta { // WithStatus uses the given status to build an ogMeta // struct specific to that status. It's suitable for serving // at status pages. -func (og *OGMeta) WithStatus(status *apimodel.Status) *OGMeta { +func (og *OGMeta) WithStatus(status *apimodel.WebStatus) *OGMeta { og.Title = "Post by " + AccountTitle(status.Account, og.SiteName) og.Type = "article" if status.Language != nil { -- cgit v1.2.3