From 5fed25bb0ad81be2f2f542b7a04dd3d84c165481 Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman <the@jeffreyfreeman.me> Date: Sun, 25 Oct 2020 16:32:00 -0400 Subject: [PATCH] Added support for posting in markdown format as well as rendering rich text in general. --- Gemfile | 2 + Gemfile.lock | 6 + .../api/v1/accounts/credentials_controller.rb | 1 + app/controllers/api/v1/statuses_controller.rb | 2 + .../settings/preferences_controller.rb | 1 + app/javascript/mastodon/actions/compose.js | 9 + .../compose/components/compose_form.js | 3 + .../components/content_type_dropdown.js | 272 ++++++++++++++++++ .../containers/compose_form_container.js | 1 + .../content_type_dropdown_container.js | 24 ++ app/javascript/mastodon/locales/ar.json | 3 + app/javascript/mastodon/locales/ast.json | 3 + app/javascript/mastodon/locales/bg.json | 3 + app/javascript/mastodon/locales/bn.json | 3 + app/javascript/mastodon/locales/br.json | 3 + app/javascript/mastodon/locales/ca.json | 3 + app/javascript/mastodon/locales/co.json | 3 + app/javascript/mastodon/locales/cs.json | 3 + app/javascript/mastodon/locales/cy.json | 3 + app/javascript/mastodon/locales/da.json | 3 + app/javascript/mastodon/locales/de.json | 3 + .../mastodon/locales/defaultMessages.json | 17 ++ app/javascript/mastodon/locales/el.json | 3 + app/javascript/mastodon/locales/en.json | 3 + app/javascript/mastodon/locales/eo.json | 3 + app/javascript/mastodon/locales/es-AR.json | 3 + app/javascript/mastodon/locales/es.json | 3 + app/javascript/mastodon/locales/et.json | 3 + app/javascript/mastodon/locales/eu.json | 3 + app/javascript/mastodon/locales/fa.json | 3 + app/javascript/mastodon/locales/fi.json | 3 + app/javascript/mastodon/locales/fr.json | 3 + app/javascript/mastodon/locales/ga.json | 3 + app/javascript/mastodon/locales/gl.json | 3 + app/javascript/mastodon/locales/he.json | 3 + app/javascript/mastodon/locales/hi.json | 3 + app/javascript/mastodon/locales/hr.json | 3 + app/javascript/mastodon/locales/hu.json | 3 + app/javascript/mastodon/locales/hy.json | 3 + app/javascript/mastodon/locales/id.json | 3 + app/javascript/mastodon/locales/io.json | 3 + app/javascript/mastodon/locales/is.json | 3 + app/javascript/mastodon/locales/it.json | 3 + app/javascript/mastodon/locales/ja.json | 3 + app/javascript/mastodon/locales/ka.json | 3 + app/javascript/mastodon/locales/kab.json | 3 + app/javascript/mastodon/locales/kk.json | 3 + app/javascript/mastodon/locales/kn.json | 3 + app/javascript/mastodon/locales/ko.json | 3 + app/javascript/mastodon/locales/ku.json | 3 + app/javascript/mastodon/locales/lt.json | 3 + app/javascript/mastodon/locales/lv.json | 3 + app/javascript/mastodon/locales/mk.json | 3 + app/javascript/mastodon/locales/ml.json | 3 + app/javascript/mastodon/locales/mr.json | 3 + app/javascript/mastodon/locales/ms.json | 3 + app/javascript/mastodon/locales/nl.json | 3 + app/javascript/mastodon/locales/nn.json | 3 + app/javascript/mastodon/locales/no.json | 3 + app/javascript/mastodon/locales/oc.json | 3 + app/javascript/mastodon/locales/pl.json | 3 + app/javascript/mastodon/locales/pt-BR.json | 3 + app/javascript/mastodon/locales/pt-PT.json | 3 + app/javascript/mastodon/locales/ro.json | 3 + app/javascript/mastodon/locales/ru.json | 3 + app/javascript/mastodon/locales/sc.json | 3 + app/javascript/mastodon/locales/sk.json | 3 + app/javascript/mastodon/locales/sl.json | 3 + app/javascript/mastodon/locales/sq.json | 3 + app/javascript/mastodon/locales/sr-Latn.json | 3 + app/javascript/mastodon/locales/sr.json | 3 + app/javascript/mastodon/locales/sv.json | 3 + app/javascript/mastodon/locales/szl.json | 3 + app/javascript/mastodon/locales/ta.json | 3 + app/javascript/mastodon/locales/tai.json | 3 + app/javascript/mastodon/locales/te.json | 3 + app/javascript/mastodon/locales/th.json | 3 + app/javascript/mastodon/locales/tr.json | 3 + app/javascript/mastodon/locales/ug.json | 3 + app/javascript/mastodon/locales/uk.json | 3 + app/javascript/mastodon/locales/ur.json | 3 + app/javascript/mastodon/locales/vi.json | 3 + app/javascript/mastodon/locales/zh-CN.json | 3 + app/javascript/mastodon/locales/zh-HK.json | 3 + app/javascript/mastodon/locales/zh-TW.json | 3 + app/javascript/mastodon/reducers/compose.js | 11 + app/lib/formatter.rb | 42 ++- app/lib/user_settings_decorator.rb | 5 + app/models/status.rb | 6 + app/models/user.rb | 2 +- app/serializers/initial_state_serializer.rb | 1 + .../rest/credential_account_serializer.rb | 1 + app/serializers/rest/status_serializer.rb | 2 +- app/services/post_status_service.rb | 6 + .../settings/preferences/other/show.html.haml | 4 + config/application.rb | 2 + config/locales/en.yml | 3 + config/locales/simple_form.en.yml | 1 + config/locales/simple_form.zh-CN.yml | 1 + config/locales/zh-CN.yml | 3 + config/settings.yml | 1 + ...0926190114_add_content_type_to_statuses.rb | 5 + db/schema.rb | 3 +- lib/kramdown/converter/mastodon.rb | 75 +++++ lib/kramdown/parser/mastodon.rb | 69 +++++ 105 files changed, 790 insertions(+), 13 deletions(-) create mode 100644 app/javascript/mastodon/features/compose/components/content_type_dropdown.js create mode 100644 app/javascript/mastodon/features/compose/containers/content_type_dropdown_container.js create mode 100644 db/migrate/20200926190114_add_content_type_to_statuses.rb create mode 100644 lib/kramdown/converter/mastodon.rb create mode 100644 lib/kramdown/parser/mastodon.rb diff --git a/Gemfile b/Gemfile index d10b88b191..d587db50e6 100644 --- a/Gemfile +++ b/Gemfile @@ -63,6 +63,8 @@ gem 'http_accept_language', '~> 2.1' gem 'httplog', '~> 1.4.3' gem 'idn-ruby', require: 'idn' gem 'kaminari', '~> 1.2' +gem 'kramdown', '~> 2.3' +gem 'kramdown-parser-gfm', '~> 1.1' gem 'link_header', '~> 0.0' gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar' gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b176939f851338d0a4971a532' diff --git a/Gemfile.lock b/Gemfile.lock index 3c23330d13..a31c0ffce5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -324,6 +324,10 @@ GEM activerecord kaminari-core (= 1.2.1) kaminari-core (1.2.1) + kramdown (2.3.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) launchy (2.5.0) addressable (~> 2.7) letter_opener (1.7.0) @@ -760,6 +764,8 @@ DEPENDENCIES json-ld json-ld-preloaded (~> 3.1) kaminari (~> 1.2) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.1) letter_opener (~> 1.7) letter_opener_web (~> 1.4) link_header (~> 0.0) diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index af4b6e68f9..209c8958de 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -34,6 +34,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController 'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive), 'setting_default_language' => source_params.fetch(:language, @account.user.setting_default_language), 'setting_default_federation' => source_params.fetch(:federation, @account.user.setting_default_federation), + 'setting_default_content_type' => source_params.fetch(:content_type, @account.user.setting_default_content_type), } end end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index ec4a56c197..c97822691c 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -53,6 +53,7 @@ class Api::V1::StatusesController < Api::BaseController idempotency: request.headers['Idempotency-Key'], with_rate_limit: true, quote_id: status_params[:quote_id].presence, + content_type: status_params[:content_type], #'text/markdown' local_only: status_params[:local_only]) render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer @@ -102,6 +103,7 @@ class Api::V1::StatusesController < Api::BaseController :quote_id, :expires_at, :expires_action, + :content_type, :local_only, media_ids: [], poll: [ diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 0b2fd4bba9..8c9c2aa3a1 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -37,6 +37,7 @@ class Settings::PreferencesController < Settings::BaseController :setting_default_sensitive, :setting_default_language, :setting_default_federation, + :setting_default_content_type, :setting_unfollow_modal, :setting_unsubscribe_modal, :setting_boost_modal, diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 2dcb95baee..db4d5801a6 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -51,6 +51,7 @@ export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE'; export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE'; export const COMPOSE_CIRCLE_CHANGE = 'COMPOSE_CIRCLE_CHANGE'; export const COMPOSE_FEDERATION_CHANGE = 'COMPOSE_FEDERATION_CHANGE'; +export const COMPOSE_CONTENT_TYPE_CHANGE = 'COMPOSE_CONTENT_TYPE_CHANGE'; export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE'; export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE'; @@ -171,6 +172,7 @@ export function submitCompose(routerHistory) { poll: getState().getIn(['compose', 'poll'], null), quote_id: getState().getIn(['compose', 'quote_from'], null), local_only: !getState().getIn(['compose', 'federation']), + content_type: getState().getIn(['compose', 'content_type']), }, { headers: { 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), @@ -634,6 +636,13 @@ export function changeComposeFederation(value) { }; }; +export function changeComposeContentType(value) { + return { + type: COMPOSE_CONTENT_TYPE_CHANGE, + value, + }; +}; + export function insertEmojiCompose(position, emoji, needsSpace) { return { type: COMPOSE_EMOJI_INSERT, diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index dd243b9d65..5eefc193ac 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -14,6 +14,7 @@ import SpoilerButtonContainer from '../containers/spoiler_button_container'; import PrivacyDropdownContainer from '../containers/privacy_dropdown_container'; import CircleDropdownContainer from '../containers/circle_dropdown_container'; import FederationDropdownContainer from '../containers/federation_dropdown_container'; +import ContentTypeDropdownContainer from '../containers/content_type_dropdown_container'; import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container'; import PollFormContainer from '../containers/poll_form_container'; import UploadFormContainer from '../containers/upload_form_container'; @@ -47,6 +48,7 @@ class ComposeForm extends ImmutablePureComponent { spoiler: PropTypes.bool, privacy: PropTypes.string, federation: PropTypes.bool, + contentType: PropTypes.string, spoilerText: PropTypes.string, focusDate: PropTypes.instanceOf(Date), caretPosition: PropTypes.number, @@ -246,6 +248,7 @@ class ComposeForm extends ImmutablePureComponent { <div className='compose-form__buttons'> <UploadButtonContainer /> <PollButtonContainer /> + <ContentTypeDropdownContainer/> <PrivacyDropdownContainer /> <SpoilerButtonContainer /> <FederationDropdownContainer /> diff --git a/app/javascript/mastodon/features/compose/components/content_type_dropdown.js b/app/javascript/mastodon/features/compose/components/content_type_dropdown.js new file mode 100644 index 0000000000..5ac32cf20c --- /dev/null +++ b/app/javascript/mastodon/features/compose/components/content_type_dropdown.js @@ -0,0 +1,272 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { injectIntl, defineMessages } from 'react-intl'; +import IconButton from '../../../components/icon_button'; +import Overlay from 'react-overlays/lib/Overlay'; +import Motion from '../../ui/util/optional_motion'; +import spring from 'react-motion/lib/spring'; +import detectPassiveEvents from 'detect-passive-events'; +import classNames from 'classnames'; +import Icon from 'mastodon/components/icon'; + +const messages = defineMessages({ + plain: { id: 'content_type.plain.short', defaultMessage: 'Plain Text' }, + markdown: { id: 'content_type.markdown.short', defaultMessage: 'Markdown' }, + change_content_type: { id: 'content_type.change', defaultMessage: 'Adjust status content type' }, +}); + +const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false; + +class ContentTypeDropdownMenu extends React.PureComponent { + + static propTypes = { + style: PropTypes.object, + items: PropTypes.array.isRequired, + value: PropTypes.string.isRequired, + placement: PropTypes.string.isRequired, + onClose: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + }; + + state = { + mounted: false, + }; + + handleDocumentClick = e => { + if (this.node && !this.node.contains(e.target)) { + this.props.onClose(); + } + } + + handleKeyDown = e => { + const { items } = this.props; + const value = e.currentTarget.getAttribute('data-index'); + const index = items.findIndex(item => { + return (item.value === value); + }); + let element = null; + + switch(e.key) { + case 'Escape': + this.props.onClose(); + break; + case 'Enter': + this.handleClick(e); + break; + case 'ArrowDown': + element = this.node.childNodes[index + 1] || this.node.firstChild; + break; + case 'ArrowUp': + element = this.node.childNodes[index - 1] || this.node.lastChild; + break; + case 'Tab': + if (e.shiftKey) { + element = this.node.childNodes[index - 1] || this.node.lastChild; + } else { + element = this.node.childNodes[index + 1] || this.node.firstChild; + } + break; + case 'Home': + element = this.node.firstChild; + break; + case 'End': + element = this.node.lastChild; + break; + } + + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + e.preventDefault(); + e.stopPropagation(); + } + } + + handleClick = e => { + const value = e.currentTarget.getAttribute('data-index'); + + e.preventDefault(); + + this.props.onClose(); + this.props.onChange(value); + } + + componentDidMount () { + document.addEventListener('click', this.handleDocumentClick, false); + document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + if (this.focusedItem) this.focusedItem.focus({ preventScroll: true }); + this.setState({ mounted: true }); + } + + componentWillUnmount () { + document.removeEventListener('click', this.handleDocumentClick, false); + document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); + } + + setRef = c => { + this.node = c; + } + + setFocusRef = c => { + this.focusedItem = c; + } + + render () { + const { mounted } = this.state; + const { style, items, placement, value } = this.props; + + return ( + <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}> + {({ opacity, scaleX, scaleY }) => ( + // It should not be transformed when mounting because the resulting + // size will be used to determine the coordinate of the menu by + // react-overlays + <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null, zIndex: 2 }} role='listbox' ref={this.setRef}> + {items.map(item => ( + <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}> + <div className='privacy-dropdown__option__icon'> + <Icon id={item.icon} fixedWidth /> + </div> + + <div className='privacy-dropdown__option__content'> + <strong>{item.text}</strong> + {item.meta} + </div> + </div> + ))} + </div> + )} + </Motion> + ); + } + +} + +export default @injectIntl +class ContentTypeDropdown extends React.PureComponent { + + static propTypes = { + isUserTouching: PropTypes.func, + isModalOpen: PropTypes.bool.isRequired, + onModalOpen: PropTypes.func, + onModalClose: PropTypes.func, + value: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + }; + + state = { + open: false, + placement: 'bottom', + }; + + handleToggle = ({ target }) => { + if (this.props.isUserTouching()) { + if (this.state.open) { + this.props.onModalClose(); + } else { + this.props.onModalOpen({ + actions: this.options.map(option => ({ ...option, active: option.value === this.props.value })), + onClick: this.handleModalActionClick, + }); + } + } else { + const { top } = target.getBoundingClientRect(); + if (this.state.open && this.activeElement) { + this.activeElement.focus({ preventScroll: true }); + } + this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); + this.setState({ open: !this.state.open }); + } + } + + handleModalActionClick = (e) => { + e.preventDefault(); + + const { value } = this.options[e.currentTarget.getAttribute('data-index')]; + + this.props.onModalClose(); + this.props.onChange(value); + } + + handleKeyDown = e => { + switch(e.key) { + case 'Escape': + this.handleClose(); + break; + } + } + + handleMouseDown = () => { + if (!this.state.open) { + this.activeElement = document.activeElement; + } + } + + handleButtonKeyDown = (e) => { + switch(e.key) { + case ' ': + case 'Enter': + this.handleMouseDown(); + break; + } + } + + handleClose = () => { + if (this.state.open && this.activeElement) { + this.activeElement.focus({ preventScroll: true }); + } + this.setState({ open: false }); + } + + handleChange = value => { + this.props.onChange(value); + } + + componentWillMount () { + const { intl: { formatMessage } } = this.props; + + this.options = [ + { icon: 'file-text', value: 'text/plain', text: formatMessage(messages.plain), meta: null }, + { icon: 'arrow-circle-down', value: 'text/markdown', text: formatMessage(messages.markdown), meta: null }, + ]; + } + + render () { + const { value, intl } = this.props; + const { open, placement } = this.state; + + const valueOption = this.options.find(item => item.value === value); + + return ( + <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}> + <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === (placement === 'bottom' ? 0 : (this.options.length - 1)) })}> + <IconButton + className='privacy-dropdown__value-icon' + icon={valueOption.icon} + title={intl.formatMessage(messages.change_content_type)} + size={18} + expanded={open} + active={open} + inverted + onClick={this.handleToggle} + onMouseDown={this.handleMouseDown} + onKeyDown={this.handleButtonKeyDown} + style={{ height: null, lineHeight: '27px' }} + /> + </div> + + <Overlay show={open} placement={placement} target={this}> + <ContentTypeDropdownMenu + items={this.options} + value={value} + onClose={this.handleClose} + onChange={this.handleChange} + placement={placement} + /> + </Overlay> + </div> + ); + } + +} diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index d1af2a6072..39b307f2ed 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -18,6 +18,7 @@ const mapStateToProps = state => ({ spoilerText: state.getIn(['compose', 'spoiler_text']), privacy: state.getIn(['compose', 'privacy']), federation: state.getIn(['compose', 'federation']), + contentType: state.getIn(['compose', 'content_type']), focusDate: state.getIn(['compose', 'focusDate']), caretPosition: state.getIn(['compose', 'caretPosition']), preselectDate: state.getIn(['compose', 'preselectDate']), diff --git a/app/javascript/mastodon/features/compose/containers/content_type_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/content_type_dropdown_container.js new file mode 100644 index 0000000000..18107bce0c --- /dev/null +++ b/app/javascript/mastodon/features/compose/containers/content_type_dropdown_container.js @@ -0,0 +1,24 @@ +import { connect } from 'react-redux'; +import ContentTypeDropdown from '../components/content_type_dropdown'; +import { changeComposeContentType } from '../../../actions/compose'; +import { openModal, closeModal } from '../../../actions/modal'; +import { isUserTouching } from '../../../is_mobile'; + +const mapStateToProps = state => ({ + isModalOpen: state.get('modal').modalType === 'ACTIONS', + value: state.getIn(['compose', 'content_type']), +}); + +const mapDispatchToProps = dispatch => ({ + + onChange (value) { + dispatch(changeComposeContentType(value)); + }, + + isUserTouching, + onModalOpen: props => dispatch(openModal('ACTIONS', props)), + onModalClose: () => dispatch(closeModal()), + +}); + +export default connect(mapStateToProps, mapDispatchToProps)(ContentTypeDropdown); diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 876c6962c5..8af877910e 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "الرد ÙÙŠ الØÙŠÙ† Ø³ÙˆÙ ÙŠÙØ¹ÙŠØ¯ كتابة الرسالة التي أنت بصدد كتابتها. متأكد من أنك تريد المواصلة؟", "confirmations.unfollow.confirm": "إلغاء المتابعة", "confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ØŸ", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Ø§ØØ°Ù Ø§Ù„Ù…ØØ§Ø¯Ø«Ø©", "conversation.mark_as_read": "اعتبرها كمقروءة", "conversation.open": "اعرض Ø§Ù„Ù…ØØ§Ø¯Ø«Ø©", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index 675fbbf8e5..b1c13a686b 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder agora va sobrescribir el mensaxe que tas componiendo anguaño. ¿De xuru que quies siguir?", "confirmations.unfollow.confirm": "Dexar de siguir", "confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 9008de9ed8..69fdba157c 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index 7de1a10221..6bea3fee2e 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "à¦à¦–ন মতামত লিখতে গেলে আপনার à¦à¦–ন যেটা লিখছেন সেটা মà§à¦›à§‡ যাবে। আপনি নি নিশà§à¦šà¦¿à¦¤ à¦à¦Ÿà¦¾ করতে চান ?", "confirmations.unfollow.confirm": "অনà§à¦¸à¦°à¦£ করা বাতিল করতে", "confirmations.unfollow.message": "আপনি কি নিশà§à¦šà¦¿à¦¤ {name} কে আর অনà§à¦¸à¦°à¦£ করতে চান না ?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "কথোপকথন মà§à¦›à§‡ ফেলà§à¦¨", "conversation.mark_as_read": "পঠিত হিসেবে চিহà§à¦¨à¦¿à¦¤ করà§à¦¨", "conversation.open": "কথপোকথন দেখান", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 72a6d0a0a0..e88a451c0e 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Respont bremañ a zilamo ar gemennadenn emaoc'h o skrivañ. Sur e oc'h e fell deoc'h kenderc'hel ganti?", "confirmations.unfollow.confirm": "Diheuliañ", "confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Dilemel ar gaozeadenn", "conversation.mark_as_read": "Merkañ evel lennet", "conversation.open": "Gwelout ar gaozeadenn", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 2273407ac8..5c2b6b6555 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responen ara es sobreescriurà el missatge que està s editant. Està s segur que vols continuar?", "confirmations.unfollow.confirm": "Deixa de seguir", "confirmations.unfollow.message": "Està s segur que vols deixar de seguir {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Elimina la conversa", "conversation.mark_as_read": "Marca com a llegida", "conversation.open": "Veure conversa", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 34341ee832..cd990718b7 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Risponde avà sguasserà u missaghju chì scrivite. Site sicuru·a chì vulete cuntinuà ?", "confirmations.unfollow.confirm": "Disabbunassi", "confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Sguassà a cunversazione", "conversation.mark_as_read": "Marcà cum'è lettu", "conversation.open": "Vede a cunversazione", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index cd5cd96805..a1ecc950ac 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "OdpovÄ›Ä pÅ™epÃÅ¡e vaÅ¡i rozepsanou zprávu. Opravdu chcete pokraÄovat?", "confirmations.unfollow.confirm": "PÅ™estat sledovat", "confirmations.unfollow.message": "Opravdu chcete uživatele {name} pÅ™estat sledovat?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Smazat konverzaci", "conversation.mark_as_read": "OznaÄit jako pÅ™eÄtenou", "conversation.open": "Zobrazit konverzaci", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index ecd49c577a..8ab0fd0e72 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Bydd ateb nawr yn cymryd lle y neges yr ydych yn cyfansoddi ar hyn o bryd. Ydych chi'n sicr yr ydych am barhau?", "confirmations.unfollow.confirm": "Dad-ddilynwch", "confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Dileu sgwrs", "conversation.mark_as_read": "Nodi fel wedi'i ddarllen", "conversation.open": "Gweld sgwrs", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index fd6ec26f4d..58bbef812b 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Hvis du svarer nu vil du overskrive den besked du er ved at skrive. Er du sikker pÃ¥, du vil fortsætte?", "confirmations.unfollow.confirm": "Følg ikke længere", "confirmations.unfollow.message": "Er du sikker pÃ¥, du ikke længere vil følge {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Slet samtale", "conversation.mark_as_read": "Marker som læst", "conversation.open": "Vis samtale", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 1a18bafc3c..939aabf365 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Wenn du jetzt antwortest wird es die gesamte Nachricht verwerfen, die du gerade schreibst. Möchtest du wirklich fortfahren?", "confirmations.unfollow.confirm": "Entfolgen", "confirmations.unfollow.message": "Bist du dir sicher, dass du {name} entfolgen möchtest?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Unterhaltung löschen", "conversation.mark_as_read": "Als gelesen markieren", "conversation.open": "Unterhaltung anzeigen", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index bf08094378..77d61f36ad 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -1072,6 +1072,23 @@ ], "path": "app/javascript/mastodon/features/compose/components/compose_form.json" }, + { + "descriptors": [ + { + "defaultMessage": "Plain Text", + "id": "content_type.plain.short" + }, + { + "defaultMessage": "Markdown", + "id": "content_type.markdown.short" + }, + { + "defaultMessage": "Adjust status content type", + "id": "content_type.change" + } + ], + "path": "app/javascript/mastodon/features/compose/components/content_type_dropdown.json" + }, { "descriptors": [ { diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 35adb204ed..e8b4374c72 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Απαντώντας τώÏα θα αντικαταστήσεις το κείμενο που ήδη γÏάφεις. ΣίγουÏα θÎλεις να συνεχίσεις;", "confirmations.unfollow.confirm": "Διακοπή παÏακολοÏθησης", "confirmations.unfollow.message": "ΣίγουÏα θες να πάψεις να ακολουθείς τον/την {name};", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "ΔιαγÏαφή συζήτησης", "conversation.mark_as_read": "Σήμανση ως αναγνωσμÎνο", "conversation.open": "Î Ïοβολή συνομιλίας", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 49c4d99d2f..62c7d9d782 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -157,6 +157,9 @@ "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", "confirmations.unsubscribe.confirm": "Unsubscribe", "confirmations.unsubscribe.message": "Are you sure you want to unsubscribe {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index d6d6aa1b6d..44dbee9997 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Respondi nun anstataÅigos la mesaÄon, kiun vi nun skribas. Ĉu vi certas, ke vi volas daÅrigi?", "confirmations.unfollow.confirm": "Ne plu sekvi", "confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Forigi konversacion", "conversation.mark_as_read": "Marki legita", "conversation.open": "Vidi konversacion", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index fda3864554..0e498054c1 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder ahora sobreescribirá el mensaje que estás redactando actualmente. ¿Estás seguro que querés seguir?", "confirmations.unfollow.confirm": "Dejar de seguir", "confirmations.unfollow.message": "¿Estás seguro que querés dejar de seguir a {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Eliminar conversación", "conversation.mark_as_read": "Marcar como leÃdo", "conversation.open": "Ver conversación", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 88ec1f574a..70a41dbfd4 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder sobrescribirá el mensaje que estás escribiendo. ¿Estás seguro de que deseas continuar?", "confirmations.unfollow.confirm": "Dejar de seguir", "confirmations.unfollow.message": "¿Estás seguro de que quieres dejar de seguir a {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Borrar conversación", "conversation.mark_as_read": "Marcar como leÃdo", "conversation.open": "Ver conversación", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 558fe38de2..cebf52cad8 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Praegu vastamine kirjutab üle sõnumi, mida hetkel koostate. Olete kindel, et soovite jätkata?", "confirmations.unfollow.confirm": "Ära jälgi", "confirmations.unfollow.message": "Olete kindel, et ei soovi rohkem jälgida kasutajat {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Kustuta vestlus", "conversation.mark_as_read": "Märgi loetuks", "conversation.open": "Vaata vestlust", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 3d5ac92f8a..40c2914c9e 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Orain erantzuteak idazten ari zaren mezua gainidatziko du. Ziur jarraitu nahi duzula?", "confirmations.unfollow.confirm": "Utzi jarraitzeari", "confirmations.unfollow.message": "Ziur {name} jarraitzeari utzi nahi diozula?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Ezabatu elkarrizketa", "conversation.mark_as_read": "Markatu irakurrita bezala", "conversation.open": "Ikusi elkarrizketa", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 6685b2ccb1..6a07accd4a 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "اگر الان پاسخ دهید، چیزی Ú©Ù‡ در ØØ§Ù„ نوشتنش بودید پاک خواهد شد. می‌خواهید ادامه دهید؟", "confirmations.unfollow.confirm": "پایان پیگیری", "confirmations.unfollow.message": "مطمئنید Ú©Ù‡ می‌خواهید به پیگیری از {name} پایان دهید؟", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "ØØ°Ù Ú¯ÙØªÚ¯Ùˆ", "conversation.mark_as_read": "علامت‌گذاری به عنوان خوانده شده", "conversation.open": "دیدن Ú¯ÙØªÚ¯Ùˆ", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 0f150769b3..8f3154bec7 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Jos vastaat nyt, vastaus korvaa tällä hetkellä työstämäsi viestin. Oletko varma, että haluat jatkaa?", "confirmations.unfollow.confirm": "Lakkaa seuraamasta", "confirmations.unfollow.message": "Haluatko varmasti lakata seuraamasta käyttäjää {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Poista keskustelu", "conversation.mark_as_read": "Merkitse luetuksi", "conversation.open": "Näytä keskustelu", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 0c12719e25..a1fbd83d0c 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Répondre maintenant écrasera le message que vous rédigez actuellement. Voulez-vous vraiment continuer ?", "confirmations.unfollow.confirm": "Ne plus suivre", "confirmations.unfollow.message": "Voulez-vous vraiment arrêter de suivre {name} ?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Supprimer la conversation", "conversation.mark_as_read": "Marquer comme lu", "conversation.open": "Afficher la conversation", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 2b1546a578..23c8715994 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 44d8b4662d..35d5db98b4 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder agora sobrescribirá a mensaxe que estás a compor. Tes a certeza de que queres continuar?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "Desexas deixar de seguir a {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Eliminar conversa", "conversation.mark_as_read": "Marcar como lido", "conversation.open": "Ver conversa", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index d43763d8b7..f3ee5be645 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "להפסיק מעקב", "confirmations.unfollow.message": "להפסיק מעקב ×חרי {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index 88591a5bba..2a0be72ff2 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "अब उतà¥à¤¤à¤° देना उस संदेश को अधिलेखित कर देगा जो आप वरà¥à¤¤à¤®à¤¾à¤¨ में बना रहे हैं। कà¥à¤¯à¤¾ आप सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ रूप से आगे बढ़ना चाहते हैं?", "confirmations.unfollow.confirm": "अनफॉलो करें", "confirmations.unfollow.message": "कà¥à¤¯à¤¾ आप वाकई {name} को अनफॉलो करना चाहते हैं?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "वारà¥à¤¤à¤¾à¤²à¤¾à¤ª हटाà¤à¤", "conversation.mark_as_read": "पà¥à¤¾ गया के रूप में चिहà¥à¤¨à¤¿à¤¤ करें", "conversation.open": "वारà¥à¤¤à¤¾à¤²à¤¾à¤ª देखें", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index b1f80e29d5..8f37fe542b 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 9570f587ad..812d68a4ee 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ha most válaszolsz, ez felülÃrja a most szerkesztés alatt álló üzenetet. Mégis ezt szeretnéd?", "confirmations.unfollow.confirm": "Követés visszavonása", "confirmations.unfollow.message": "Biztos, hogy vissza szeretnéd vonni {name} követését?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Beszélgetés törlése", "conversation.mark_as_read": "Megjelölés olvasottként", "conversation.open": "Beszélgetés megtekintése", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 8c6cb1de2a..0dda905a62 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ô±ÕµÕ½ ÕºÕ¡Õ°Õ«Õ¶ ÕºÕ¡Õ¿Õ¡Õ½ÕÕ¡Õ¶Õ¥Õ¬Õ¨ Õ¯Õ¨ Õ¹Õ¥Õ²Õ¡Ö€Õ¯Õ« Õ±Õ¥Ö€Õ Õ¡ÕµÕ½ ÕºÕ¡Õ°Õ«Õ¶ Õ¡Õ¶Õ¡Ö‚Õ¡Ö€Õ¿ Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨Ö‰ Õ€Õ¡Õ´Õ¸Õ¦Õ¸Ö‚Õ¡ÕžÕ® Õ§Ö„Ö‰", "confirmations.unfollow.confirm": "Ô±ÕºÕ¡Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬", "confirmations.unfollow.message": "ÕŽÕ½Õ¿Õ¡ÕžÕ° Õ¥Õ½, Õ¸Ö€ Õ¸Ö‚Õ¦Õ¸Ö‚Õ´ Õ¥Õ½ Õ¡ÕµÕ¬Õ¥Ö‚Õ½ Õ¹Õ°Õ¥Õ¿Õ¥Ö‚Õ¥Õ¬ {name}ÖŠÕ«Õ¶Ö‰", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Õ‹Õ¶Õ»Õ¥Õ¬ ÕÖ…Õ½Õ¡Õ¯ÖÕ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨", "conversation.mark_as_read": "Õ†Õ·Õ¥Õ¬ Õ¸Ö€ÕºÕ§Õ½ Õ¨Õ¶Õ©Õ¥Ö€ÖÕ¸Ö‚Õ¡Õ®", "conversation.open": "Ô´Õ«Õ¿Õ¥Õ¬ ÕÖ…Õ½Õ¡Õ¯ÖÕ¸Ö‚Õ©Õ«Ö‚Õ¶Õ¨", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 0b97bf1b2e..67b0decf84 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?", "confirmations.unfollow.confirm": "Berhenti mengikuti", "confirmations.unfollow.message": "Apakah anda ingin berhenti mengikuti {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Hapus percakapan", "conversation.mark_as_read": "Tandai sudah dibaca", "conversation.open": "Lihat percakapan", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index 30d20a7e97..6e649e30dd 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 72d8fefaf6..fdad2d3363 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ef þú svarar núna verður skrifað yfir skilaboðin sem þú ert að semja núna. Ertu viss um að þú viljir halda áfram?", "confirmations.unfollow.confirm": "Hætta að fylgja", "confirmations.unfollow.message": "Ertu viss um að þú viljir hætta að fylgjast með {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Eyða samtali", "conversation.mark_as_read": "Merkja sem lesið", "conversation.open": "Skoða samtal", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 5be797a60c..c0bca57b64 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Rispondere ora sovrascriverà il messaggio che stai correntemente componendo. Sei sicuro di voler procedere?", "confirmations.unfollow.confirm": "Smetti di seguire", "confirmations.unfollow.message": "Sei sicuro di non voler più seguire {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Elimina conversazione", "conversation.mark_as_read": "Segna come letto", "conversation.open": "Visualizza conversazione", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 7c0d164a50..a98d9f33f0 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -155,6 +155,9 @@ "confirmations.unfollow.message": "本当ã«{name}ã•ã‚“ã®ãƒ•ã‚©ãƒãƒ¼ã‚’解除ã—ã¾ã™ã‹ï¼Ÿ", "confirmations.unsubscribe.confirm": "è³¼èªè§£é™¤", "confirmations.unsubscribe.message": "本当ã«{name}ã•ã‚“ã®è³¼èªã‚’解除ã—ã¾ã™ã‹ï¼Ÿ", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "会話を削除", "conversation.mark_as_read": "æ—¢èªã«ã™ã‚‹", "conversation.open": "会話を表示", diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json index 140f2d0042..565d3be40d 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "ნუღáƒáƒ მიჰყვები", "confirmations.unfollow.message": "დáƒáƒ წმუნებული ხáƒáƒ თ, áƒáƒ¦áƒáƒ გსურთ მიჰყვებáƒáƒ“ეთ {name}-ს?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index fde0375045..33c73197ac 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Tiririt akka tura ad k-degger izen-agi i tettaruá¸. TebÉ£iḠad tkemmleá¸?", "confirmations.unfollow.confirm": "Ur á¸á¸afaá¹› ara", "confirmations.unfollow.message": "TetḥeqqeḠbelli tebÉ£iḠur teá¹afaá¹›eḠara {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "SfeḠadiwenni", "conversation.mark_as_read": "CreḠyettwaɣṛa", "conversation.open": "Ssken adiwenni", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 5e08d43a11..d3f7cc048d 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Жауабыңыз жазып жатқан жазбаңыздың Ò¯Ñтіне кетеді. ЖалғаÑтырамыз ба?", "confirmations.unfollow.confirm": "Оқымау", "confirmations.unfollow.message": "\"{name} атты қолданушыға енді жазылғыңыз келмей ме?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "ПікірталаÑты өшіру", "conversation.mark_as_read": "Оқылды деп белгіле", "conversation.open": "ПікірталаÑты қарау", diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json index 8a0014e916..b08da6d7e5 100644 --- a/app/javascript/mastodon/locales/kn.json +++ b/app/javascript/mastodon/locales/kn.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 07b570777c..058adb89c4 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "ë‹µê¸€ì„ ë‹¬ê¸° 위해 현재 작성 ì¤‘ì¸ ë©”ì‹œì§€ê°€ ë®ì–´ 씌워집니다. ì§„í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", "confirmations.unfollow.confirm": "언팔로우", "confirmations.unfollow.message": "ì •ë§ë¡œ {name}를 ì–¸íŒ”ë¡œìš°í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "대화 ì‚ì œ", "conversation.mark_as_read": "ì½ì€ ìƒíƒœë¡œ 표시", "conversation.open": "대화 보기", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index b3822ff084..ef549d4f9f 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 22fabd580e..39ebf8cbee 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 59af93c98d..78999665f8 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Atbildot tagad tava ziņa ko Å¡obrÄ«d raksti tiks pÄrrakstÄ«ta. Vai tieÅ¡Äm vÄ“lies turpinÄt?", "confirmations.unfollow.confirm": "Nesekot", "confirmations.unfollow.message": "Vai tieÅ¡am vairs nevÄ“lies sekot lietotÄjam {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json index aeaf7355c7..d44328d4e9 100644 --- a/app/javascript/mastodon/locales/mk.json +++ b/app/javascript/mastodon/locales/mk.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "ОдÑледи", "confirmations.unfollow.message": "Сигурни Ñте дека ќе го отÑледите {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Избриши разговор", "conversation.mark_as_read": "Означете како прочитано", "conversation.open": "Прегледај разговор", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 0c5a842042..c95d83de7c 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "ഇപàµà´ªàµ‹àµ¾ മറàµà´ªà´Ÿà´¿ കൊടàµà´•àµà´•àµà´¨àµà´¨à´¤àµ നിങàµà´™àµ¾ à´Žà´´àµà´¤à´¿à´•àµà´•ൊണàµà´Ÿà´¿à´°à´¿à´•àµà´•àµà´¨àµà´¨ സനàµà´¦àµ‡à´¶à´¤àµà´¤à´¿à´¨àµ à´®àµà´•ളിൽ à´Žà´´àµà´¤à´¾àµ» കാരണമാകàµà´‚. തീർചàµà´šà´¯à´¾à´¯àµà´‚ à´®àµàµ»à´ªàµ‹à´Ÿàµà´Ÿàµ പോകാൻ തീരàµà´®à´¾à´¨à´¿à´šàµà´šàµà´µàµ‹?", "confirmations.unfollow.confirm": "പിനàµà´¤àµà´Ÿà´°àµà´¨àµà´¨à´¤àµ നിരàµâ€à´¤àµà´¤àµà´•", "confirmations.unfollow.message": "നിങàµà´™àµ¾ {name} യെ പിനàµà´¤àµà´Ÿà´°àµà´¨àµà´¨à´¤àµ നിർതàµà´¤àµà´µà´¾àµ» തീർചàµà´šà´¯à´¾à´¯àµà´‚ തീരàµà´®à´¾à´¨à´¿à´šàµà´šàµà´µàµ‹?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "സംà´à´¾à´·à´£à´‚ മായികàµà´•àµà´•", "conversation.mark_as_read": "വായിചàµà´šà´¤à´¾à´¯à´¿ അടയാളപàµà´ªàµ†à´Ÿàµà´¤àµà´¤àµà´•", "conversation.open": "സംà´à´¾à´·à´£à´‚ കാണàµà´•", diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json index e07baddffb..1157575e05 100644 --- a/app/javascript/mastodon/locales/mr.json +++ b/app/javascript/mastodon/locales/mr.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 5144411bb7..03c5c6b30c 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 9825fb3a04..13d9653481 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Door nu te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?", "confirmations.unfollow.confirm": "Ontvolgen", "confirmations.unfollow.message": "Weet je het zeker dat je {name} wilt ontvolgen?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Gesprek verwijderen", "conversation.mark_as_read": "Als gelezen markeren", "conversation.open": "Gesprek tonen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index b567a35330..e28164ccc1 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ã… svara no vil overskriva meldinga du skriv no. Er du sikker pÃ¥ at du vil halda fram?", "confirmations.unfollow.confirm": "Slutt Ã¥ fylgja", "confirmations.unfollow.message": "Er du sikker pÃ¥ at du vil slutta Ã¥ fylgja {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Slett samtale", "conversation.mark_as_read": "Merk som lese", "conversation.open": "SjÃ¥ samtale", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index af911c2be9..b17d81ef6e 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ã… svare nÃ¥ vil overskrive meldingen du skriver for øyeblikket. Er du sikker pÃ¥ at du vil fortsette?", "confirmations.unfollow.confirm": "Slutt Ã¥ følge", "confirmations.unfollow.message": "Er du sikker pÃ¥ at du vil slutte Ã¥ følge {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Slett samtalen", "conversation.mark_as_read": "Marker som lest", "conversation.open": "Vis samtale", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 6e7518d572..1843074286 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Respondre remplaçarà lo messatge que sètz a escriure. Volètz vertadièrament contunhar ?", "confirmations.unfollow.confirm": "Quitar de sègre", "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Suprimir la conversacion", "conversation.mark_as_read": "Marcar coma legida", "conversation.open": "Veire la conversacion", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index a43d7fc850..72fa7f7fdc 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "W ten sposób utracisz wpis który obecnie tworzysz. Czy na pewno chcesz to zrobić?", "confirmations.unfollow.confirm": "PrzestaÅ„ Å›ledzić", "confirmations.unfollow.message": "Czy na pewno zamierzasz przestać Å›ledzić {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "UsuÅ„ rozmowÄ™", "conversation.mark_as_read": "Oznacz jako przeczytane", "conversation.open": "Zobacz rozmowÄ™", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 016d98b933..44f36ca4a3 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder agora sobrescreverá o toot que você está compondo. Deseja continuar?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "Você tem certeza de que deseja deixar de seguir {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Excluir conversa", "conversation.mark_as_read": "Marcar como lida", "conversation.open": "Ver conversa", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index becce22e04..821548dc24 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Responder agora irá reescrever a mensagem que está a compor actualmente. Tem a certeza que quer continuar?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "De certeza que queres deixar de seguir {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Eliminar conversa", "conversation.mark_as_read": "Marcar como lida", "conversation.open": "Ver conversa", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index 5470db028d..3fe44cb660 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Răspunzând la asta acum, mesajul pe care îl compui în prezent se va È™terge. EÈ™ti sigur că vrei să continui?", "confirmations.unfollow.confirm": "Nu mai urmări", "confirmations.unfollow.message": "EÈ™ti sigur că nu mai vrei să urmăreÈ™ti pe {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "ȘtergeÈ›i conversaÈ›ia", "conversation.mark_as_read": "MarcaÈ›i ca citit", "conversation.open": "VizualizaÈ›i conversaÈ›ia", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index eb181e78e3..467b2f4843 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "При ответе, текÑÑ‚ набираемого поÑта будет очищен. Продолжить?", "confirmations.unfollow.confirm": "ОтпиÑатьÑÑ", "confirmations.unfollow.message": "Ð’Ñ‹ уверены, что хотите отпиÑатьÑÑ Ð¾Ñ‚ {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Удалить беÑеду", "conversation.mark_as_read": "Пометить прочитанным", "conversation.open": "ПроÑмотр беÑеды", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 30a3e33745..0b4d6cfe31 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Rispondende immoe as a subraiscrìere su messà giu chi ses iscriende. Seguru chi boles sighire?", "confirmations.unfollow.confirm": "Non sigas prus", "confirmations.unfollow.message": "Seguru chi non boles sighire prus {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Cantzella arresonada", "conversation.mark_as_read": "Signala comente lèghidu", "conversation.open": "Bide arresonada", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index e2fd8477e2..c69433f41b 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "OdpovedanÃm akurát teraz prepÃÅ¡eÅ¡ správu, ktorú máš práve rozpÃsanú. Si si istý/á, že chceÅ¡ pokraÄovaÅ¥?", "confirmations.unfollow.confirm": "Nesleduj", "confirmations.unfollow.message": "Naozaj chceÅ¡ prestaÅ¥ sledovaÅ¥ {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Vymaž konverzáciu", "conversation.mark_as_read": "OznaÄ za preÄÃtané", "conversation.open": "Ukáž konverzáciu", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 726a2a33a2..70f81004e5 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Odgovarjanje bo prepisalo sporoÄilo, ki ga trenutno sestavljate. Ali ste prepriÄani, da želite nadaljevati?", "confirmations.unfollow.confirm": "Prenehaj slediti", "confirmations.unfollow.message": "Ali ste prepriÄani, da ne želite veÄ slediti {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 6f8acbc21f..c1f6f1265c 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Po të përgjigjeni tani, mesazhi që po hartoni, do të mbishkruhet. Jeni i sigurt se doni të vazhdohet më tej?", "confirmations.unfollow.confirm": "Resht së ndjekuri", "confirmations.unfollow.message": "Jeni i sigurt se doni të mos ndiqet më {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Fshije bisedën", "conversation.mark_as_read": "Vëri shenjë si të lexuar", "conversation.open": "Shfaq bisedën", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index a0f1dff9ca..3742981482 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Otprati", "confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index c3aef8080e..01abd87365 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Одговарањем ћете обриÑати поруку коју ÑаÑтављате. ЈеÑте ли Ñигурни да желите да наÑтавите?", "confirmations.unfollow.confirm": "Отпрати", "confirmations.unfollow.message": "Да ли Ñте Ñигурни да желите да отпратите кориÑника {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Обриши препиÑку", "conversation.mark_as_read": "Означи као прочитано", "conversation.open": "Прикажи препиÑку", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 1515443adf..b35b9a9823 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Om du svarar nu kommer det att ersätta meddelandet du hÃ¥ller pÃ¥ att skapa. Är du säker pÃ¥ att du vill fortsätta?", "confirmations.unfollow.confirm": "Avfölj", "confirmations.unfollow.message": "Är du säker pÃ¥ att du vill avfölja {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Radera konversation", "conversation.mark_as_read": "Markera som läst", "conversation.open": "Se konversation", diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json index b3822ff084..ef549d4f9f 100644 --- a/app/javascript/mastodon/locales/szl.json +++ b/app/javascript/mastodon/locales/szl.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index ca8e1bb2c0..49571f4582 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "à®à®±à¯à®•னவே ஒர௠பதிவ௠எழà¯à®¤à®ªà¯à®ªà®Ÿà¯à®Ÿà¯à®•à¯à®•ொணà¯à®Ÿà®¿à®°à¯à®•à¯à®•ிறதà¯. இபà¯à®ªà¯Šà®´à¯à®¤à¯ பதில௠எழà¯à®¤ à®®à¯à®©à¯ˆà®¨à¯à®¤à®¾à®²à¯ அத௠அழிகà¯à®•பà¯à®ªà®Ÿà¯à®®à¯. பரவாயிலà¯à®²à¯ˆà®¯à®¾?", "confirmations.unfollow.confirm": "விலகà¯", "confirmations.unfollow.message": "{name}-à®à®ªà¯ பினà¯à®¤à¯Šà®Ÿà®°à¯à®µà®¤à¯ˆ நிசà¯à®šà®¯à®®à®¾à®• நீஙà¯à®•ள௠நிறà¯à®¤à¯à®¤ விரà¯à®®à¯à®ªà¯à®•ிறீரà¯à®•ளா?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "உரையாடலை அழி", "conversation.mark_as_read": "படிகà¯à®•படà¯à®Ÿà®¤à®¾à®•க௠கà¯à®±à®¿", "conversation.open": "உரையாடலைக௠காடà¯à®Ÿà¯", diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json index b3822ff084..ef549d4f9f 100644 --- a/app/javascript/mastodon/locales/tai.json +++ b/app/javascript/mastodon/locales/tai.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index fce6f32f24..5a17119611 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "ఇపà±à°ªà±à°¡à±‡ à°ªà±à°°à°¤à±à°¯à±à°¤à±à°¤à°°à°‚ ఇసà±à°¤à±‡ మీరౠపà±à°°à°¸à±à°¤à±à°¤à°‚ à°µà±à°°à°¾à°¸à±à°¤à±à°¨à±à°¨ సందేశం తిరగరాయబడà±à°¤à±à°‚ది. మీరౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ కొనసాగించాలనà±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?", "confirmations.unfollow.confirm": "à°…à°¨à±à°¸à°°à°¿à°‚చవదà±à°¦à±", "confirmations.unfollow.message": "{name}నౠమీరౠఖచà±à°šà°¿à°¤à°‚à°—à°¾ à°…à°¨à±à°¸à°°à°¿à°‚చవదà±à°¦à°¨à±à°•à±à°‚à°Ÿà±à°¨à±à°¨à°¾à°°à°¾?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index b29a9eccda..182b91a94c 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "à¸à¸²à¸£à¸•à¸à¸šà¸à¸¥à¸±à¸šà¸•à¸à¸™à¸™à¸µà¹‰à¸ˆà¸°à¹€à¸‚ียนทับข้à¸à¸„วามที่คุณà¸à¸³à¸¥à¸±à¸‡à¹€à¸‚ียน คุณà¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸à¹„ม่ว่าต้à¸à¸‡à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸•่à¸?", "confirmations.unfollow.confirm": "เลิà¸à¸•ิดตาม", "confirmations.unfollow.message": "คุณà¹à¸™à¹ˆà¹ƒà¸ˆà¸«à¸£à¸·à¸à¹„ม่ว่าต้à¸à¸‡à¸à¸²à¸£à¹€à¸¥à¸´à¸à¸•ิดตาม {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "ลบà¸à¸²à¸£à¸ªà¸™à¸—นา", "conversation.mark_as_read": "ทำเครื่à¸à¸‡à¸«à¸¡à¸²à¸¢à¸§à¹ˆà¸²à¸à¹ˆà¸²à¸™à¹à¸¥à¹‰à¸§", "conversation.open": "ดูà¸à¸²à¸£à¸ªà¸™à¸—นา", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 5c7d4b382a..205d383800 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Åžimdi yanıtlarken o an oluÅŸturduÄŸunuz mesajın üzerine yazılır. Devam etmek istediÄŸinize emin misiniz?", "confirmations.unfollow.confirm": "Takibi kaldır", "confirmations.unfollow.message": "{name}'yi takipten çıkarmak istediÄŸinizden emin misiniz?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "KonuÅŸmayı sil", "conversation.mark_as_read": "OkunmuÅŸ olarak iÅŸaretle", "conversation.open": "KonuÅŸmayı görüntüle", diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json index b3822ff084..ef549d4f9f 100644 --- a/app/javascript/mastodon/locales/ug.json +++ b/app/javascript/mastodon/locales/ug.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 244f04a9e8..e19d906bab 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Поточна відповідь перезапише повідомленнÑ, Ñке ви зараз пишете. Ви впевнені, що хочете продовжити?", "confirmations.unfollow.confirm": "ВідпиÑатиÑÑ", "confirmations.unfollow.message": "Ви впевнені, що хочете відпиÑатиÑÑ Ð²Ñ–Ð´ {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Видалити цю беÑіду", "conversation.mark_as_read": "Позначити Ñк прочитане", "conversation.open": "ПереглÑнути беÑіду", diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index ada675496a..2b5547dfc8 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Delete conversation", "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index aa0c0d5ffb..83c8ed9c85 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "Ná»™i dung bạn Ä‘ang soạn thảo sẽ bị ghi đè, bạn có tiếp tục?", "confirmations.unfollow.confirm": "Ngưng theo dõi", "confirmations.unfollow.message": "Bạn có chắc chắn muốn ngưng theo dõi {name}?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "Xóa tin nhắn nà y", "conversation.mark_as_read": "Äánh dấu là đã Ä‘á»c", "conversation.open": "Xem toà n bá»™ tin nhắn", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 778c8c04e5..b3d8fbfe18 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "å›žå¤æ¤æ¶ˆæ¯å°†ä¼šè¦†ç›–当剿£åœ¨ç¼–辑的信æ¯ã€‚确定继ç»å—?", "confirmations.unfollow.confirm": "å–æ¶ˆå…³æ³¨", "confirmations.unfollow.message": "ä½ ç¡®å®šè¦å–消关注 {name} å—?", + "content_type.change": "设置富文本类型", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "纯文本", "conversation.delete": "åˆ é™¤å¯¹è¯", "conversation.mark_as_read": "æ ‡è®°ä¸ºå·²è¯»", "conversation.open": "查看对è¯", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index a332db0114..b65e6d9748 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "ç¾åœ¨å›žè¦†å°‡è“‹æŽ‰æ‚¨ç›®å‰æ£åœ¨æ’°å¯«çš„訊æ¯ã€‚是å¦ä»è¦å›žè¦†ï¼Ÿ", "confirmations.unfollow.confirm": "å–æ¶ˆé—œæ³¨", "confirmations.unfollow.message": "真的ä¸è¦ç¹¼çºŒé—œæ³¨ {name} 了嗎?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "刪除å°è©±", "conversation.mark_as_read": "標為已讀", "conversation.open": "檢視å°è©±", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index da4cc777da..7bde874a52 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -123,6 +123,9 @@ "confirmations.reply.message": "ç¾åœ¨å›žè¦†å°‡è“‹æŽ‰æ‚¨ç›®å‰æ£åœ¨æ’°å¯«çš„訊æ¯ã€‚是å¦ä»è¦å›žè¦†ï¼Ÿ", "confirmations.unfollow.confirm": "å–æ¶ˆé—œæ³¨", "confirmations.unfollow.message": "真的è¦å–消關注 {name} 嗎?", + "content_type.change": "Adjust status content type", + "content_type.markdown.short": "Markdown", + "content_type.plain.short": "Plain Text", "conversation.delete": "刪除å°è©±", "conversation.mark_as_read": "標為已讀", "conversation.open": "檢視å°è©±", diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index ff3d38c3f0..d7985d241d 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -31,6 +31,7 @@ import { COMPOSE_VISIBILITY_CHANGE, COMPOSE_CIRCLE_CHANGE, COMPOSE_FEDERATION_CHANGE, + COMPOSE_CONTENT_TYPE_CHANGE, COMPOSE_COMPOSING_CHANGE, COMPOSE_EMOJI_INSERT, COMPOSE_UPLOAD_CHANGE_REQUEST, @@ -60,6 +61,7 @@ const initialState = ImmutableMap({ privacy: null, circle_id: null, federation: null, + content_type: null, text: '', focusDate: null, caretPosition: null, @@ -82,6 +84,7 @@ const initialState = ImmutableMap({ suggestions: ImmutableList(), default_privacy: 'public', default_federation: true, + default_content_type: 'text/plain', default_sensitive: false, resetFileKey: Math.floor((Math.random() * 0x10000)), idempotencyKey: null, @@ -131,6 +134,7 @@ const clearAll = state => { map.set('privacy', state.get('default_privacy')); map.set('circle_id', null); map.set('federation', state.get('default_federation')); + map.set('content_type', state.get('default_content_type')); map.set('sensitive', false); map.update('media_attachments', list => list.clear()); map.set('poll', null); @@ -322,6 +326,10 @@ export default function compose(state = initialState, action) { return state .set('federation', action.value) .set('idempotencyKey', uuid()); + case COMPOSE_CONTENT_TYPE_CHANGE: + return state + .set('content_type', action.value) + .set('idempotencyKey', uuid()); case COMPOSE_VISIBILITY_CHANGE: return state.withMutations(map => { map.set('text', statusToTextMentions(state.get('text'), action.value, state.get('reply_status'))); @@ -351,6 +359,7 @@ export default function compose(state = initialState, action) { map.set('privacy', privacy); map.set('circle_id', null); map.set('federation', !action.status.get('local_only')); + map.set('content_type', action.status.get('content_type')); // TODO MDpref map.set('focusDate', new Date()); map.set('caretPosition', null); map.set('preselectDate', new Date()); @@ -398,6 +407,7 @@ export default function compose(state = initialState, action) { map.set('circle_id', null); map.set('poll', null); map.set('federation', state.get('default_federation')); + map.set('content_type', state.get('default_content_type')); map.set('idempotencyKey', uuid()); }); case COMPOSE_SUBMIT_REQUEST: @@ -490,6 +500,7 @@ export default function compose(state = initialState, action) { map.set('privacy', action.status.get('visibility')); map.set('circle_id', action.status.get('circle_id')); map.set('federation', !action.status.get('local_only')); + map.set('content_type', action.status.get('content_type')); map.set('media_attachments', action.status.get('media_attachments')); map.set('focusDate', new Date()); map.set('caretPosition', null); diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index d115f0ed66..71ad904cf6 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -31,18 +31,40 @@ class Formatter return html.html_safe # rubocop:disable Rails/OutputSafety end - linkable_accounts = status.active_mentions.map(&:account) - linkable_accounts << status.account + formatter_options = { + input: :mastodon, + entity_output: :as_input, + linkable_accounts: status.active_mentions.map(&:account) + [status.account], + custom_emojis: options[:custom_emojify] ? status.emojis : nil, + autoplay: options[:autoplay], + syntax_highlighter: 'rouge', + syntax_highlighter_opts: { + guess_lang: true, + # line_numbers: true, # useless! + # inline_theme: 'base16.light' # do not use this! + } + } + + case status.content_type + when 'text/markdown' + raw_content = "RT @#{prepend_reblog} #{raw_content}" if prepend_reblog + html = Kramdown::Document.new(raw_content, formatter_options).to_mastodon + html = html.delete("\n").html_safe # rubocop:disable Rails/OutputSafety + #when 'text/plain' + else + linkable_accounts = status.active_mentions.map(&:account) + linkable_accounts << status.account - html = raw_content - html = "RT @#{prepend_reblog} #{html}" if prepend_reblog - html = encode_and_link_urls(html, linkable_accounts) - html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify] - html = simple_format(html, {}, sanitize: false) - html = quotify(html, status) if status.quote? && !options[:escape_quotify] - html = html.delete("\n") + html = raw_content + html = "RT @#{prepend_reblog} #{html}" if prepend_reblog + html = encode_and_link_urls(html, linkable_accounts) + html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify] + html = simple_format(html, {}, sanitize: false) + html = quotify(html, status) if status.quote? && !options[:escape_quotify] + html = html.delete("\n") - html.html_safe # rubocop:disable Rails/OutputSafety + html.html_safe # rubocop:disable Rails/OutputSafety + end end def format_in_quote(status, **options) diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 6824b8b0cb..de5c639fec 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -21,6 +21,7 @@ class UserSettingsDecorator user.settings['default_sensitive'] = default_sensitive_preference if change?('setting_default_sensitive') user.settings['default_language'] = default_language_preference if change?('setting_default_language') user.settings['default_federation'] = default_federation_preference if change?('setting_default_federation') + user.settings['default_content_type']= default_content_type_preference if change?('setting_default_content_type') user.settings['unfollow_modal'] = unfollow_modal_preference if change?('setting_unfollow_modal') user.settings['unsubscribe_modal'] = unsubscribe_modal_preference if change?('setting_unsubscribe_modal') user.settings['boost_modal'] = boost_modal_preference if change?('setting_boost_modal') @@ -70,6 +71,10 @@ class UserSettingsDecorator def default_federation_preference boolean_cast_setting 'setting_default_federation' end + + def default_content_type_preference + settings['setting_default_content_type'] + end def unfollow_modal_preference boolean_cast_setting 'setting_unfollow_modal' diff --git a/app/models/status.rb b/app/models/status.rb index f8f3eebf86..2e97f3584e 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -27,6 +27,7 @@ # expires_at :datetime # expires_action :integer default("delete"), not null # local_only :boolean +# content_type :string # class Status < ApplicationRecord @@ -93,6 +94,7 @@ class Status < ApplicationRecord validates :visibility, exclusion: { in: %w(direct limited) }, if: :reblog? validates :quote_visibility, inclusion: { in: %w(public unlisted) }, if: :quote? validates_with ExpiresValidator, on: :create, if: :local? + validates :content_type, inclusion: { in: %w(text/plain text/markdown) }, allow_nil: true accepts_nested_attributes_for :poll @@ -353,6 +355,10 @@ class Status < ApplicationRecord visibilities.keys - %w(direct limited) end + def selectable_content_types + %w(text/plain text/markdown) + end + def favourites_map(status_ids, account_id) Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true } end diff --git a/app/models/user.rb b/app/models/user.rb index 47c23f458e..83a617f3c8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -116,7 +116,7 @@ class User < ApplicationRecord :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network, :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, :advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images, :default_federation, - :disable_swiping, + :disable_swiping, :default_content_type, :show_follow_button_on_timeline, :show_subscribe_button_on_timeline, :show_target, :show_follow_button_on_timeline, :show_subscribe_button_on_timeline, :show_followed_by, :show_target, :follow_button_to_list_adder, :show_navigation_panel, :show_quote_button, :show_bookmark_button, diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 4751a8bd9b..b6390c2323 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -72,6 +72,7 @@ class InitialStateSerializer < ActiveModel::Serializer store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy store[:default_sensitive] = object.current_account.user.setting_default_sensitive store[:default_federation] = object.current_account.user.setting_default_federation + store[:default_content_type] = object.current_account.user.setting_default_content_type end store[:text] = object.text if object.text diff --git a/app/serializers/rest/credential_account_serializer.rb b/app/serializers/rest/credential_account_serializer.rb index fa8f900cc5..c91fe0adbd 100644 --- a/app/serializers/rest/credential_account_serializer.rb +++ b/app/serializers/rest/credential_account_serializer.rb @@ -11,6 +11,7 @@ class REST::CredentialAccountSerializer < REST::AccountSerializer sensitive: user.setting_default_sensitive, language: user.setting_default_language, federation: user.setting_default_federation, + content_type: user.setting_default_content_type, note: object.note, fields: object.fields.map(&:to_h), follow_requests_count: FollowRequest.where(target_account: object).limit(40).count, diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index e4c4991b4a..cc46277b87 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -4,7 +4,7 @@ class REST::StatusSerializer < ActiveModel::Serializer attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitive, :spoiler_text, :visibility, :language, :uri, :url, :replies_count, :reblogs_count, - :favourites_count, :limited, :local_only + :favourites_count, :limited, :local_only, :content_type attribute :favourited, if: :current_user? attribute :reblogged, if: :current_user? diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index d3fc7c3073..4e94f9c15c 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -128,6 +128,11 @@ class PostStatusService < BaseService local_only end + def content_type_option(content_type, content_type_setting) + return content_type_setting if content_type.nil? + content_type + end + def postprocess_status! LinkCrawlWorker.perform_async(@status.id) unless @status.spoiler_text? DistributionWorker.perform_async(@status.id) @@ -205,6 +210,7 @@ class PostStatusService < BaseService expires_at: @expires_at, expires_action: @expires_action, local_only: local_only_option(@options[:local_only], @in_reply_to, @account.user&.setting_default_federation), + content_type: content_type_option(@options[:content_type], @account.user&.setting_default_content_type), }.compact end diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 6b9190b033..91baca1b40 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -25,6 +25,10 @@ .fields-group.fields-row__column.fields-row__column-6 = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false, hint: false + .fields-row + .fields-group.fields-row__column.fields-row__column-6 + = f.input :setting_default_content_type, collection: Status.selectable_content_types, wrapper: :with_label, include_blank: false, label_method: lambda { |content_type| I18n.t("statuses.content_types.#{content_type}") }, required: false, hint: false + .fields-group = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label diff --git a/config/application.rb b/config/application.rb index ad6cf82d70..dbc02d1d7f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,6 +22,8 @@ require_relative '../lib/mastodon/version' require_relative '../lib/devise/two_factor_ldap_authenticatable' require_relative '../lib/devise/two_factor_pam_authenticatable' require_relative '../lib/chewy/strategy/custom_sidekiq' +require_relative '../lib/kramdown/parser/mastodon' +require_relative '../lib/kramdown/converter/mastodon' Dotenv::Railtie.load diff --git a/config/locales/en.yml b/config/locales/en.yml index b480bf33a1..b98283c194 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1271,6 +1271,9 @@ en: one: "%{count} video" other: "%{count} videos" boosted_from_html: Boosted from %{acct_link} + content_types: + text/markdown: Markdown + text/plain: Plain text content_warning: 'Content warning: %{warning}' disallowed_hashtags: one: 'contained a disallowed hashtag: %{tags}' diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 70daf572a0..4bff199bc5 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -163,6 +163,7 @@ en: setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting setting_crop_images: Crop images in non-expanded toots to 16x9 + setting_default_content_type: Default rich content type of toots setting_default_federation: Allow my toots to reach other instances by default setting_default_language: Posting language setting_default_privacy: Posting privacy diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index 6bb1053a8e..5d19076066 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -131,6 +131,7 @@ zh-CN: setting_auto_play_gif: è‡ªåŠ¨æ’æ”¾ GIF 动画 setting_boost_modal: 在转嘟å‰è¯¢é—®æˆ‘ setting_crop_images: 把未展开嘟文ä¸çš„图片è£å‰ªåˆ° 16x9 + setting_default_content_type: é»˜è®¤çš„å˜Ÿæ–‡å¯Œæ–‡æœ¬æ ¼å¼ setting_default_language: å‘布è¯è¨€ setting_default_privacy: 嘟文默认å¯è§èŒƒå›´ setting_default_sensitive: 总是将我å‘é€çš„åª’ä½“æ–‡ä»¶æ ‡è®°ä¸ºæ•æ„Ÿå†…容 diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index a67cd01225..6172adcd27 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1114,6 +1114,9 @@ zh-CN: video: other: "%{count} 段视频" boosted_from_html: 转嘟自 %{acct_link} + content_types: + text/markdown: Markdown + text/plain: 纯文本 content_warning: 内容è¦å‘Šï¼š%{warning} disallowed_hashtags: other: 包å«äº†è¿™äº›ç¦æ¢çš„è¯é¢˜æ ‡ç¾ï¼š%{tags} diff --git a/config/settings.yml b/config/settings.yml index 57e3d84dac..a044caf067 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -18,6 +18,7 @@ defaults: &defaults show_staff_badge: true default_sensitive: false default_federation: true + default_content_type: 'text/plain' hide_network: false unfollow_modal: false unsubscribe_modal: false diff --git a/db/migrate/20200926190114_add_content_type_to_statuses.rb b/db/migrate/20200926190114_add_content_type_to_statuses.rb new file mode 100644 index 0000000000..efbe2caa71 --- /dev/null +++ b/db/migrate/20200926190114_add_content_type_to_statuses.rb @@ -0,0 +1,5 @@ +class AddContentTypeToStatuses < ActiveRecord::Migration[5.2] + def change + add_column :statuses, :content_type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 0fdc8cbfad..6dbad1864e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_10_08_220312) do +ActiveRecord::Schema.define(version: 2020_10_08_220313) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -930,6 +930,7 @@ ActiveRecord::Schema.define(version: 2020_10_08_220312) do t.datetime "expires_at" t.integer "expires_action", default: 0, null: false t.boolean "local_only" + t.string "content_type" t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)" t.index ["id", "account_id"], name: "index_statuses_local_20190824", order: { id: :desc }, where: "((local OR (uri IS NULL)) AND (deleted_at IS NULL) AND (visibility = 0) AND (reblog_of_id IS NULL) AND ((NOT reply) OR (in_reply_to_account_id = account_id)))" t.index ["id", "account_id"], name: "index_statuses_public_20200119", order: { id: :desc }, where: "((deleted_at IS NULL) AND (visibility = 0) AND (reblog_of_id IS NULL) AND ((NOT reply) OR (in_reply_to_account_id = account_id)))" diff --git a/lib/kramdown/converter/mastodon.rb b/lib/kramdown/converter/mastodon.rb new file mode 100644 index 0000000000..97aa67cd1c --- /dev/null +++ b/lib/kramdown/converter/mastodon.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'kramdown/converter' +require 'kramdown/utils' + +module Kramdown + module Converter + class Mastodon < Html + def convert_text(element, _indent) + html = Formatter.instance.send(:encode_and_link_urls, element.value, @options[:linkable_accounts]) + + if @options[:custom_emojis] + Formatter.instance.send(:encode_custom_emojis, html, @options[:custom_emojis], @options[:autoplay]) + else + html + end + end + + def host_to_url(str) + "http#{Rails.configuration.x.use_https ? 's' : ''}://#{str}" unless str.blank? + end + + def convert_img(el, _opts) + base_host = Rails.configuration.x.web_domain + + assets_host = Rails.configuration.action_controller.asset_host + assets_host ||= host_to_url(base_host) + + media_host = host_to_url(ENV['S3_ALIAS_HOST']) + media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST']) + media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true' + media_host ||= assets_host + + src = el.attr['src'] + unless src.start_with?( media_host, ENV['IMAGE_PROXY_HOST'] || 'https://images.weserv.nl/') + src = "#{ENV['IMAGE_PROXY_PATH'] || 'https://images.weserv.nl/?n=-1&il&url='}#{src}" + end + el.attr['src'] = src + "<img#{html_attributes(el.attr)} />" + end + + def convert_codeblock(el, indent) + attr = el.attr.dup + lang = extract_code_language!(attr) + hl_opts = {} + highlighted_code = highlight_code(el.value, el.options[:lang] || lang, :block, hl_opts) + highlighted_code = highlighted_code == nil ? highlighted_code : highlighted_code.gsub(/[\r\n]/, '<br>') + + if highlighted_code + add_syntax_highlighter_to_class_attr(attr, lang || hl_opts[:default_lang]) + "#{' ' * indent}<div#{html_attributes(attr)}>#{highlighted_code}#{' ' * indent}</div>\n" + else + result = escape_html(el.value) + result.chomp! + if el.attr['class'].to_s =~ /\bshow-whitespaces\b/ + result.gsub!(/(?:(^[ \t]+)|([ \t]+$)|([ \t]+))/) do |m| + suffix = ($1 ? '-l' : ($2 ? '-r' : '')) + m.scan(/./).map do |c| + case c + when "\t" then "<span class=\"ws-tab#{suffix}\">\t</span>" + when " " then "<span class=\"ws-space#{suffix}\">⋅</span>" + end + end.join('') + end + end + code_attr = {} + code_attr['class'] = "language-#{lang}" if lang + "#{' ' * indent}<pre#{html_attributes(attr)}>" \ + "<code#{html_attributes(code_attr)}>#{result}\n</code></pre>\n" + end + end + + end + end +end \ No newline at end of file diff --git a/lib/kramdown/parser/mastodon.rb b/lib/kramdown/parser/mastodon.rb new file mode 100644 index 0000000000..1b35a1d6e8 --- /dev/null +++ b/lib/kramdown/parser/mastodon.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'kramdown/parser' + +module Kramdown + module Parser + class Mastodon < GFM + def initialize(source, options) + super + + # @block_parsers = %i(blank_line paragraph) + # @span_parsers = %i(no_intra_emphasis codespan immediate_line_break escaped_chars) + end + + def parse_immediate_line_break + @tree.children << Element.new(:br, nil, nil, location: @src.current_line_number) + @src.pos += @src.matched_size + end + + define_parser(:immediate_line_break, /\n/, '\n') + + def parse_no_intra_emphasis + start_line_number = @src.current_line_number + saved_pos = @src.save_pos + + result = @src.scan(EMPHASIS_START) + element = (result.length == 2 ? :strong : :em) + type = result[0..0] + + if (@src.pre_match =~ /[[:alpha:]-]\z/) || @src.check(/\s/) || @tree.type == element || @stack.any? { |el, _| el.type == element } + add_text(result) + return + end + + sub_parse = lambda do |delim, elem| + el = Element.new(elem, nil, nil, location: start_line_number) + stop_re = /#{Regexp.escape(delim)}/ + + found = parse_spans(el, stop_re) do + (@src.pre_match[-1, 1] !~ /\s/) && + (elem != :em || !@src.match?(/#{Regexp.escape(delim * 2)}(?!#{Regexp.escape(delim)})/)) && + (type != '_' || !@src.match?(/#{Regexp.escape(delim)}[[:alnum:]]/)) && !el.children.empty? + end + + [found, el, stop_re] + end + + found, el, stop_re = sub_parse.call(result, element) + + if !found && element == :strong && @tree.type != :em + @src.revert_pos(saved_pos) + @src.pos += 1 + found, el, stop_re = sub_parse.call(type, :em) + end + + if found + @src.scan(stop_re) + @tree.children << el + else + @src.revert_pos(saved_pos) + @src.pos += result.length + add_text(result) + end + end + + define_parser(:no_intra_emphasis, EMPHASIS_START, '\*|_') + end + end +end \ No newline at end of file -- GitLab