[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
This commit is contained in:
tobi 2024-07-12 20:36:03 +02:00 committed by GitHub
commit aeb65bceae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 895 additions and 385 deletions

View file

@ -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)
}

View file

@ -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
}
/*

View file

@ -17,12 +17,48 @@
package model
// Context models the tree around a given status.
// ThreadContext models the tree or
// "thread" around a given status.
//
// swagger:model statusContext
type Context struct {
// 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
}

View file

@ -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 {