diff --git a/docs/api/swagger.yaml b/docs/api/swagger.yaml
index 601c3a2b9..783e1147e 100644
--- a/docs/api/swagger.yaml
+++ b/docs/api/swagger.yaml
@@ -143,10 +143,10 @@ definitions:
description: Whether new statuses should be marked sensitive by default.
type: boolean
x-go-name: Sensitive
- status_format:
- description: The default posting format for new statuses.
+ status_content_type:
+ description: The default posting content type for new statuses.
type: string
- x-go-name: StatusFormat
+ x-go-name: StatusContentType
title: Source represents display or publishing preferences of user's own account.
type: object
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
@@ -1240,6 +1240,15 @@ definitions:
format: int64
type: integer
x-go-name: MaxMediaAttachments
+ supported_mime_types:
+ description: List of mime types that it's possible to use for statuses on this instance.
+ example:
+ - text/plain
+ - text/markdown
+ items:
+ type: string
+ type: array
+ x-go-name: SupportedMimeTypes
title: InstanceConfigurationStatuses models instance status config parameters.
type: object
x-go-name: InstanceConfigurationStatuses
@@ -2112,12 +2121,12 @@ definitions:
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
statusCreateRequest:
properties:
- format:
+ content_type:
description: |-
- Format to use when parsing this status.
+ Content type to use when parsing this status.
in: formData
type: string
- x-go-name: Format
+ x-go-name: ContentType
in_reply_to_id:
description: |-
ID of the status being replied to, if status is a reply.
@@ -2463,10 +2472,10 @@ definitions:
description: Mark authored statuses as sensitive by default.
type: boolean
x-go-name: Sensitive
- status_format:
- description: Default format for authored statuses (plain or markdown).
+ status_content_type:
+ description: Default format for authored statuses (text/plain or text/markdown).
type: string
- x-go-name: StatusFormat
+ x-go-name: StatusContentType
title: UpdateSource is to be used specifically in an UpdateCredentialsRequest.
type: object
x-go-name: UpdateSource
@@ -3081,9 +3090,9 @@ paths:
in: formData
name: source[language]
type: string
- - description: Default format to use for authored statuses (plain or markdown).
+ - description: Default content type to use for authored statuses (text/plain or text/markdown).
in: formData
- name: source[status_format]
+ name: source[status_content_type]
type: string
- description: Custom CSS to use when rendering this account's profile or statuses. String must be no more than 5,000 characters (~5kb).
in: formData
@@ -4874,11 +4883,11 @@ paths:
name: language
type: string
x-go-name: Language
- - description: Format to use when parsing this status.
+ - description: Content type to use when parsing this status.
in: formData
- name: format
+ name: content_type
type: string
- x-go-name: Format
+ x-go-name: ContentType
- description: This status will be federated beyond the local timeline(s).
in: query
name: federated
diff --git a/internal/api/client/accounts/accountupdate.go b/internal/api/client/accounts/accountupdate.go
index 3983fe8e1..b5d0dd5f9 100644
--- a/internal/api/client/accounts/accountupdate.go
+++ b/internal/api/client/accounts/accountupdate.go
@@ -99,9 +99,9 @@ import (
// description: Default language to use for authored statuses (ISO 6391).
// type: string
// -
-// name: source[status_format]
+// name: source[status_content_type]
// in: formData
-// description: Default format to use for authored statuses (plain or markdown).
+// description: Default content type to use for authored statuses (text/plain or text/markdown).
// type: string
// -
// name: custom_css
@@ -190,8 +190,8 @@ func parseUpdateAccountForm(c *gin.Context) (*apimodel.UpdateCredentialsRequest,
form.Source.Language = &language
}
- if statusFormat, ok := sourceMap["status_format"]; ok {
- form.Source.StatusFormat = &statusFormat
+ if statusContentType, ok := sourceMap["status_content_type"]; ok {
+ form.Source.StatusContentType = &statusContentType
}
if form == nil ||
@@ -205,7 +205,7 @@ func parseUpdateAccountForm(c *gin.Context) (*apimodel.UpdateCredentialsRequest,
form.Source.Privacy == nil &&
form.Source.Sensitive == nil &&
form.Source.Language == nil &&
- form.Source.StatusFormat == nil &&
+ form.Source.StatusContentType == nil &&
form.FieldsAttributes == nil &&
form.CustomCSS == nil &&
form.EnableRSS == nil) {
diff --git a/internal/api/client/accounts/accountupdate_test.go b/internal/api/client/accounts/accountupdate_test.go
index 95387f3d7..f898e64da 100644
--- a/internal/api/client/accounts/accountupdate_test.go
+++ b/internal/api/client/accounts/accountupdate_test.go
@@ -414,13 +414,13 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpd
suite.True(apimodelAccount.Locked)
}
-func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpdateStatusFormatOK() {
+func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpdateStatusContentTypeOK() {
// set up the request
// we're updating the language of zork
requestBody, w, err := testrig.CreateMultipartFormData(
"", "",
map[string]string{
- "source[status_format]": "markdown",
+ "source[status_content_type]": "text/markdown",
})
if err != nil {
panic(err)
@@ -450,22 +450,22 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpd
// check the returned api model account
// fields should be updated
- suite.Equal("markdown", apimodelAccount.Source.StatusFormat)
+ suite.Equal("text/markdown", apimodelAccount.Source.StatusContentType)
dbAccount, err := suite.db.GetAccountByID(context.Background(), suite.testAccounts["local_account_1"].ID)
if err != nil {
suite.FailNow(err.Error())
}
- suite.Equal(dbAccount.StatusFormat, "markdown")
+ suite.Equal(dbAccount.StatusContentType, "text/markdown")
}
-func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpdateStatusFormatBad() {
+func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpdateStatusContentTypeBad() {
// set up the request
// we're updating the language of zork
requestBody, w, err := testrig.CreateMultipartFormData(
"", "",
map[string]string{
- "source[status_format]": "peepeepoopoo",
+ "source[status_content_type]": "peepeepoopoo",
})
if err != nil {
panic(err)
@@ -486,7 +486,7 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandlerUpd
b, err := ioutil.ReadAll(result.Body)
suite.NoError(err)
- suite.Equal(`{"error":"Bad Request: status format 'peepeepoopoo' was not recognized, valid options are 'plain', 'markdown'"}`, string(b))
+ suite.Equal(`{"error":"Bad Request: status content type 'peepeepoopoo' was not recognized, valid options are 'text/plain', 'text/markdown'"}`, string(b))
}
func TestAccountUpdateTestSuite(t *testing.T) {
diff --git a/internal/api/client/instance/instancepatch_test.go b/internal/api/client/instance/instancepatch_test.go
index 0a508083c..6fb9b0d03 100644
--- a/internal/api/client/instance/instancepatch_test.go
+++ b/internal/api/client/instance/instancepatch_test.go
@@ -90,7 +90,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -188,7 +192,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -286,7 +294,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -435,7 +447,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -554,7 +570,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -689,7 +709,11 @@ func (suite *InstancePatchTestSuite) TestInstancePatch9() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
diff --git a/internal/api/client/statuses/statuscreate_test.go b/internal/api/client/statuses/statuscreate_test.go
index 6802558ec..3c2120105 100644
--- a/internal/api/client/statuses/statuscreate_test.go
+++ b/internal/api/client/statuses/statuscreate_test.go
@@ -105,14 +105,14 @@ func (suite *StatusCreateTestSuite) TestPostNewStatus() {
func (suite *StatusCreateTestSuite) TestPostNewStatusMarkdown() {
// set default post language of account 1 to markdown
testAccount := suite.testAccounts["local_account_1"]
- testAccount.StatusFormat = "markdown"
+ testAccount.StatusContentType = "text/markdown"
a := testAccount
err := suite.db.UpdateAccount(context.Background(), a)
if err != nil {
suite.FailNow(err.Error())
}
- suite.Equal(a.StatusFormat, "markdown")
+ suite.Equal(a.StatusContentType, "text/markdown")
t := suite.testTokens["local_account_1"]
oauthToken := oauth.DBTokenToToken(t)
diff --git a/internal/api/model/account.go b/internal/api/model/account.go
index 238def59d..c275c8155 100644
--- a/internal/api/model/account.go
+++ b/internal/api/model/account.go
@@ -174,8 +174,8 @@ type UpdateSource struct {
Sensitive *bool `form:"sensitive" json:"sensitive" xml:"sensitive"`
// Default language to use for authored statuses. (ISO 6391)
Language *string `form:"language" json:"language" xml:"language"`
- // Default format for authored statuses (plain or markdown).
- StatusFormat *string `form:"status_format" json:"status_format" xml:"status_format"`
+ // Default format for authored statuses (text/plain or text/markdown).
+ StatusContentType *string `form:"status_content_type" json:"status_content_type" xml:"status_content_type"`
}
// UpdateField is to be used specifically in an UpdateCredentialsRequest.
diff --git a/internal/api/model/instance.go b/internal/api/model/instance.go
index c1eec1d54..84e4bab8f 100644
--- a/internal/api/model/instance.go
+++ b/internal/api/model/instance.go
@@ -73,6 +73,10 @@ type InstanceConfigurationStatuses struct {
//
// example: 25
CharactersReservedPerURL int `json:"characters_reserved_per_url"`
+ // List of mime types that it's possible to use for statuses on this instance.
+ //
+ // example: ["text/plain","text/markdown"]
+ SupportedMimeTypes []string `json:"supported_mime_types,omitempty"`
}
// InstanceConfigurationMediaAttachments models instance media attachment config parameters.
diff --git a/internal/api/model/source.go b/internal/api/model/source.go
index 9e2eafa0a..4f32399cc 100644
--- a/internal/api/model/source.go
+++ b/internal/api/model/source.go
@@ -31,8 +31,8 @@ type Source struct {
Sensitive bool `json:"sensitive"`
// The default posting language for new statuses.
Language string `json:"language"`
- // The default posting format for new statuses.
- StatusFormat string `json:"status_format"`
+ // The default posting content type for new statuses.
+ StatusContentType string `json:"status_content_type"`
// Profile bio.
Note string `json:"note"`
// Metadata about the account.
diff --git a/internal/api/model/status.go b/internal/api/model/status.go
index 92741edfe..57f5f6c63 100644
--- a/internal/api/model/status.go
+++ b/internal/api/model/status.go
@@ -179,9 +179,9 @@ type StatusCreateRequest struct {
// ISO 639 language code for this status.
// in: formData
Language string `form:"language" json:"language" xml:"language"`
- // Format to use when parsing this status.
+ // Content type to use when parsing this status.
// in: formData
- Format StatusFormat `form:"format" json:"format" xml:"format"`
+ ContentType StatusContentType `form:"content_type" json:"content_type" xml:"content_type"`
}
// Visibility models the visibility of a status.
@@ -227,16 +227,16 @@ type AdvancedVisibilityFlagsForm struct {
Likeable *bool `form:"likeable" json:"likeable" xml:"likeable"`
}
-// StatusFormat is the format in which to parse the submitted status.
-// Can be either plain or markdown. Empty will default to plain.
+// StatusContentType is the content type with which to parse the submitted status.
+// Can be either text/plain or text/markdown. Empty will default to text/plain.
//
-// swagger:enum statusFormat
+// swagger:enum statusContentType
// swagger:type string
-type StatusFormat string
+type StatusContentType string
-// Format to use when parsing submitted status into an html-formatted status
+// Content type to use when parsing submitted status into an html-formatted status
const (
- StatusFormatPlain StatusFormat = "plain"
- StatusFormatMarkdown StatusFormat = "markdown"
- StatusFormatDefault StatusFormat = StatusFormatPlain
+ StatusContentTypePlain StatusContentType = "text/plain"
+ StatusContentTypeMarkdown StatusContentType = "text/markdown"
+ StatusContentTypeDefault = StatusContentTypePlain
)
diff --git a/internal/db/bundb/basic_test.go b/internal/db/bundb/basic_test.go
index 86a9995fc..13fa9f8c7 100644
--- a/internal/db/bundb/basic_test.go
+++ b/internal/db/bundb/basic_test.go
@@ -89,7 +89,7 @@ func (suite *BasicTestSuite) TestPutAccountWithBunDefaultFields() {
suite.Empty(a.Privacy)
suite.False(*a.Sensitive)
suite.Equal("en", a.Language)
- suite.Empty(a.StatusFormat)
+ suite.Empty(a.StatusContentType)
suite.Equal(testAccount.URI, a.URI)
suite.Equal(testAccount.URL, a.URL)
suite.Zero(testAccount.FetchedAt)
diff --git a/internal/db/bundb/migrations/20230126170719_format_to_content_type.go b/internal/db/bundb/migrations/20230126170719_format_to_content_type.go
new file mode 100644
index 000000000..f8ffb9087
--- /dev/null
+++ b/internal/db/bundb/migrations/20230126170719_format_to_content_type.go
@@ -0,0 +1,96 @@
+/*
+ GoToSocial
+ Copyright (C) 2021-2023 GoToSocial Authors admin@gotosocial.org
+
+ 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 migrations
+
+import (
+ "context"
+ "strings"
+
+ "github.com/uptrace/bun"
+ "github.com/uptrace/bun/dialect"
+)
+
+func init() {
+ up := func(ctx context.Context, db *bun.DB) error {
+ return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+ // Create a new column for status_content_type.
+ if _, err := tx.ExecContext(ctx, "ALTER TABLE ? ADD COLUMN ? TEXT", bun.Ident("accounts"), bun.Ident("status_content_type")); err != nil &&
+ !(strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "duplicate column name") || strings.Contains(err.Error(), "SQLSTATE 42701")) {
+ return err
+ }
+
+ // Port values into this column from the old status_format column,
+ // prepending 'text/' to the value to derive the mime type.
+ //
+ // Eg, 'plain' status_format becomes 'text/plain' status_content_type.
+ q := tx.
+ NewUpdate().
+ Table("accounts").
+ Where("? IS NOT NULL", bun.Ident("status_format"))
+
+ // We need to switch here because Postgres and SQLite
+ // have different syntaxes for concatenation.
+ switch tx.Dialect().Name() {
+ case dialect.SQLite:
+ q = q.
+ Set("? = ? || ?", bun.Ident("status_content_type"), "text/", bun.Ident("status_format"))
+ case dialect.PG:
+ q = q.
+ Set("? = CONCAT(?, ?)", bun.Ident("status_content_type"), "text/", bun.Ident("status_format"))
+ default:
+ panic("db conn was neither pg not sqlite")
+ }
+
+ if _, err := q.Exec(ctx); err != nil {
+ return err
+ }
+
+ // Drop the old status_format column.
+ if _, err := tx.ExecContext(ctx, "ALTER TABLE ? DROP COLUMN ?", bun.Ident("accounts"), bun.Ident("status_format")); err != nil &&
+ !(strings.Contains(err.Error(), "no such column") || strings.Contains(err.Error(), "does not exist") || strings.Contains(err.Error(), "SQLSTATE 42703")) {
+ return err
+ }
+
+ return nil
+ })
+ }
+
+ down := func(ctx context.Context, db *bun.DB) error {
+ return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+ var err error
+ _, err = db.ExecContext(ctx, "ALTER TABLE ? ADD COLUMN ? TEXT", bun.Ident("accounts"), bun.Ident("status_format"))
+ if err != nil && !(strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "duplicate column name") || strings.Contains(err.Error(), "SQLSTATE 42701")) {
+ return err
+ }
+ _, err = db.ExecContext(ctx, "UPDATE ? SET ? = SUBSTR(?, 6) WHERE ? IS NOT NULL", bun.Ident("accounts"), bun.Ident("status_format"), bun.Ident("status_content_type"), bun.Ident("status_content_type"))
+ if err != nil {
+ return err
+ }
+ _, err = db.ExecContext(ctx, "ALTER TABLE ? DROP COLUMN ?", bun.Ident("accounts"), bun.Ident("status_content_type"))
+ if err != nil {
+ return err
+ }
+ return nil
+ })
+ }
+
+ if err := Migrations.Register(up, down); err != nil {
+ panic(err)
+ }
+}
diff --git a/internal/gtsmodel/account.go b/internal/gtsmodel/account.go
index 076bd7a9a..5c5a60373 100644
--- a/internal/gtsmodel/account.go
+++ b/internal/gtsmodel/account.go
@@ -60,7 +60,7 @@ type Account struct {
Privacy Visibility `validate:"required_without=Domain,omitempty,oneof=public unlocked followers_only mutuals_only direct" bun:",nullzero"` // Default post privacy for this account
Sensitive *bool `validate:"-" bun:",default:false"` // Set posts from this account to sensitive by default?
Language string `validate:"omitempty,bcp47_language_tag" bun:",nullzero,notnull,default:'en'"` // What language does this account post in?
- StatusFormat string `validate:"required_without=Domain,omitempty,oneof=plain markdown" bun:",nullzero"` // What is the default format for statuses posted by this account (only for local accounts).
+ StatusContentType string `validate:"required_without=Domain,omitempty,oneof=text/plain text/markdown" bun:",nullzero"` // What is the default format for statuses posted by this account (only for local accounts).
CustomCSS string `validate:"-" bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
URI string `validate:"required,url" bun:",nullzero,notnull,unique"` // ActivityPub URI for this account.
URL string `validate:"required_without=Domain,omitempty,url" bun:",nullzero,unique"` // Web URL for this account's profile
diff --git a/internal/processing/account/update.go b/internal/processing/account/update.go
index 537857cee..a96c17eeb 100644
--- a/internal/processing/account/update.go
+++ b/internal/processing/account/update.go
@@ -79,7 +79,7 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
// Process note to generate a valid HTML representation
var f text.FormatFunc
- if account.StatusFormat == "markdown" {
+ if account.StatusContentType == "text/markdown" {
f = p.formatter.FromMarkdown
} else {
f = p.formatter.FromPlain
@@ -144,12 +144,12 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
account.Privacy = privacy
}
- if form.Source.StatusFormat != nil {
- if err := validate.StatusFormat(*form.Source.StatusFormat); err != nil {
+ if form.Source.StatusContentType != nil {
+ if err := validate.StatusContentType(*form.Source.StatusContentType); err != nil {
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- account.StatusFormat = *form.Source.StatusFormat
+ account.StatusContentType = *form.Source.StatusContentType
}
}
diff --git a/internal/processing/account/update_test.go b/internal/processing/account/update_test.go
index 8ebce7888..486848549 100644
--- a/internal/processing/account/update_test.go
+++ b/internal/processing/account/update_test.go
@@ -122,13 +122,13 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMarkdownNote() {
Note: ¬e,
}
- // set default post language of account 1 to markdown
- testAccount.StatusFormat = "markdown"
+ // set default post content type of account 1 to markdown
+ testAccount.StatusContentType = "text/markdown"
// should get no error from the update function, and an api model account returned
apiAccount, errWithCode := suite.accountProcessor.Update(context.Background(), testAccount, form)
// reset test account to avoid breaking other tests
- testAccount.StatusFormat = "plain"
+ testAccount.StatusContentType = "text/plain"
suite.NoError(errWithCode)
suite.NotNil(apiAccount)
diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go
index 4e5399469..35c36a29b 100644
--- a/internal/processing/status/create.go
+++ b/internal/processing/status/create.go
@@ -290,32 +290,32 @@ func processContent(ctx context.Context, dbService db.DB, formatter text.Formatt
return nil
}
- // if format wasn't specified we should try to figure out what format this user prefers
- if form.Format == "" {
+ // if content type wasn't specified we should try to figure out what content type this user prefers
+ if form.ContentType == "" {
acct, err := dbService.GetAccountByID(ctx, accountID)
if err != nil {
return fmt.Errorf("error processing new content: couldn't retrieve account from db to check post format: %s", err)
}
- switch acct.StatusFormat {
- case "plain":
- form.Format = apimodel.StatusFormatPlain
- case "markdown":
- form.Format = apimodel.StatusFormatMarkdown
+ switch acct.StatusContentType {
+ case "text/plain":
+ form.ContentType = apimodel.StatusContentTypePlain
+ case "text/markdown":
+ form.ContentType = apimodel.StatusContentTypeMarkdown
default:
- form.Format = apimodel.StatusFormatDefault
+ form.ContentType = apimodel.StatusContentTypeDefault
}
}
- // parse content out of the status depending on what format has been submitted
+ // parse content out of the status depending on what content type has been submitted
var f text.FormatFunc
- switch form.Format {
- case apimodel.StatusFormatPlain:
+ switch form.ContentType {
+ case apimodel.StatusContentTypePlain:
f = formatter.FromPlain
- case apimodel.StatusFormatMarkdown:
+ case apimodel.StatusContentTypeMarkdown:
f = formatter.FromMarkdown
default:
- return fmt.Errorf("format %s not recognised as a valid status format", form.Format)
+ return fmt.Errorf("format %s not recognised as a valid status format", form.ContentType)
}
formatted := f(ctx, parseMention, accountID, status.ID, form.Status)
diff --git a/internal/processing/status/create_test.go b/internal/processing/status/create_test.go
index 84adbf32f..717843ce1 100644
--- a/internal/processing/status/create_test.go
+++ b/internal/processing/status/create_test.go
@@ -50,7 +50,7 @@ func (suite *StatusCreateTestSuite) TestProcessContentWarningWithQuotationMarks(
Visibility: apimodel.VisibilityPublic,
ScheduledAt: "",
Language: "en",
- Format: apimodel.StatusFormatPlain,
+ ContentType: apimodel.StatusContentTypePlain,
},
AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{
Federated: nil,
@@ -84,7 +84,7 @@ func (suite *StatusCreateTestSuite) TestProcessContentWarningWithHTMLEscapedQuot
Visibility: apimodel.VisibilityPublic,
ScheduledAt: "",
Language: "en",
- Format: apimodel.StatusFormatPlain,
+ ContentType: apimodel.StatusContentTypePlain,
},
AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{
Federated: nil,
@@ -122,7 +122,7 @@ func (suite *StatusCreateTestSuite) TestProcessStatusMarkdownWithUnderscoreEmoji
Visibility: apimodel.VisibilityPublic,
ScheduledAt: "",
Language: "en",
- Format: apimodel.StatusFormatMarkdown,
+ ContentType: apimodel.StatusContentTypeMarkdown,
},
AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{
Federated: nil,
@@ -156,7 +156,7 @@ func (suite *StatusCreateTestSuite) TestProcessStatusMarkdownWithSpoilerTextEmoj
Visibility: apimodel.VisibilityPublic,
ScheduledAt: "",
Language: "en",
- Format: apimodel.StatusFormatMarkdown,
+ ContentType: apimodel.StatusContentTypeMarkdown,
},
AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{
Federated: nil,
@@ -194,7 +194,7 @@ func (suite *StatusCreateTestSuite) TestProcessMediaDescriptionTooShort() {
Visibility: apimodel.VisibilityPublic,
ScheduledAt: "",
Language: "en",
- Format: apimodel.StatusFormatPlain,
+ ContentType: apimodel.StatusContentTypePlain,
},
AdvancedVisibilityFlagsForm: apimodel.AdvancedVisibilityFlagsForm{
Federated: nil,
diff --git a/internal/trans/import_test.go b/internal/trans/import_test.go
index a53305c79..e980d090b 100644
--- a/internal/trans/import_test.go
+++ b/internal/trans/import_test.go
@@ -111,7 +111,7 @@ func (suite *ImportMinimalTestSuite) TestImportMinimalOK() {
suite.Equal(testAccountBefore.Privacy, testAccountAfter.Privacy)
suite.Equal(testAccountBefore.Sensitive, testAccountAfter.Sensitive)
suite.Equal(testAccountBefore.Language, testAccountAfter.Language)
- suite.Equal(testAccountBefore.StatusFormat, testAccountAfter.StatusFormat)
+ suite.Equal(testAccountBefore.StatusContentType, testAccountAfter.StatusContentType)
suite.Equal(testAccountBefore.URI, testAccountAfter.URI)
suite.Equal(testAccountBefore.URL, testAccountAfter.URL)
suite.Equal(testAccountBefore.InboxURI, testAccountAfter.InboxURI)
diff --git a/internal/trans/model/account.go b/internal/trans/model/account.go
index e29293fdd..cc0ed0f95 100644
--- a/internal/trans/model/account.go
+++ b/internal/trans/model/account.go
@@ -43,7 +43,7 @@ type Account struct {
Privacy string `json:"privacy,omitempty" bun:",nullzero"`
Sensitive *bool `json:"sensitive"`
Language string `json:"language,omitempty" bun:",nullzero"`
- StatusFormat string `json:"statusFormat,omitempty" bun:",nullzero"`
+ StatusContentType string `json:"statusContentType,omitempty" bun:",nullzero"`
URI string `json:"uri" bun:",nullzero"`
URL string `json:"url" bun:",nullzero"`
InboxURI string `json:"inboxURI" bun:",nullzero"`
diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go
index ebea023cf..aa9352272 100644
--- a/internal/typeutils/internaltofrontend.go
+++ b/internal/typeutils/internaltofrontend.go
@@ -46,6 +46,11 @@ const (
instanceSourceURL = "https://github.com/superseriousbusiness/gotosocial"
)
+var instanceStatusesSupportedMimeTypes = []string{
+ string(apimodel.StatusContentTypePlain),
+ string(apimodel.StatusContentTypeMarkdown),
+}
+
func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
// we can build this sensitive account easily by first getting the public account....
apiAccount, err := c.AccountToAPIAccountPublic(ctx, a)
@@ -67,16 +72,16 @@ func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode
frc = len(frs)
}
- statusFormat := string(apimodel.StatusFormatDefault)
- if a.StatusFormat != "" {
- statusFormat = a.StatusFormat
+ statusContentType := string(apimodel.StatusContentTypeDefault)
+ if a.StatusContentType != "" {
+ statusContentType = a.StatusContentType
}
apiAccount.Source = &apimodel.Source{
Privacy: c.VisToAPIVis(ctx, a.Privacy),
Sensitive: *a.Sensitive,
Language: a.Language,
- StatusFormat: statusFormat,
+ StatusContentType: statusContentType,
Note: a.NoteRaw,
Fields: apiAccount.Fields,
FollowRequestsCount: frc,
@@ -695,6 +700,7 @@ func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
instance.Configuration.Statuses.MaxCharacters = config.GetStatusesMaxChars()
instance.Configuration.Statuses.MaxMediaAttachments = config.GetStatusesMediaMaxFiles()
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
+ instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
instance.Configuration.MediaAttachments.ImageSizeLimit = int(config.GetMediaImageMaxSize())
instance.Configuration.MediaAttachments.ImageMatrixLimit = instanceMediaAttachmentsImageMatrixLimit
@@ -820,6 +826,7 @@ func (c *converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
instance.Configuration.Statuses.MaxCharacters = config.GetStatusesMaxChars()
instance.Configuration.Statuses.MaxMediaAttachments = config.GetStatusesMediaMaxFiles()
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
+ instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
instance.Configuration.MediaAttachments.ImageSizeLimit = int(config.GetMediaImageMaxSize())
instance.Configuration.MediaAttachments.ImageMatrixLimit = instanceMediaAttachmentsImageMatrixLimit
diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go
index f82fd8cb5..30241892e 100644
--- a/internal/typeutils/internaltofrontend_test.go
+++ b/internal/typeutils/internaltofrontend_test.go
@@ -198,7 +198,7 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendSensitive() {
"privacy": "public",
"sensitive": false,
"language": "en",
- "status_format": "plain",
+ "status_content_type": "text/plain",
"note": "hey yo this is my profile!",
"fields": [],
"follow_requests_count": 0
@@ -504,7 +504,11 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
@@ -616,7 +620,11 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() {
"statuses": {
"max_characters": 5000,
"max_media_attachments": 6,
- "characters_reserved_per_url": 25
+ "characters_reserved_per_url": 25,
+ "supported_mime_types": [
+ "text/plain",
+ "text/markdown"
+ ]
},
"media_attachments": {
"supported_mime_types": [
diff --git a/internal/validate/account_test.go b/internal/validate/account_test.go
index 3c918e1fc..0e23a2409 100644
--- a/internal/validate/account_test.go
+++ b/internal/validate/account_test.go
@@ -63,7 +63,7 @@ func happyAccount() *gtsmodel.Account {
Privacy: gtsmodel.VisibilityPublic,
Sensitive: testrig.FalseBool(),
Language: "en",
- StatusFormat: "plain",
+ StatusContentType: "text/plain",
URI: "http://localhost:8080/users/the_mighty_zork",
URL: "http://localhost:8080/@the_mighty_zork",
FetchedAt: time.Time{},
diff --git a/internal/validate/formvalidation.go b/internal/validate/formvalidation.go
index 48e0b7015..32aa1fd1e 100644
--- a/internal/validate/formvalidation.go
+++ b/internal/validate/formvalidation.go
@@ -150,16 +150,16 @@ func Privacy(privacy string) error {
return fmt.Errorf("privacy '%s' was not recognized, valid options are 'direct', 'mutuals_only', 'private', 'public', 'unlisted'", privacy)
}
-// StatusFormat checks that the desired status format setting is valid.
-func StatusFormat(statusFormat string) error {
- if statusFormat == "" {
+// StatusContentType checks that the desired status format setting is valid.
+func StatusContentType(statusContentType string) error {
+ if statusContentType == "" {
return fmt.Errorf("empty string for status format not allowed")
}
- switch apimodel.StatusFormat(statusFormat) {
- case apimodel.StatusFormatPlain, apimodel.StatusFormatMarkdown:
+ switch apimodel.StatusContentType(statusContentType) {
+ case apimodel.StatusContentTypePlain, apimodel.StatusContentTypeMarkdown:
return nil
}
- return fmt.Errorf("status format '%s' was not recognized, valid options are 'plain', 'markdown'", statusFormat)
+ return fmt.Errorf("status content type '%s' was not recognized, valid options are 'text/plain', 'text/markdown'", statusContentType)
}
func CustomCSS(customCSS string) error {
diff --git a/web/source/settings/user/settings.js b/web/source/settings/user/settings.js
index 6b6b3c09f..e997beeb6 100644
--- a/web/source/settings/user/settings.js
+++ b/web/source/settings/user/settings.js
@@ -53,14 +53,14 @@ function UserSettingsForm({ data }) {
- string source[privacy]
- bool source[sensitive]
- string source[language]
- - string source[status_format]
+ - string source[status_content_type]
*/
const form = {
defaultPrivacy: useTextInput("source[privacy]", { source: data, defaultValue: "unlisted" }),
isSensitive: useBoolInput("source[sensitive]", { source: data }),
language: useTextInput("source[language]", { source: data, valueSelector: (s) => s.source.language?.toUpperCase() ?? "EN" }),
- format: useTextInput("source[status_format]", { source: data, defaultValue: "plain" }),
+ statusContentType: useTextInput("source[status_content_type]", { source: data, defaultValue: "text/plain" }),
};
const [submitForm, result] = useFormSubmit(form, query.useUpdateCredentialsMutation());
@@ -82,10 +82,10 @@ function UserSettingsForm({ data }) {
}>
Learn more about post privacy settings (opens in a new tab)
-