[bugfix] Add support for public:remote stream type (#4899)

Adds support for the `public:remote` stream type, ie., the federated timeline with *only* remote posts in it (as used by masto-fe in the "live feeds -> other servers" tab).

Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4899
This commit is contained in:
tobi
2026-06-23 15:05:02 +02:00
committed by tobi
parent d51bec4999
commit 4bb89d213f
4 changed files with 33 additions and 3 deletions
+3
View File
@@ -15965,6 +15965,7 @@ paths:
`user:notification`: receive notifications for the account.
`public`: receive updates for the public timeline.
`public:local`: receive updates for the local timeline.
`public:remote`: receive updates for the public remote-only timeline
`hashtag`: receive updates for a given hashtag.
`hashtag:local`: receive local updates for a given hashtag.
`list`: receive updates for a certain list of accounts.
@@ -15974,6 +15975,7 @@ paths:
- user:notification
- public
- public:local
- public:remote
- hashtag
- hashtag:local
- list
@@ -16035,6 +16037,7 @@ paths:
- user:notification
- public
- public:local
- public:remote
- hashtag
- hashtag:local
- list
+16 -2
View File
@@ -76,6 +76,7 @@ var pingMsg = []byte("ping!")
// - user:notification
// - public
// - public:local
// - public:remote
// - hashtag
// - hashtag:local
// - list
@@ -89,6 +90,7 @@ var pingMsg = []byte("ping!")
// `user:notification`: receive notifications for the account.
// `public`: receive updates for the public timeline.
// `public:local`: receive updates for the local timeline.
// `public:remote`: receive updates for the public remote-only timeline
// `hashtag`: receive updates for a given hashtag.
// `hashtag:local`: receive local updates for a given hashtag.
// `list`: receive updates for a certain list of accounts.
@@ -128,6 +130,7 @@ var pingMsg = []byte("ping!")
// - user:notification
// - public
// - public:local
// - public:remote
// - hashtag
// - hashtag:local
// - list
@@ -218,6 +221,12 @@ func (m *Module) StreamGETHandler(c *gin.Context) {
// Get the initial requested stream type, if there is one.
streamType := c.Query(StreamQueryKey)
// Rewrite "allow_local_only" type as we always
// allow local-only posts in the public timeline.
if streamType == "public:allow_local_only" {
streamType = "public"
}
// By appending other query params to the streamType, we
// can allow streaming for specific list IDs or hashtags.
// The streamType in this case will end up looking like
@@ -292,7 +301,7 @@ func (m *Module) handleWSConn(l *log.Entry, wsConn *websocket.Conn, stream *stre
defer cncl()
// Read messages from websocket to server.
m.readFromWSConn(ctx, wsConn, stream, l)
m.readFromWSConn(wsConn, stream, l)
}()
go func() {
@@ -325,7 +334,6 @@ func (m *Module) handleWSConn(l *log.Entry, wsConn *websocket.Conn, stream *stre
// This is a blocking function; will return only on read error or
// if the given context is canceled.
func (m *Module) readFromWSConn(
ctx context.Context,
wsConn *websocket.Conn,
stream *streampkg.Stream,
l *log.Entry,
@@ -359,6 +367,12 @@ func (m *Module) readFromWSConn(
// and usually interesting, so log this at info.
l.Infof("received websocket message: %+v", msg)
// Rewrite "allow_local_only" type as we always
// allow local-only posts in the public timeline.
if msg.Stream == "public:allow_local_only" {
msg.Stream = "public"
}
// Ignore if the updateStreamType is unknown (or missing),
// so a bad client can't cause extra memory allocations
if !slices.Contains(streampkg.AllStatusTimelines, msg.Stream) {
+8 -1
View File
@@ -59,10 +59,16 @@ const (
TimelineLocal = "public:local"
// TimelinePublic:
// All public posts known to the server.
// All public posts known to the server,
// including local ones too.
// Analogous to the federated timeline.
TimelinePublic = "public"
// TimelinePublicRemote:
// All *remote* public posts known to
// the server, excluding local posts.
TimelinePublicRemote = "public:remote"
// TimelineHome:
// Events related to the current user, such
// as home feed updates and notifications.
@@ -87,6 +93,7 @@ const (
var AllStatusTimelines = []string{
TimelineLocal,
TimelinePublic,
TimelinePublicRemote,
TimelineHome,
TimelineDirect,
TimelineList,
+6
View File
@@ -77,6 +77,12 @@ func (s *Surfacer) TimelineAndNotifyStatus(ctx context.Context, status *gtsmodel
// Stream the status model as public timeline update event.
s.stream.Update(ctx, account, apiStatus, stream.TimelinePublic)
// If this is a remote status, stream it to
// the public remote-only timeline as well.
if status.Account.IsRemote() {
s.stream.Update(ctx, account, apiStatus, stream.TimelinePublicRemote)
}
},
)