mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] add support for polls + receiving federated status edits (#2330)
This commit is contained in:
@@ -66,6 +66,26 @@ func (p *Processor) Create(ctx context.Context, requestingAccount *gtsmodel.Acco
|
||||
Text: form.Status,
|
||||
}
|
||||
|
||||
if form.Poll != nil {
|
||||
// Update the status AS type to "Question".
|
||||
status.ActivityStreamsType = ap.ActivityQuestion
|
||||
|
||||
// Create new poll for status from form.
|
||||
secs := time.Duration(form.Poll.ExpiresIn)
|
||||
status.Poll = >smodel.Poll{
|
||||
ID: id.NewULID(),
|
||||
Multiple: &form.Poll.Multiple,
|
||||
HideCounts: &form.Poll.HideTotals,
|
||||
Options: form.Poll.Options,
|
||||
StatusID: statusID,
|
||||
Status: status,
|
||||
ExpiresAt: now.Add(secs * time.Second),
|
||||
}
|
||||
|
||||
// Set poll ID on the status.
|
||||
status.PollID = status.Poll.ID
|
||||
}
|
||||
|
||||
if errWithCode := p.processReplyToID(ctx, form, requestingAccount.ID, status); errWithCode != nil {
|
||||
return nil, errWithCode
|
||||
}
|
||||
@@ -90,6 +110,14 @@ func (p *Processor) Create(ctx context.Context, requestingAccount *gtsmodel.Acco
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
|
||||
if status.Poll != nil {
|
||||
// Try to insert the new status poll in the database.
|
||||
if err := p.state.DB.PutPoll(ctx, status.Poll); err != nil {
|
||||
err := gtserror.Newf("error inserting poll in db: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Insert this new status in the database.
|
||||
if err := p.state.DB.PutStatus(ctx, status); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
@@ -103,6 +131,15 @@ func (p *Processor) Create(ctx context.Context, requestingAccount *gtsmodel.Acco
|
||||
OriginAccount: requestingAccount,
|
||||
})
|
||||
|
||||
if status.Poll != nil {
|
||||
// Now that the status is inserted, and side effects queued,
|
||||
// attempt to schedule an expiry handler for the status poll.
|
||||
if err := p.polls.ScheduleExpiry(ctx, status.Poll); err != nil {
|
||||
err := gtserror.Newf("error scheduling poll expiry: %w", err)
|
||||
return nil, gtserror.NewErrorInternalError(err)
|
||||
}
|
||||
}
|
||||
|
||||
return p.c.GetAPIStatus(ctx, requestingAccount, status)
|
||||
}
|
||||
|
||||
@@ -370,6 +407,18 @@ func (p *Processor) processContent(ctx context.Context, parseMention gtsmodel.Pa
|
||||
status.ContentWarning = warningRes.HTML
|
||||
status.Emojis = append(status.Emojis, warningRes.Emojis...)
|
||||
|
||||
if status.Poll != nil {
|
||||
for i := range status.Poll.Options {
|
||||
// Sanitize each option title name and format.
|
||||
option := text.SanitizeToPlaintext(status.Poll.Options[i])
|
||||
optionRes := formatInput(format, option)
|
||||
|
||||
// Collect each formatted result.
|
||||
status.Poll.Options[i] = optionRes.HTML
|
||||
status.Emojis = append(status.Emojis, optionRes.Emojis...)
|
||||
}
|
||||
}
|
||||
|
||||
// Gather all the database IDs from each of the gathered status mentions, tags, and emojis.
|
||||
status.MentionIDs = gatherIDs(status.Mentions, func(mention *gtsmodel.Mention) string { return mention.ID })
|
||||
status.TagIDs = gatherIDs(status.Tags, func(tag *gtsmodel.Tag) string { return tag.ID })
|
||||
|
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/common"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/polls"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/text"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
|
||||
@@ -28,7 +29,7 @@ import (
|
||||
)
|
||||
|
||||
type Processor struct {
|
||||
// common processor logic
|
||||
// embedded common logic
|
||||
c *common.Processor
|
||||
|
||||
state *state.State
|
||||
@@ -37,12 +38,16 @@ type Processor struct {
|
||||
filter *visibility.Filter
|
||||
formatter *text.Formatter
|
||||
parseMention gtsmodel.ParseMentionFunc
|
||||
|
||||
// other processors
|
||||
polls *polls.Processor
|
||||
}
|
||||
|
||||
// New returns a new status processor.
|
||||
func New(
|
||||
common *common.Processor,
|
||||
state *state.State,
|
||||
common *common.Processor,
|
||||
polls *polls.Processor,
|
||||
federator *federation.Federator,
|
||||
converter *typeutils.Converter,
|
||||
filter *visibility.Filter,
|
||||
@@ -56,5 +61,6 @@ func New(
|
||||
filter: filter,
|
||||
formatter: text.NewFormatter(state.DB),
|
||||
parseMention: parseMention,
|
||||
polls: polls,
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/superseriousbusiness/gotosocial/internal/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/common"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/polls"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/status"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/storage"
|
||||
@@ -96,8 +97,8 @@ func (suite *StatusStandardTestSuite) SetupTest() {
|
||||
)
|
||||
|
||||
common := common.New(&suite.state, suite.typeConverter, suite.federator, filter)
|
||||
|
||||
suite.status = status.New(&common, &suite.state, suite.federator, suite.typeConverter, filter, processing.GetParseMentionFunc(suite.db, suite.federator))
|
||||
polls := polls.New(&common, &suite.state, suite.typeConverter)
|
||||
suite.status = status.New(&suite.state, &common, &polls, suite.federator, suite.typeConverter, filter, processing.GetParseMentionFunc(suite.db, suite.federator))
|
||||
|
||||
testrig.StandardDBSetup(suite.db, suite.testAccounts)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../testrig/media")
|
||||
|
Reference in New Issue
Block a user