Compare commits

...

7 Commits

Author SHA1 Message Date
Matt Jankowski
c433a29371
Merge 372e0a423d into 9a2be25199 2025-09-05 09:07:27 +00:00
Claire
9a2be25199
Fix missing beforeUnload confirmation when a quote post is being authored (#36034) 2025-09-05 08:51:49 +00:00
Claire
279405f2a7
Fix incorrect change of unlisted source strings (#36033) 2025-09-05 08:34:14 +00:00
Claire
497bfbc483
Fix source string for visibility dropdown hint (#36031) 2025-09-05 08:14:34 +00:00
github-actions[bot]
dd6bd681ea
New Crowdin Translations (automated) (#36029)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-09-05 08:14:25 +00:00
Claire
0d93801bde
Fix missing beforeUnload confirmation when a poll is being authored (#36030) 2025-09-05 08:07:59 +00:00
Matt Jankowski
372e0a423d Convert to doorkeeper ORM mixin style for OAuth models 2025-09-02 11:00:04 -04:00
62 changed files with 294 additions and 185 deletions

View File

@ -4,7 +4,7 @@ class Api::V1::AppsController < Api::BaseController
skip_before_action :require_authenticated_user! skip_before_action :require_authenticated_user!
def create def create
@app = Doorkeeper::Application.create!(application_options) @app = OAuth::Application.create!(application_options)
render json: @app, serializer: REST::CredentialApplicationSerializer render json: @app, serializer: REST::CredentialApplicationSerializer
end end

View File

@ -17,7 +17,7 @@ class OAuth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
def destroy def destroy
Web::PushSubscription.unsubscribe_for(params[:id], current_resource_owner) Web::PushSubscription.unsubscribe_for(params[:id], current_resource_owner)
Doorkeeper::Application.find_by(id: params[:id])&.close_streaming_sessions(current_resource_owner) OAuth::Application.find_by(id: params[:id])&.close_streaming_sessions(current_resource_owner)
super super
end end

View File

@ -10,7 +10,7 @@ class Settings::ApplicationsController < Settings::BaseController
def show; end def show; end
def new def new
@application = Doorkeeper::Application.new( @application = OAuth::Application.new(
redirect_uri: Doorkeeper.configuration.native_redirect_uri, redirect_uri: Doorkeeper.configuration.native_redirect_uri,
scopes: 'profile' scopes: 'profile'
) )
@ -59,6 +59,6 @@ class Settings::ApplicationsController < Settings::BaseController
end end
def application_params def application_params
params.expect(doorkeeper_application: [:name, :redirect_uri, :website, scopes: []]) params.expect(oauth_application: [:name, :redirect_uri, :website, scopes: []])
end end
end end

View File

@ -92,8 +92,7 @@ const messages = defineMessages({
const mapStateToProps = state => ({ const mapStateToProps = state => ({
layout: state.getIn(['meta', 'layout']), layout: state.getIn(['meta', 'layout']),
isComposing: state.getIn(['compose', 'is_composing']), isComposing: state.getIn(['compose', 'is_composing']),
hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null || state.getIn(['compose', 'quoted_status_id']) !== null,
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']), canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']),
firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0, newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0,
@ -241,8 +240,7 @@ class UI extends PureComponent {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
children: PropTypes.node, children: PropTypes.node,
isComposing: PropTypes.bool, isComposing: PropTypes.bool,
hasComposingText: PropTypes.bool, hasComposingContents: PropTypes.bool,
hasMediaAttachments: PropTypes.bool,
canUploadMore: PropTypes.bool, canUploadMore: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
layout: PropTypes.string.isRequired, layout: PropTypes.string.isRequired,
@ -257,11 +255,11 @@ class UI extends PureComponent {
}; };
handleBeforeUnload = e => { handleBeforeUnload = e => {
const { intl, dispatch, isComposing, hasComposingText, hasMediaAttachments } = this.props; const { intl, dispatch, isComposing, hasComposingContents } = this.props;
dispatch(synchronouslySubmitMarkers()); dispatch(synchronouslySubmitMarkers());
if (isComposing && (hasComposingText || hasMediaAttachments)) { if (isComposing && hasComposingContents) {
e.preventDefault(); e.preventDefault();
// Setting returnValue to any string causes confirmation dialog. // Setting returnValue to any string causes confirmation dialog.
// Many browsers no longer display this text to users, // Many browsers no longer display this text to users,

View File

@ -29,6 +29,8 @@
"account.endorse": "Lakaat war-wel war ar profil", "account.endorse": "Lakaat war-wel war ar profil",
"account.familiar_followers_one": "Heuilhet gant {name1}", "account.familiar_followers_one": "Heuilhet gant {name1}",
"account.familiar_followers_two": "Heuilhet gant {name1} ha {name2}", "account.familiar_followers_two": "Heuilhet gant {name1} ha {name2}",
"account.featured.accounts": "Profiloù",
"account.featured.hashtags": "Gerioù-klik",
"account.featured_tags.last_status_at": "Toud diwezhañ : {date}", "account.featured_tags.last_status_at": "Toud diwezhañ : {date}",
"account.featured_tags.last_status_never": "Embannadur ebet", "account.featured_tags.last_status_never": "Embannadur ebet",
"account.follow": "Heuliañ", "account.follow": "Heuliañ",
@ -39,6 +41,7 @@
"account.followers_you_know_counter": "{counter} a anavezit", "account.followers_you_know_counter": "{counter} a anavezit",
"account.following": "Koumanantoù", "account.following": "Koumanantoù",
"account.follows.empty": "An implijer·ez-mañ na heul den ebet.", "account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
"account.follows_you": "Ho heuilh",
"account.go_to_profile": "Gwelet ar profil", "account.go_to_profile": "Gwelet ar profil",
"account.hide_reblogs": "Kuzh skignadennoù gant @{name}", "account.hide_reblogs": "Kuzh skignadennoù gant @{name}",
"account.in_memoriam": "E koun.", "account.in_memoriam": "E koun.",
@ -89,7 +92,10 @@
"alt_text_modal.done": "Graet", "alt_text_modal.done": "Graet",
"announcement.announcement": "Kemennad", "announcement.announcement": "Kemennad",
"annual_report.summary.followers.followers": "heulier", "annual_report.summary.followers.followers": "heulier",
"annual_report.summary.followers.total": "{count} en holl",
"annual_report.summary.highlighted_post.possessive": "{name}", "annual_report.summary.highlighted_post.possessive": "{name}",
"annual_report.summary.most_used_app.most_used_app": "arload muiañ implijet",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "ar gerioù-klik implijet ar muiañ",
"annual_report.summary.most_used_hashtag.none": "Hini ebet", "annual_report.summary.most_used_hashtag.none": "Hini ebet",
"annual_report.summary.new_posts.new_posts": "toudoù nevez", "annual_report.summary.new_posts.new_posts": "toudoù nevez",
"attachments_list.unprocessed": "(ket meret)", "attachments_list.unprocessed": "(ket meret)",
@ -149,7 +155,7 @@
"compose.saved.body": "Enrollet.", "compose.saved.body": "Enrollet.",
"compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h", "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
"compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.", "compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.hashtag_warning": "Ne vo ket listennet an toud-mañ dindan gerioù-klik ebet dre m'eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.",
"compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.", "compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.",
"compose_form.lock_disclaimer.lock": "prennet", "compose_form.lock_disclaimer.lock": "prennet",
"compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?", "compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
@ -168,6 +174,7 @@
"confirmations.block.confirm": "Stankañ", "confirmations.block.confirm": "Stankañ",
"confirmations.delete.confirm": "Dilemel", "confirmations.delete.confirm": "Dilemel",
"confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?", "confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?",
"confirmations.delete.title": "Dilemel an toud?",
"confirmations.delete_list.confirm": "Dilemel", "confirmations.delete_list.confirm": "Dilemel",
"confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?", "confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?",
"confirmations.delete_list.title": "Dilemel al listenn?", "confirmations.delete_list.title": "Dilemel al listenn?",
@ -176,10 +183,14 @@
"confirmations.follow_to_list.title": "Heuliañ an implijer·ez?", "confirmations.follow_to_list.title": "Heuliañ an implijer·ez?",
"confirmations.logout.confirm": "Digevreañ", "confirmations.logout.confirm": "Digevreañ",
"confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?", "confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?",
"confirmations.logout.title": "Digevreañ?",
"confirmations.mute.confirm": "Kuzhat", "confirmations.mute.confirm": "Kuzhat",
"confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro", "confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro",
"confirmations.unfollow.confirm": "Diheuliañ", "confirmations.unfollow.confirm": "Diheuliañ",
"confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?", "confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?",
"confirmations.unfollow.title": "Paouez da heuliañ an implijer·ez?",
"content_warning.hide": "Kuzhat an embannadur",
"content_warning.show": "Diskwel memes tra",
"content_warning.show_more": "Diskouez muioc'h", "content_warning.show_more": "Diskouez muioc'h",
"conversation.delete": "Dilemel ar gaozeadenn", "conversation.delete": "Dilemel ar gaozeadenn",
"conversation.mark_as_read": "Merkañ evel lennet", "conversation.mark_as_read": "Merkañ evel lennet",
@ -224,8 +235,8 @@
"empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.", "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.",
"empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !", "empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !",
"empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.", "empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.",
"empty_column.followed_tags": "N'emaoc'h oc'h heuliañ hashtag ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.", "empty_column.followed_tags": "N'emaoc'h oc'h heuliañ ger-klik ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.",
"empty_column.hashtag": "N'eus netra en hashtag-mañ c'hoazh.", "empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.",
"empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.", "empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.",
"empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.", "empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.",
"empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.", "empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.",
@ -241,7 +252,7 @@
"explore.title": "Diouzh ar c'hiz", "explore.title": "Diouzh ar c'hiz",
"explore.trending_links": "Keleier", "explore.trending_links": "Keleier",
"explore.trending_statuses": "Embannadurioù", "explore.trending_statuses": "Embannadurioù",
"explore.trending_tags": "Hashtagoù", "explore.trending_tags": "Gerioù-klik",
"featured_carousel.next": "War-raok", "featured_carousel.next": "War-raok",
"featured_carousel.post": "Embannadenn", "featured_carousel.post": "Embannadenn",
"featured_carousel.previous": "War-gil", "featured_carousel.previous": "War-gil",
@ -269,7 +280,8 @@
"follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h", "follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h",
"follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}", "follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}",
"follow_suggestions.view_all": "Gwelet pep tra", "follow_suggestions.view_all": "Gwelet pep tra",
"followed_tags": "Hashtagoù o heuliañ", "follow_suggestions.who_to_follow": "Piv heuliañ",
"followed_tags": "Gerioù-klik o heuliañ",
"footer.about": "Diwar-benn", "footer.about": "Diwar-benn",
"footer.directory": "Kavlec'h ar profiloù", "footer.directory": "Kavlec'h ar profiloù",
"footer.get_app": "Pellgargañ an arload", "footer.get_app": "Pellgargañ an arload",
@ -281,19 +293,23 @@
"generic.saved": "Enrollet", "generic.saved": "Enrollet",
"getting_started.heading": "Loc'hañ", "getting_started.heading": "Loc'hañ",
"hashtag.admin_moderation": "Digeriñ an etrefas evezhiañ evit #{name}", "hashtag.admin_moderation": "Digeriñ an etrefas evezhiañ evit #{name}",
"hashtag.browse": "Furchal dre an toudoù gant #{hashtag}",
"hashtag.browse_from_account": "Furchal dre an toudoù gant @{name} gant #{hashtag}",
"hashtag.column_header.tag_mode.all": "ha(g) {additional}", "hashtag.column_header.tag_mode.all": "ha(g) {additional}",
"hashtag.column_header.tag_mode.any": "pe {additional}", "hashtag.column_header.tag_mode.any": "pe {additional}",
"hashtag.column_header.tag_mode.none": "hep {additional}", "hashtag.column_header.tag_mode.none": "hep {additional}",
"hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet", "hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet",
"hashtag.column_settings.select.placeholder": "Ouzhpennañ hashtagoù…", "hashtag.column_settings.select.placeholder": "Ouzhpennañ geri-klik…",
"hashtag.column_settings.tag_mode.all": "An holl anezho", "hashtag.column_settings.tag_mode.all": "An holl anezho",
"hashtag.column_settings.tag_mode.any": "Unan e mesk anezho", "hashtag.column_settings.tag_mode.any": "Unan e mesk anezho",
"hashtag.column_settings.tag_mode.none": "Hini ebet anezho", "hashtag.column_settings.tag_mode.none": "Hini ebet anezho",
"hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ", "hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ",
"hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv",
"hashtag.feature": "Lakaat war-wel war ar profil",
"hashtag.follow": "Heuliañ ar ger-klik", "hashtag.follow": "Heuliañ ar ger-klik",
"hashtag.unfollow": "Paouez heuliañ an hashtag", "hashtag.mute": "Kuzhat #{hashtag}",
"hashtag.unfollow": "Diheuliañ ar ger-klik",
"hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}", "hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}",
"home.column_settings.show_quotes": "Diskouez an arroudennoù", "home.column_settings.show_quotes": "Diskouez an arroudennoù",
"home.column_settings.show_reblogs": "Diskouez ar skignadennoù", "home.column_settings.show_reblogs": "Diskouez ar skignadennoù",
@ -302,12 +318,14 @@
"home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!", "home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!",
"home.pending_critical_update.link": "Gwelet an hizivadennoù", "home.pending_critical_update.link": "Gwelet an hizivadennoù",
"home.show_announcements": "Diskouez ar c'hemennoù", "home.show_announcements": "Diskouez ar c'hemennoù",
"interaction_modal.go": "Mont di",
"interaction_modal.on_another_server": "War ur servijer all", "interaction_modal.on_another_server": "War ur servijer all",
"interaction_modal.on_this_server": "War ar servijer-mañ", "interaction_modal.on_this_server": "War ar servijer-mañ",
"interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet", "interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet",
"interaction_modal.title.follow": "Heuliañ {name}", "interaction_modal.title.follow": "Heuliañ {name}",
"interaction_modal.title.reblog": "Skignañ toud {name}", "interaction_modal.title.reblog": "Skignañ toud {name}",
"interaction_modal.title.reply": "Respont da doud {name}", "interaction_modal.title.reply": "Respont da doud {name}",
"interaction_modal.username_prompt": "D.s. {example}",
"intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}", "intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}",
"intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}", "intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}",
"intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}", "intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}",
@ -345,12 +363,14 @@
"keyboard_shortcuts.toot": "Kregiñ gant un toud nevez", "keyboard_shortcuts.toot": "Kregiñ gant un toud nevez",
"keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask", "keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask",
"keyboard_shortcuts.up": "Pignat er roll", "keyboard_shortcuts.up": "Pignat er roll",
"learn_more_link.got_it": "Mat eo",
"lightbox.close": "Serriñ", "lightbox.close": "Serriñ",
"lightbox.next": "Da-heul", "lightbox.next": "Da-heul",
"lightbox.previous": "A-raok", "lightbox.previous": "A-raok",
"limited_account_hint.action": "Diskouez an aelad memes tra", "limited_account_hint.action": "Diskouez ar profil memes tra",
"limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.", "limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.",
"link_preview.author": "Gant {name}", "link_preview.author": "Gant {name}",
"link_preview.more_from_author": "Muioc'h gant {name}",
"lists.add_member": "Ouzhpennañ", "lists.add_member": "Ouzhpennañ",
"lists.add_to_list": "Ouzhpennañ d'al listenn", "lists.add_to_list": "Ouzhpennañ d'al listenn",
"lists.create": "Krouiñ", "lists.create": "Krouiñ",
@ -359,13 +379,19 @@
"lists.done": "Graet", "lists.done": "Graet",
"lists.edit": "Kemmañ al listenn", "lists.edit": "Kemmañ al listenn",
"lists.list_name": "Anv al listenn", "lists.list_name": "Anv al listenn",
"lists.new_list_name": "Anv nevez al listenn",
"lists.no_lists_yet": "Listenn ebet c'hoazh.",
"lists.replies_policy.followed": "Pep implijer.ez heuliet", "lists.replies_policy.followed": "Pep implijer.ez heuliet",
"lists.replies_policy.list": "Izili ar roll", "lists.replies_policy.list": "Izili ar roll",
"lists.replies_policy.none": "Den ebet", "lists.replies_policy.none": "Den ebet",
"lists.save": "Enrollañ",
"lists.search": "Klask",
"load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}",
"loading_indicator.label": "O kargañ…", "loading_indicator.label": "O kargañ…",
"media_gallery.hide": "Kuzhat",
"navigation_bar.about": "Diwar-benn", "navigation_bar.about": "Diwar-benn",
"navigation_bar.account_settings": "Ger-tremen ha surentez", "navigation_bar.account_settings": "Ger-tremen ha surentez",
"navigation_bar.administration": "Merañ",
"navigation_bar.automated_deletion": "Dilemel an embannadenn ent-emgefreek", "navigation_bar.automated_deletion": "Dilemel an embannadenn ent-emgefreek",
"navigation_bar.blocks": "Implijer·ezed·ien berzet", "navigation_bar.blocks": "Implijer·ezed·ien berzet",
"navigation_bar.bookmarks": "Sinedoù", "navigation_bar.bookmarks": "Sinedoù",
@ -374,11 +400,12 @@
"navigation_bar.favourites": "Muiañ-karet", "navigation_bar.favourites": "Muiañ-karet",
"navigation_bar.filters": "Gerioù kuzhet", "navigation_bar.filters": "Gerioù kuzhet",
"navigation_bar.follow_requests": "Pedadoù heuliañ", "navigation_bar.follow_requests": "Pedadoù heuliañ",
"navigation_bar.followed_tags": "Hashtagoù o heuliañ", "navigation_bar.followed_tags": "Gerioù-klik o heuliañ",
"navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien", "navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien",
"navigation_bar.import_export": "Enporzhiañ hag ezporzhiañ", "navigation_bar.import_export": "Enporzhiañ hag ezporzhiañ",
"navigation_bar.lists": "Listennoù", "navigation_bar.lists": "Listennoù",
"navigation_bar.logout": "Digennaskañ", "navigation_bar.logout": "Digennaskañ",
"navigation_bar.moderation": "Habaskadur",
"navigation_bar.more": "Muioc'h", "navigation_bar.more": "Muioc'h",
"navigation_bar.mutes": "Implijer·ion·ezed kuzhet", "navigation_bar.mutes": "Implijer·ion·ezed kuzhet",
"navigation_bar.preferences": "Gwellvezioù", "navigation_bar.preferences": "Gwellvezioù",
@ -391,6 +418,8 @@
"notification.follow.name_and_others": "{name} <a>{count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}}</a> zo o heuliañ ac'hanoc'h", "notification.follow.name_and_others": "{name} <a>{count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}}</a> zo o heuliañ ac'hanoc'h",
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ", "notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
"notification.label.reply": "Respont", "notification.label.reply": "Respont",
"notification.mention": "Meneg",
"notification.mentioned_you": "Gant {name} oc'h bet meneget",
"notification.moderation-warning.learn_more": "Gouzout hiroc'h", "notification.moderation-warning.learn_more": "Gouzout hiroc'h",
"notification.own_poll": "Echu eo ho sontadeg", "notification.own_poll": "Echu eo ho sontadeg",
"notification.reblog": "Gant {name} eo bet skignet ho toud", "notification.reblog": "Gant {name} eo bet skignet ho toud",
@ -447,7 +476,7 @@
"onboarding.profile.display_name": "Anv diskouezet", "onboarding.profile.display_name": "Anv diskouezet",
"onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…", "onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…",
"onboarding.profile.note": "Berr-ha-berr", "onboarding.profile.note": "Berr-ha-berr",
"onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #hashtagoù…", "onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #geri-klik…",
"onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel", "onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel",
"onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil", "onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil",
"password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se", "password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se",
@ -480,6 +509,7 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}eil", "relative_time.seconds": "{number}eil",
"relative_time.today": "hiziv", "relative_time.today": "hiziv",
"remove_quote_hint.button_label": "Mat eo",
"reply_indicator.cancel": "Nullañ", "reply_indicator.cancel": "Nullañ",
"reply_indicator.poll": "Sontadeg", "reply_indicator.poll": "Sontadeg",
"report.block": "Stankañ", "report.block": "Stankañ",
@ -528,7 +558,7 @@
"search.placeholder": "Klask", "search.placeholder": "Klask",
"search.quick_action.account_search": "Profiloù a glot gant {x}", "search.quick_action.account_search": "Profiloù a glot gant {x}",
"search.quick_action.go_to_account": "Mont d'ar profil {x}", "search.quick_action.go_to_account": "Mont d'ar profil {x}",
"search.quick_action.go_to_hashtag": "Mont d'an hashtag {x}", "search.quick_action.go_to_hashtag": "Mont d'ar ger-klik {x}",
"search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon", "search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon",
"search.quick_action.status_search": "Embannadurioù a glot gant {x}", "search.quick_action.status_search": "Embannadurioù a glot gant {x}",
"search.search_or_paste": "Klask pe pegañ un URL", "search.search_or_paste": "Klask pe pegañ un URL",
@ -541,7 +571,7 @@
"search_popout.user": "implijer·ez", "search_popout.user": "implijer·ez",
"search_results.accounts": "Profiloù", "search_results.accounts": "Profiloù",
"search_results.all": "Pep tra", "search_results.all": "Pep tra",
"search_results.hashtags": "Hashtagoù", "search_results.hashtags": "Gerioù-klik",
"search_results.no_results": "Disoc'h ebet.", "search_results.no_results": "Disoc'h ebet.",
"search_results.see_all": "Gwelet pep tra", "search_results.see_all": "Gwelet pep tra",
"search_results.statuses": "Toudoù", "search_results.statuses": "Toudoù",
@ -607,6 +637,7 @@
"subscribed_languages.save": "Enrollañ ar cheñchamantoù", "subscribed_languages.save": "Enrollañ ar cheñchamantoù",
"subscribed_languages.target": "Cheñch ar yezhoù koumanantet evit {target}", "subscribed_languages.target": "Cheñch ar yezhoù koumanantet evit {target}",
"tabs_bar.home": "Degemer", "tabs_bar.home": "Degemer",
"tabs_bar.menu": "Lañser",
"tabs_bar.notifications": "Kemennoù", "tabs_bar.notifications": "Kemennoù",
"tabs_bar.publish": "Embannadenn nevez", "tabs_bar.publish": "Embannadenn nevez",
"tabs_bar.search": "Klask", "tabs_bar.search": "Klask",
@ -638,6 +669,8 @@
"video.hide": "Kuzhat ar video", "video.hide": "Kuzhat ar video",
"video.pause": "Paouez", "video.pause": "Paouez",
"video.play": "Lenn", "video.play": "Lenn",
"visibility_modal.privacy_label": "Gwelusted",
"visibility_modal.quote_followers": "Tud koumanantet hepken", "visibility_modal.quote_followers": "Tud koumanantet hepken",
"visibility_modal.quote_public": "Pep den" "visibility_modal.quote_public": "Pep den",
"visibility_modal.save": "Enrollañ"
} }

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} m", "relative_time.minutes": "{number} m",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "dnes", "relative_time.today": "dnes",
"remove_quote_hint.button_label": "Chápu",
"remove_quote_hint.message": "Můžete to udělat z {icon} nabídky možností.",
"remove_quote_hint.title": "Chcete odstranit citovaný příspěvek?",
"reply_indicator.attachments": "{count, plural, one {{counter} příloha} few {{counter} přílohy} other {{counter} příloh}}", "reply_indicator.attachments": "{count, plural, one {{counter} příloha} few {{counter} přílohy} other {{counter} příloh}}",
"reply_indicator.cancel": "Zrušit", "reply_indicator.cancel": "Zrušit",
"reply_indicator.poll": "Anketa", "reply_indicator.poll": "Anketa",
@ -863,6 +866,7 @@
"status.block": "Blokovat @{name}", "status.block": "Blokovat @{name}",
"status.bookmark": "Přidat do záložek", "status.bookmark": "Přidat do záložek",
"status.cancel_reblog_private": "Zrušit boostnutí", "status.cancel_reblog_private": "Zrušit boostnutí",
"status.cannot_quote": "Citování je na tomo příspěvku zakázáno",
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
"status.context.load_new_replies": "K dispozici jsou nové odpovědi", "status.context.load_new_replies": "K dispozici jsou nové odpovědi",
"status.context.loading": "Hledání dalších odpovědí", "status.context.loading": "Hledání dalších odpovědí",
@ -988,6 +992,7 @@
"visibility_modal.header": "Viditelnost a interakce", "visibility_modal.header": "Viditelnost a interakce",
"visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.", "visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
"visibility_modal.helper.privacy_editing": "Publikované příspěvky nemohou změnit svou viditelnost.", "visibility_modal.helper.privacy_editing": "Publikované příspěvky nemohou změnit svou viditelnost.",
"visibility_modal.helper.privacy_private_self_quote": "Citace vlastních soukromých příspěvků nelze zveřejnit.",
"visibility_modal.helper.private_quoting": "Příspěvky pouze pro sledující, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.", "visibility_modal.helper.private_quoting": "Příspěvky pouze pro sledující, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
"visibility_modal.helper.unlisted_quoting": "Když vás lidé citují, jejich příspěvek bude v časové ose populárních příspěvků také skryt.", "visibility_modal.helper.unlisted_quoting": "Když vás lidé citují, jejich příspěvek bude v časové ose populárních příspěvků také skryt.",
"visibility_modal.instructions": "Nastavte, kdo bude moci interagovat s tímto příspěvkem. Tyto nastavení též můžete změnit pro všechny budoucí příspěvky v <link>Nastavení > Výchozí nastavení příspěvků</link>.", "visibility_modal.instructions": "Nastavte, kdo bude moci interagovat s tímto příspěvkem. Tyto nastavení též můžete změnit pro všechny budoucí příspěvky v <link>Nastavení > Výchozí nastavení příspěvků</link>.",

View File

@ -768,6 +768,7 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "i dag", "relative_time.today": "i dag",
"remove_quote_hint.button_label": "Forstået",
"reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}", "reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}",
"reply_indicator.cancel": "Afbryd", "reply_indicator.cancel": "Afbryd",
"reply_indicator.poll": "Afstemning", "reply_indicator.poll": "Afstemning",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} Min.", "relative_time.minutes": "{number} Min.",
"relative_time.seconds": "{number} Sek.", "relative_time.seconds": "{number} Sek.",
"relative_time.today": "heute", "relative_time.today": "heute",
"remove_quote_hint.button_label": "Verstanden",
"remove_quote_hint.message": "Klicke dafür im Beitrag auf „{icon} Mehr“.",
"remove_quote_hint.title": "Möchtest du aus dem zitierten Beitrag entfernt werden?",
"reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}", "reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}",
"reply_indicator.cancel": "Abbrechen", "reply_indicator.cancel": "Abbrechen",
"reply_indicator.poll": "Umfrage", "reply_indicator.poll": "Umfrage",

View File

@ -991,7 +991,7 @@
"visibility_modal.button_title": "Set visibility", "visibility_modal.button_title": "Set visibility",
"visibility_modal.header": "Visibility and interaction", "visibility_modal.header": "Visibility and interaction",
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.", "visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
"visibility_modal.helper.privacy_editing": "Published posts cannot change their visibility.", "visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.",
"visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.", "visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.",
"visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.", "visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.",
"visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.", "visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.",

View File

@ -30,6 +30,8 @@
"account.edit_profile": "Redakti la profilon", "account.edit_profile": "Redakti la profilon",
"account.enable_notifications": "Sciigu min kiam @{name} afiŝos", "account.enable_notifications": "Sciigu min kiam @{name} afiŝos",
"account.endorse": "Montri en profilo", "account.endorse": "Montri en profilo",
"account.familiar_followers_one": "Sekvita de {name1}",
"account.familiar_followers_two": "Sekvita de {name1} kaj {name2}",
"account.featured": "Montrita", "account.featured": "Montrita",
"account.featured.accounts": "Profiloj", "account.featured.accounts": "Profiloj",
"account.featured.hashtags": "Kradvortoj", "account.featured.hashtags": "Kradvortoj",
@ -305,6 +307,7 @@
"emoji_button.search_results": "Serĉaj rezultoj", "emoji_button.search_results": "Serĉaj rezultoj",
"emoji_button.symbols": "Simboloj", "emoji_button.symbols": "Simboloj",
"emoji_button.travel": "Vojaĝoj kaj lokoj", "emoji_button.travel": "Vojaĝoj kaj lokoj",
"empty_column.account_featured.me": "Vi ankoraŭ nenion prezentis. Ĉu vi sciis, ke vi povas prezenti viajn plej ofte uzatajn kradvortojn, kaj eĉ la kontojn de viaj amikoj sur via profilo?",
"empty_column.account_featured_other.unknown": "Ĉi tiu konto ankoraŭ ne montris ion ajn.", "empty_column.account_featured_other.unknown": "Ĉi tiu konto ankoraŭ ne montris ion ajn.",
"empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon", "empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon",
"empty_column.account_suspended": "Konto suspendita", "empty_column.account_suspended": "Konto suspendita",
@ -338,6 +341,7 @@
"explore.trending_links": "Novaĵoj", "explore.trending_links": "Novaĵoj",
"explore.trending_statuses": "Afiŝoj", "explore.trending_statuses": "Afiŝoj",
"explore.trending_tags": "Kradvortoj", "explore.trending_tags": "Kradvortoj",
"featured_carousel.header": "{count, plural, one {Alpinglita afiŝo} other {Alpinglitaj afiŝoj}}",
"featured_carousel.next": "Antaŭen", "featured_carousel.next": "Antaŭen",
"featured_carousel.post": "Afiŝi", "featured_carousel.post": "Afiŝi",
"featured_carousel.previous": "Malantaŭen", "featured_carousel.previous": "Malantaŭen",
@ -751,6 +755,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "hodiaŭ", "relative_time.today": "hodiaŭ",
"remove_quote_hint.button_label": "Komprenite",
"remove_quote_hint.message": "Vi povas fari tion el la menuo de opcioj {icon}.",
"remove_quote_hint.title": "Ĉu vi volas forigi vian cititan afiŝon?",
"reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}", "reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}",
"reply_indicator.cancel": "Nuligi", "reply_indicator.cancel": "Nuligi",
"reply_indicator.poll": "Balotenketo", "reply_indicator.poll": "Balotenketo",
@ -846,6 +853,7 @@
"status.block": "Bloki @{name}", "status.block": "Bloki @{name}",
"status.bookmark": "Aldoni al la legosignoj", "status.bookmark": "Aldoni al la legosignoj",
"status.cancel_reblog_private": "Ne plu diskonigi", "status.cancel_reblog_private": "Ne plu diskonigi",
"status.cannot_quote": "Citaĵoj estas malebligitaj en ĉi tiu afiŝo",
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi", "status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
"status.context.load_new_replies": "Disponeblaj novaj respondoj", "status.context.load_new_replies": "Disponeblaj novaj respondoj",
"status.context.loading": "Serĉante pliajn respondojn", "status.context.loading": "Serĉante pliajn respondojn",
@ -971,6 +979,7 @@
"visibility_modal.helper.privacy_editing": "Publikigitaj afiŝoj ne povas ŝanĝi sian videblon.", "visibility_modal.helper.privacy_editing": "Publikigitaj afiŝoj ne povas ŝanĝi sian videblon.",
"visibility_modal.helper.private_quoting": "Afiŝoj nur por sekvantoj verkitaj ĉe Mastodon ne povas esti cititaj de aliaj.", "visibility_modal.helper.private_quoting": "Afiŝoj nur por sekvantoj verkitaj ĉe Mastodon ne povas esti cititaj de aliaj.",
"visibility_modal.helper.unlisted_quoting": "Kiam homoj citas vin, ilia afiŝo ankaŭ estos kaŝita de tendencaj templinioj.", "visibility_modal.helper.unlisted_quoting": "Kiam homoj citas vin, ilia afiŝo ankaŭ estos kaŝita de tendencaj templinioj.",
"visibility_modal.privacy_label": "Videbleco",
"visibility_modal.quote_followers": "Nur sekvantoj", "visibility_modal.quote_followers": "Nur sekvantoj",
"visibility_modal.quote_label": "Kiu povas citi", "visibility_modal.quote_label": "Kiu povas citi",
"visibility_modal.quote_nobody": "Nur mi", "visibility_modal.quote_nobody": "Nur mi",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "hoy", "relative_time.today": "hoy",
"remove_quote_hint.button_label": "Entendido",
"remove_quote_hint.message": "Podés hacerlo desde el menú de opciones {icon}.",
"remove_quote_hint.title": "¿Querés eliminar tu mensaje citado?",
"reply_indicator.attachments": "{count, plural,one {# adjunto} other {# adjuntos}}", "reply_indicator.attachments": "{count, plural,one {# adjunto} other {# adjuntos}}",
"reply_indicator.cancel": "Cancelar", "reply_indicator.cancel": "Cancelar",
"reply_indicator.poll": "Encuesta", "reply_indicator.poll": "Encuesta",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} m", "relative_time.minutes": "{number} m",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "hoy", "relative_time.today": "hoy",
"remove_quote_hint.button_label": "Entendido",
"remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.",
"remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?",
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}", "reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
"reply_indicator.cancel": "Cancelar", "reply_indicator.cancel": "Cancelar",
"reply_indicator.poll": "Encuesta", "reply_indicator.poll": "Encuesta",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} m", "relative_time.minutes": "{number} m",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "hoy", "relative_time.today": "hoy",
"remove_quote_hint.button_label": "Entendido",
"remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.",
"remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?",
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}", "reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
"reply_indicator.cancel": "Cancelar", "reply_indicator.cancel": "Cancelar",
"reply_indicator.poll": "Encuesta", "reply_indicator.poll": "Encuesta",

View File

@ -863,6 +863,7 @@
"status.block": "Blokeeri @{name}", "status.block": "Blokeeri @{name}",
"status.bookmark": "Järjehoidja", "status.bookmark": "Järjehoidja",
"status.cancel_reblog_private": "Lõpeta jagamine", "status.cancel_reblog_private": "Lõpeta jagamine",
"status.cannot_quote": "Selle postituse tsiteerimine pole lubatud",
"status.cannot_reblog": "Seda postitust ei saa jagada", "status.cannot_reblog": "Seda postitust ei saa jagada",
"status.context.load_new_replies": "Leidub uusi vastuseid", "status.context.load_new_replies": "Leidub uusi vastuseid",
"status.context.loading": "Kontrollin täiendavate vastuste olemasolu", "status.context.loading": "Kontrollin täiendavate vastuste olemasolu",
@ -988,9 +989,13 @@
"visibility_modal.header": "Nähtavus ja kasutus", "visibility_modal.header": "Nähtavus ja kasutus",
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.", "visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
"visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.", "visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.",
"visibility_modal.helper.privacy_private_self_quote": "Privaatsete postituste tsiteerimist oma enda poolt pole võimalik teha avalikuks.",
"visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.", "visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
"visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.", "visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.",
"visibility_modal.instructions": "Halda seda, kes võivad antud postitusega suhestuda. Lisaks võid kõikide tulevaste postituste seadistusi muuta valikust <link>Eelistused > Postituse vaikeseadistused</link>.",
"visibility_modal.privacy_label": "Nähtavus",
"visibility_modal.quote_followers": "Ainult jälgijad", "visibility_modal.quote_followers": "Ainult jälgijad",
"visibility_modal.quote_label": "Kes võivad tsiteerida",
"visibility_modal.quote_nobody": "Ainult mina", "visibility_modal.quote_nobody": "Ainult mina",
"visibility_modal.quote_public": "Kõik", "visibility_modal.quote_public": "Kõik",
"visibility_modal.save": "Salvesta" "visibility_modal.save": "Salvesta"

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} min", "relative_time.minutes": "{number} min",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "tänään", "relative_time.today": "tänään",
"remove_quote_hint.button_label": "Selvä",
"remove_quote_hint.message": "Voit tehdä sen {icon}-valikosta.",
"remove_quote_hint.title": "Haluatko poistaa lainatun julkaisusi?",
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}", "reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
"reply_indicator.cancel": "Peruuta", "reply_indicator.cancel": "Peruuta",
"reply_indicator.poll": "Äänestys", "reply_indicator.poll": "Äänestys",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "hoxe", "relative_time.today": "hoxe",
"remove_quote_hint.button_label": "Entendido",
"remove_quote_hint.message": "Pódelo facer desde o {icon} menú de opcións.",
"remove_quote_hint.title": "Queres eliminar a publicación citada?",
"reply_indicator.attachments": "{count, plural, one {# adxunto} other {# adxuntos}}", "reply_indicator.attachments": "{count, plural, one {# adxunto} other {# adxuntos}}",
"reply_indicator.cancel": "Desbotar", "reply_indicator.cancel": "Desbotar",
"reply_indicator.poll": "Enquisa", "reply_indicator.poll": "Enquisa",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} דקות", "relative_time.minutes": "{number} דקות",
"relative_time.seconds": "{number} שניות", "relative_time.seconds": "{number} שניות",
"relative_time.today": "היום", "relative_time.today": "היום",
"remove_quote_hint.button_label": "הבנתי",
"remove_quote_hint.message": "ניתן לעשות זאת מתפריט האפשרויות {icon}",
"remove_quote_hint.title": "להסיר את ההודעה המצוטטת?",
"reply_indicator.attachments": "{count, plural,one {# קובץ מצורף}other {# קבצים מצורפים}}", "reply_indicator.attachments": "{count, plural,one {# קובץ מצורף}other {# קבצים מצורפים}}",
"reply_indicator.cancel": "ביטול", "reply_indicator.cancel": "ביטול",
"reply_indicator.poll": "משאל", "reply_indicator.poll": "משאל",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number}mín", "relative_time.minutes": "{number}mín",
"relative_time.seconds": "{number}sek", "relative_time.seconds": "{number}sek",
"relative_time.today": "í dag", "relative_time.today": "í dag",
"remove_quote_hint.button_label": "Náði því",
"remove_quote_hint.message": "Þú getur gert það úr {icon} valmyndinni.",
"remove_quote_hint.title": "Viltu fjarlægja tilvitnuðu færsluna þína?",
"reply_indicator.attachments": "{count, plural, one {# viðhengi} other {# viðhengi}}", "reply_indicator.attachments": "{count, plural, one {# viðhengi} other {# viðhengi}}",
"reply_indicator.cancel": "Hætta við", "reply_indicator.cancel": "Hætta við",
"reply_indicator.poll": "Könnun", "reply_indicator.poll": "Könnun",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "vandaag", "relative_time.today": "vandaag",
"remove_quote_hint.button_label": "Begrepen",
"remove_quote_hint.message": "Je kunt dit doen vanuit het {icon} optiesmenu.",
"remove_quote_hint.title": "Wil je jouw geciteerd bericht verwijderen?",
"reply_indicator.attachments": "{count, plural, one {# bijlage} other {# bijlagen}}", "reply_indicator.attachments": "{count, plural, one {# bijlage} other {# bijlagen}}",
"reply_indicator.cancel": "Annuleren", "reply_indicator.cancel": "Annuleren",
"reply_indicator.poll": "Peiling", "reply_indicator.poll": "Peiling",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} phút", "relative_time.minutes": "{number} phút",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "hôm nay", "relative_time.today": "hôm nay",
"remove_quote_hint.button_label": "Đã hiểu",
"remove_quote_hint.message": "Bạn cũng có thể làm trong menu tùy chọn {icon}",
"remove_quote_hint.title": "Gỡ tút mà bạn đã trích dẫn?",
"reply_indicator.attachments": "{count, plural, other {# tập tin đính kèm}}", "reply_indicator.attachments": "{count, plural, other {# tập tin đính kèm}}",
"reply_indicator.cancel": "Hủy bỏ", "reply_indicator.cancel": "Hủy bỏ",
"reply_indicator.poll": "Vốt", "reply_indicator.poll": "Vốt",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} 分钟前", "relative_time.minutes": "{number} 分钟前",
"relative_time.seconds": "{number} 秒前", "relative_time.seconds": "{number} 秒前",
"relative_time.today": "今天", "relative_time.today": "今天",
"remove_quote_hint.button_label": "明白了",
"remove_quote_hint.message": "你可以通过 {icon} 选项菜单进行此操作。",
"remove_quote_hint.title": "是否需要删除你的引用嘟文?",
"reply_indicator.attachments": "{count, plural, other {# 个附件}}", "reply_indicator.attachments": "{count, plural, other {# 个附件}}",
"reply_indicator.cancel": "取消", "reply_indicator.cancel": "取消",
"reply_indicator.poll": "投票", "reply_indicator.poll": "投票",

View File

@ -768,6 +768,9 @@
"relative_time.minutes": "{number} 分鐘前", "relative_time.minutes": "{number} 分鐘前",
"relative_time.seconds": "{number} 秒", "relative_time.seconds": "{number} 秒",
"relative_time.today": "今天", "relative_time.today": "今天",
"remove_quote_hint.button_label": "了解",
"remove_quote_hint.message": "您能自 {icon} 選單完成此操作。",
"remove_quote_hint.title": "是否想要移除您的引用嘟文?",
"reply_indicator.attachments": "{count, plural, other {# 個附加檔案}}", "reply_indicator.attachments": "{count, plural, other {# 個附加檔案}}",
"reply_indicator.cancel": "取消", "reply_indicator.cancel": "取消",
"reply_indicator.poll": "投票", "reply_indicator.poll": "投票",

View File

@ -1,10 +0,0 @@
# frozen_string_literal: true
module AccessGrantExtension
extend ActiveSupport::Concern
included do
scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') }
scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) }
end
end

View File

@ -1,29 +0,0 @@
# frozen_string_literal: true
module AccessTokenExtension
extend ActiveSupport::Concern
included do
include Redisable
has_many :web_push_subscriptions, class_name: 'Web::PushSubscription', inverse_of: :access_token
after_commit :push_to_streaming_api
scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') }
scope :not_revoked, -> { where(revoked_at: nil) }
scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) }
end
def revoke(clock = Time)
update(revoked_at: clock.now.utc)
end
def update_last_used(request, clock = Time)
update(last_used_at: clock.now.utc, last_used_ip: request.remote_ip)
end
def push_to_streaming_api
redis.publish("timeline:access_token:#{id}", Oj.dump(event: :kill)) if revoked? || destroyed?
end
end

View File

@ -1,49 +0,0 @@
# frozen_string_literal: true
module ApplicationExtension
extend ActiveSupport::Concern
APP_NAME_LIMIT = 60
APP_REDIRECT_URI_LIMIT = 2_000
APP_WEBSITE_LIMIT = 2_000
included do
include Redisable
has_many :created_users, class_name: 'User', foreign_key: 'created_by_application_id', inverse_of: :created_by_application
validates :name, length: { maximum: APP_NAME_LIMIT }
validates :redirect_uri, length: { maximum: APP_REDIRECT_URI_LIMIT }
validates :website, url: true, length: { maximum: APP_WEBSITE_LIMIT }, if: :website?
# The relationship used between Applications and AccessTokens is using
# dependent: delete_all, which means the ActiveRecord callback in
# AccessTokenExtension is not run, so instead we manually announce to
# streaming that these tokens are being deleted.
before_destroy :close_streaming_sessions, prepend: true
end
def confirmation_redirect_uri
redirect_uri.lines.first.strip
end
def redirect_uris
# Doorkeeper stores the redirect_uri value as a newline delimeted list in
# the database:
redirect_uri.split
end
def close_streaming_sessions(resource_owner = nil)
# TODO: #28793 Combine into a single topic
payload = Oj.dump(event: :kill)
scope = access_tokens
scope = scope.where(resource_owner_id: resource_owner.id) unless resource_owner.nil?
scope.in_batches do |tokens|
redis.pipelined do |pipeline|
tokens.ids.each do |id|
pipeline.publish("timeline:access_token:#{id}", payload)
end
end
end
end
end

View File

@ -9,12 +9,12 @@ class Vacuum::AccessTokensVacuum
private private
def vacuum_revoked_access_tokens! def vacuum_revoked_access_tokens!
Doorkeeper::AccessToken.expired.in_batches.delete_all OAuth::AccessToken.expired.in_batches.delete_all
Doorkeeper::AccessToken.revoked.in_batches.delete_all OAuth::AccessToken.revoked.in_batches.delete_all
end end
def vacuum_revoked_access_grants! def vacuum_revoked_access_grants!
Doorkeeper::AccessGrant.expired.in_batches.delete_all OAuth::AccessGrant.expired.in_batches.delete_all
Doorkeeper::AccessGrant.revoked.in_batches.delete_all OAuth::AccessGrant.revoked.in_batches.delete_all
end end
end end

7
app/models/oauth.rb Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module OAuth
def self.table_name_prefix
'oauth_'
end
end

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
class OAuth::AccessGrant < ApplicationRecord
include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant
scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') }
scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) }
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class OAuth::AccessToken < ApplicationRecord
include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
include Redisable
has_many :web_push_subscriptions, class_name: 'Web::PushSubscription', inverse_of: :access_token, dependent: nil
scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') }
scope :not_revoked, -> { where(revoked_at: nil) }
scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) }
after_commit :push_to_streaming_api
def revoke(clock = Time)
update(revoked_at: clock.now.utc)
end
def update_last_used(request, clock = Time)
update(last_used_at: clock.now.utc, last_used_ip: request.remote_ip)
end
private
def push_to_streaming_api
redis.publish("timeline:access_token:#{id}", Oj.dump(event: :kill)) if revoked? || destroyed?
end
end

View File

@ -0,0 +1,44 @@
# frozen_string_literal: true
class OAuth::Application < ApplicationRecord
include ::Doorkeeper::Orm::ActiveRecord::Mixins::Application
APP_NAME_LIMIT = 60
APP_REDIRECT_URI_LIMIT = 2_000
APP_WEBSITE_LIMIT = 2_000
include Redisable
has_many :created_users, class_name: 'User', foreign_key: :created_by_application_id, inverse_of: :created_by_application, dependent: nil
validates :name, length: { maximum: APP_NAME_LIMIT }
validates :redirect_uri, length: { maximum: APP_REDIRECT_URI_LIMIT }
validates :website, url: true, length: { maximum: APP_WEBSITE_LIMIT }, if: :website?
before_destroy :close_streaming_sessions, prepend: true
def confirmation_redirect_uri
redirect_uri.lines.first.strip
end
def redirect_uris
# The redirect_uri value is stored as a newline delimited list
redirect_uri.split
end
# The association between `Application` and `AccessToken` uses a setting of
# `dependent: delete_all` which means the callbacks in `AccessToken` are not
# run. Instead, announce to streaming that these tokens are being deleted.
def close_streaming_sessions(resource_owner = nil)
payload = Oj.dump(event: :kill)
scope = access_tokens
scope = scope.where(resource_owner_id: resource_owner.id) unless resource_owner.nil?
scope.in_batches do |tokens|
redis.pipelined do |pipeline|
tokens.ids.each do |id|
pipeline.publish("timeline:access_token:#{id}", payload)
end
end
end
end
end

View File

@ -32,7 +32,7 @@ class Report < ApplicationRecord
rate_limit by: :account, family: :reports rate_limit by: :account, family: :reports
belongs_to :account belongs_to :account
belongs_to :application, class_name: 'Doorkeeper::Application', optional: true belongs_to :application, class_name: 'OAuth::Application', optional: true
with_options class_name: 'Account' do with_options class_name: 'Account' do
belongs_to :target_account belongs_to :target_account

View File

@ -19,7 +19,7 @@ class SessionActivation < ApplicationRecord
include BrowserDetection include BrowserDetection
belongs_to :user, inverse_of: :session_activations belongs_to :user, inverse_of: :session_activations
belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', dependent: :destroy, optional: true belongs_to :access_token, class_name: 'OAuth::AccessToken', dependent: :destroy, optional: true
belongs_to :web_push_subscription, class_name: 'Web::PushSubscription', dependent: :destroy, optional: true belongs_to :web_push_subscription, class_name: 'Web::PushSubscription', dependent: :destroy, optional: true
delegate :token, delegate :token,
@ -61,12 +61,12 @@ class SessionActivation < ApplicationRecord
private private
def assign_access_token def assign_access_token
self.access_token = Doorkeeper::AccessToken.create!(access_token_attributes) self.access_token = OAuth::AccessToken.create!(access_token_attributes)
end end
def access_token_attributes def access_token_attributes
{ {
application_id: Doorkeeper::Application.find_by(superapp: true)&.id, application_id: OAuth::Application.find_by(superapp: true)&.id,
resource_owner_id: user_id, resource_owner_id: user_id,
scopes: DEFAULT_SCOPES.join(' '), scopes: DEFAULT_SCOPES.join(' '),
expires_in: Doorkeeper.configuration.access_token_expires_in, expires_in: Doorkeeper.configuration.access_token_expires_in,

View File

@ -58,7 +58,7 @@ class Status < ApplicationRecord
update_index('statuses', :proper) update_index('statuses', :proper)
update_index('public_statuses', :proper) update_index('public_statuses', :proper)
belongs_to :application, class_name: 'Doorkeeper::Application', optional: true belongs_to :application, class_name: 'OAuth::Application', optional: true
belongs_to :account, inverse_of: :statuses belongs_to :account, inverse_of: :statuses
belongs_to :in_reply_to_account, class_name: 'Account', optional: true belongs_to :in_reply_to_account, class_name: 'Account', optional: true

View File

@ -76,11 +76,11 @@ class User < ApplicationRecord
belongs_to :account, inverse_of: :user belongs_to :account, inverse_of: :user
belongs_to :invite, counter_cache: :uses, optional: true belongs_to :invite, counter_cache: :uses, optional: true
belongs_to :created_by_application, class_name: 'Doorkeeper::Application', optional: true belongs_to :created_by_application, class_name: 'OAuth::Application', optional: true
belongs_to :role, class_name: 'UserRole', optional: true belongs_to :role, class_name: 'UserRole', optional: true
accepts_nested_attributes_for :account accepts_nested_attributes_for :account
has_many :applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: nil has_many :applications, class_name: 'OAuth::Application', as: :owner, dependent: nil
has_many :backups, inverse_of: :user, dependent: nil has_many :backups, inverse_of: :user, dependent: nil
has_many :invites, inverse_of: :user, dependent: nil has_many :invites, inverse_of: :user, dependent: nil
has_many :login_activities, inverse_of: :user, dependent: :destroy has_many :login_activities, inverse_of: :user, dependent: :destroy
@ -273,7 +273,7 @@ class User < ApplicationRecord
end end
def applications_last_used def applications_last_used
Doorkeeper::AccessToken OAuth::AccessToken
.where(resource_owner_id: id) .where(resource_owner_id: id)
.where.not(last_used_at: nil) .where.not(last_used_at: nil)
.group(:application_id) .group(:application_id)
@ -284,7 +284,7 @@ class User < ApplicationRecord
def token_for_app(app) def token_for_app(app)
return nil if app.nil? || app.owner != self return nil if app.nil? || app.owner != self
Doorkeeper::AccessToken.find_or_create_by(application_id: app.id, resource_owner_id: id) do |t| OAuth::AccessToken.find_or_create_by(application_id: app.id, resource_owner_id: id) do |t|
t.scopes = app.scopes t.scopes = app.scopes
t.expires_in = Doorkeeper.configuration.access_token_expires_in t.expires_in = Doorkeeper.configuration.access_token_expires_in
t.use_refresh_token = Doorkeeper.configuration.refresh_token_enabled? t.use_refresh_token = Doorkeeper.configuration.refresh_token_enabled?
@ -338,9 +338,9 @@ class User < ApplicationRecord
end end
def revoke_access! def revoke_access!
Doorkeeper::AccessGrant.by_resource_owner(self).touch_all(:revoked_at) OAuth::AccessGrant.by_resource_owner(self).touch_all(:revoked_at)
Doorkeeper::AccessToken.by_resource_owner(self).in_batches do |batch| OAuth::AccessToken.by_resource_owner(self).in_batches do |batch|
batch.touch_all(:revoked_at) batch.touch_all(:revoked_at)
Web::PushSubscription.where(access_token_id: batch).delete_all Web::PushSubscription.where(access_token_id: batch).delete_all

View File

@ -18,7 +18,7 @@
class Web::PushSubscription < ApplicationRecord class Web::PushSubscription < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :access_token, class_name: 'Doorkeeper::AccessToken' belongs_to :access_token, class_name: 'OAuth::AccessToken'
has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription, dependent: nil has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription, dependent: nil
@ -42,7 +42,7 @@ class Web::PushSubscription < ApplicationRecord
class << self class << self
def unsubscribe_for(application_id, resource_owner) def unsubscribe_for(application_id, resource_owner)
access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id).not_revoked.pluck(:id) access_token_ids = OAuth::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id).not_revoked.pluck(:id)
where(access_token_id: access_token_ids).delete_all where(access_token_id: access_token_ids).delete_all
end end
end end

View File

@ -27,7 +27,7 @@ class AppSignUpService < BaseService
end end
def create_access_token! def create_access_token!
@access_token = Doorkeeper::AccessToken.create!( @access_token = OAuth::AccessToken.create!(
application: @app, application: @app,
resource_owner_id: @user.id, resource_owner_id: @user.id,
scopes: @app.scopes, scopes: @app.scopes,

View File

@ -27,7 +27,7 @@ class PostStatusService < BaseService
# @option [String] :scheduled_at # @option [String] :scheduled_at
# @option [Hash] :poll Optional poll to attach # @option [Hash] :poll Optional poll to attach
# @option [Enumerable] :media_ids Optional array of media IDs to attach # @option [Enumerable] :media_ids Optional array of media IDs to attach
# @option [Doorkeeper::Application] :application # @option [OAuth::Application] :application
# @option [String] :idempotency Optional idempotency key # @option [String] :idempotency Optional idempotency key
# @option [Boolean] :with_rate_limit # @option [Boolean] :with_rate_limit
# @option [Enumerable] :allowed_mentions Optional array of expected mentioned account IDs, raises `UnexpectedMentionsError` if unexpected accounts end up in mentions # @option [Enumerable] :allowed_mentions Optional array of expected mentioned account IDs, raises `UnexpectedMentionsError` if unexpected accounts end up in mentions

View File

@ -21,7 +21,7 @@ class PublishScheduledStatusWorker
def options_with_objects(options) def options_with_objects(options)
options.tap do |options_hash| options.tap do |options_hash|
options_hash[:application] = Doorkeeper::Application.find(options_hash.delete(:application_id)) if options[:application_id] options_hash[:application] = OAuth::Application.find(options_hash.delete(:application_id)) if options[:application_id]
options_hash[:thread] = Status.find(options_hash.delete(:in_reply_to_id)) if options_hash[:in_reply_to_id] options_hash[:thread] = Status.find(options_hash.delete(:in_reply_to_id)) if options_hash[:in_reply_to_id]
end end
end end

View File

@ -20,7 +20,7 @@ class Scheduler::IpCleanupScheduler
SessionActivation.where(updated_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(ip: nil) SessionActivation.where(updated_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(ip: nil)
User.where(current_sign_in_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(sign_up_ip: nil) User.where(current_sign_in_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(sign_up_ip: nil)
LoginActivity.where(created_at: ...IP_RETENTION_PERIOD.ago).in_batches.destroy_all LoginActivity.where(created_at: ...IP_RETENTION_PERIOD.ago).in_batches.destroy_all
Doorkeeper::AccessToken.where(last_used_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(last_used_ip: nil) OAuth::AccessToken.where(last_used_at: ...IP_RETENTION_PERIOD.ago).in_batches.update_all(last_used_ip: nil)
end end
def clean_expired_ip_blocks! def clean_expired_ip_blocks!

View File

@ -117,9 +117,6 @@ module Mastodon
end end
config.to_prepare do config.to_prepare do
Doorkeeper::Application.include ApplicationExtension
Doorkeeper::AccessGrant.include AccessGrantExtension
Doorkeeper::AccessToken.include AccessTokenExtension
Devise::FailureApp.include AbstractController::Callbacks Devise::FailureApp.include AbstractController::Callbacks
Devise::FailureApp.include Localized Devise::FailureApp.include Localized
end end

View File

@ -4,6 +4,10 @@ Doorkeeper.configure do
# Change the ORM that doorkeeper will use (needs plugins) # Change the ORM that doorkeeper will use (needs plugins)
orm :active_record orm :active_record
access_grant_class 'OAuth::AccessGrant'
access_token_class 'OAuth::AccessToken'
application_class 'OAuth::Application'
# This block will be called to check whether the resource owner is authenticated or not. # This block will be called to check whether the resource owner is authenticated or not.
resource_owner_authenticator do resource_owner_authenticator do
current_user || redirect_to(new_user_session_url) current_user || redirect_to(new_user_session_url)

View File

@ -63,6 +63,7 @@ br:
all: Pep tra all: Pep tra
local: Lec'hel local: Lec'hel
remote: A-bell remote: A-bell
title: Lec'hiadur
media_attachments: Restroù media stag media_attachments: Restroù media stag
moderation: moderation:
active: Oberiant active: Oberiant
@ -180,6 +181,7 @@ br:
name: Anv name: Anv
registrations: registrations:
confirm: Kadarnaat confirm: Kadarnaat
save: Enrollañ
status: Statud status: Statud
follow_recommendations: follow_recommendations:
status: Statud status: Statud
@ -260,6 +262,7 @@ br:
title: Disklêriadennoù title: Disklêriadennoù
unresolved: Andiskoulmet unresolved: Andiskoulmet
updated_at: Nevesaet updated_at: Nevesaet
view_profile: Gwelet ar profil
roles: roles:
categories: categories:
devops: DevOps devops: DevOps
@ -287,6 +290,7 @@ br:
danger_zone: Takad dañjer danger_zone: Takad dañjer
discovery: discovery:
privacy: Buhez prevez privacy: Buhez prevez
profile_directory: Kavlec'h ar profiloù
title: Dizoloadur title: Dizoloadur
trends: Luskadoù trends: Luskadoù
domain_blocks: domain_blocks:
@ -310,6 +314,10 @@ br:
strikes: strikes:
actions: actions:
delete_statuses: Dilamet eo bet toudoù %{target} gant %{name} delete_statuses: Dilamet eo bet toudoù %{target} gant %{name}
tags:
title: Gerioù-klik
terms_of_service:
save_draft: Enrollañ ar brouilhed
trends: trends:
allow: Aotren allow: Aotren
approved: Aprouet approved: Aprouet
@ -324,7 +332,7 @@ br:
dashboard: dashboard:
tag_uses_measure: implijoù hollek tag_uses_measure: implijoù hollek
not_usable: N'haller ket en implijout not_usable: N'haller ket en implijout
title: Hashtagoù diouzh ar c'hiz title: Gerioù-klik diouzh ar c'hiz
warning_presets: warning_presets:
add_new: Ouzhpenniñ unan nevez add_new: Ouzhpenniñ unan nevez
delete: Dilemel delete: Dilemel
@ -342,7 +350,7 @@ br:
none: ur c'hemenn diwall none: ur c'hemenn diwall
new_trends: new_trends:
new_trending_tags: new_trending_tags:
title: Hashtagoù diouzh ar c'hiz title: Gerioù-klik diouzh ar c'hiz
appearance: appearance:
discovery: Dizoloadur discovery: Dizoloadur
localization: localization:
@ -350,6 +358,7 @@ br:
guide_link: https://crowdin.com/project/mastodon guide_link: https://crowdin.com/project/mastodon
application_mailer: application_mailer:
view: 'Sellet :' view: 'Sellet :'
view_profile: Gwelet ar profil
view_status: Gwelet ar c'hannad view_status: Gwelet ar c'hannad
auth: auth:
delete_account: Dilemel ar gont delete_account: Dilemel ar gont
@ -396,6 +405,8 @@ br:
created_at: Deiziad created_at: Deiziad
title_actions: title_actions:
none: Diwall none: Diwall
edit_profile:
other: All
emoji_styles: emoji_styles:
auto: Emgefreek auto: Emgefreek
twemoji: Twemoji twemoji: Twemoji
@ -422,6 +433,8 @@ br:
other: "%{count} a gannadoù" other: "%{count} a gannadoù"
two: "%{count} gannad" two: "%{count} gannad"
title: Siloù title: Siloù
new:
save: Enrollañ ar sil nevez
statuses: statuses:
index: index:
title: Toudoù silet title: Toudoù silet
@ -547,7 +560,7 @@ br:
back: Distreiñ da vMastodon back: Distreiñ da vMastodon
development: Diorren development: Diorren
edit_profile: Kemmañ ar profil edit_profile: Kemmañ ar profil
featured_tags: Hashtagoù pennañ featured_tags: Gerioù-klik pennañ
import: Enporzhiañ import: Enporzhiañ
import_and_export: Enporzhiañ hag ezporzhiañ import_and_export: Enporzhiañ hag ezporzhiañ
preferences: Gwellvezioù preferences: Gwellvezioù
@ -609,6 +622,9 @@ br:
edit_profile_title: Personelaat ho profil edit_profile_title: Personelaat ho profil
feature_action: Gouzout hiroc'h feature_action: Gouzout hiroc'h
follow_action: Heuliañ follow_action: Heuliañ
hashtags_title: Gerioù-klik diouzh ar c'hiz
hashtags_view_more: Gwelet muioc'h a c'herioù-klik diouzh ar c'hiz
share_title: Rannit ho kont Mastodon
sign_in_action: Kevreañ sign_in_action: Kevreañ
subject: Donemat e Mastodon subject: Donemat e Mastodon
title: Degemer mat e bourzh, %{name}! title: Degemer mat e bourzh, %{name}!

View File

@ -1894,6 +1894,9 @@ cy:
self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun
too_few_options: rhaid cael mwy nag un eitem too_few_options: rhaid cael mwy nag un eitem
too_many_options: ni all gynnwys mwy na %{max} eitem too_many_options: ni all gynnwys mwy na %{max} eitem
vote: Pleidleisio
posting_defaults:
explanation: Bydd y gosodiadau hyn yn cael eu defnyddio fel rhagosodiadau pan fyddwch chi'n creu postiadau newydd, ond gallwch chi eu golygu fesul postiad o fewn y cyfansoddwr.
preferences: preferences:
other: Arall other: Arall
posting_defaults: Rhagosodiadau postio posting_defaults: Rhagosodiadau postio

View File

@ -367,7 +367,7 @@ en:
title: Custom emojis title: Custom emojis
uncategorized: Uncategorized uncategorized: Uncategorized
unlist: Unlist unlist: Unlist
unlisted: Quiet public unlisted: Unlisted
update_failed_msg: Could not update that emoji update_failed_msg: Could not update that emoji
updated_msg: Emoji successfully updated! updated_msg: Emoji successfully updated!
upload: Upload upload: Upload
@ -1923,7 +1923,7 @@ en:
private_long: Only show to followers private_long: Only show to followers
public: Public public: Public
public_long: Anyone on and off Mastodon public_long: Anyone on and off Mastodon
unlisted: Unlisted unlisted: Quiet public
unlisted_long: Hidden from Mastodon search results, trending, and public timelines unlisted_long: Hidden from Mastodon search results, trending, and public timelines
statuses_cleanup: statuses_cleanup:
enabled: Automatically delete old posts enabled: Automatically delete old posts

View File

@ -2,6 +2,8 @@
br: br:
simple_form: simple_form:
hints: hints:
account:
note: 'Gallout a rit @menegiñ tud all pe #gerioù-klik.'
defaults: defaults:
avatar: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px avatar: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
header: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px header: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
@ -56,7 +58,7 @@ br:
username: Anv username: Anv
whole_word: Ger a-bezh whole_word: Ger a-bezh
featured_tag: featured_tag:
name: Hashtag name: Ger-klik
invite: invite:
comment: Evezhiadenn comment: Evezhiadenn
invite_request: invite_request:
@ -71,8 +73,8 @@ br:
hint: Titouroù ouzhpenn hint: Titouroù ouzhpenn
text: Reolenn text: Reolenn
tag: tag:
name: Hashtag name: Ger-klik
trendable: Aotren an hashtag-mañ da zont war wel dindan tuadurioù trendable: Aotren ar ger-klik-mañ da zont war wel dindan tuadurioù
user: user:
role: Roll role: Roll
time_zone: Gwerzhid eur time_zone: Gwerzhid eur

View File

@ -1,3 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
Doorkeeper::Application.create_with(name: 'Web', redirect_uri: Doorkeeper.configuration.native_redirect_uri, scopes: 'read write follow push').find_or_create_by(superapp: true) OAuth::Application.create_with(name: 'Web', redirect_uri: Doorkeeper.configuration.native_redirect_uri, scopes: 'read write follow push').find_or_create_by(superapp: true)

View File

@ -134,12 +134,12 @@ namespace :tests do
exit(1) exit(1)
end end
unless Doorkeeper::Application.find(2)[:scopes] == 'write:accounts profile' unless OAuth::Application.find(2)[:scopes] == 'write:accounts profile'
puts 'Application OAuth scopes not rewritten as expected' puts 'Application OAuth scopes not rewritten as expected'
exit(1) exit(1)
end end
unless Doorkeeper::Application.find(2).access_tokens.first[:scopes] == 'write:accounts profile' unless OAuth::Application.find(2).access_tokens.first[:scopes] == 'write:accounts profile'
puts 'OAuth access token scopes not rewritten as expected' puts 'OAuth access token scopes not rewritten as expected'
exit(1) exit(1)
end end

View File

@ -5,7 +5,7 @@ require 'rails_helper'
RSpec.describe OAuth::AuthorizationsController do RSpec.describe OAuth::AuthorizationsController do
render_views render_views
let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') } let(:app) { OAuth::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') }
describe 'GET #new' do describe 'GET #new' do
subject do subject do
@ -34,7 +34,7 @@ RSpec.describe OAuth::AuthorizationsController do
context 'when app is already authorized' do context 'when app is already authorized' do
before do before do
Doorkeeper::AccessToken.find_or_create_for( OAuth::AccessToken.find_or_create_for(
application: app, application: app,
resource_owner: user.id, resource_owner: user.id,
scopes: app.scopes, scopes: app.scopes,

View File

@ -55,7 +55,7 @@ RSpec.describe OAuth::AuthorizedApplicationsController do
it 'revokes access tokens for the application and removes subscriptions and sends kill payload to streaming' do it 'revokes access tokens for the application and removes subscriptions and sends kill payload to streaming' do
post :destroy, params: { id: application.id } post :destroy, params: { id: application.id }
expect(Doorkeeper::AccessToken.where(application: application).first.revoked_at) expect(OAuth::AccessToken.where(application: application).first.revoked_at)
.to_not be_nil .to_not be_nil
expect(Web::PushSubscription.where(user: user).count) expect(Web::PushSubscription.where(user: user).count)
.to eq(0) .to eq(0)

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
Fabricator :access_grant, from: 'Doorkeeper::AccessGrant' do Fabricator :access_grant, from: OAuth::AccessGrant do
application application
resource_owner_id { Fabricate(:user).id } resource_owner_id { Fabricate(:user).id }
expires_in 3_600 expires_in 3_600

View File

@ -1,3 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
Fabricator :access_token, from: 'Doorkeeper::AccessToken' Fabricator :access_token, from: OAuth::AccessToken

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
Fabricator(:application, from: Doorkeeper::Application) do Fabricator(:application, from: OAuth::Application) do
name 'Example' name 'Example'
website 'http://example.com' website 'http://example.com'
redirect_uri 'http://example.com/callback' redirect_uri 'http://example.com/callback'

View File

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Doorkeeper::AccessGrant do RSpec.describe OAuth::AccessGrant do
describe 'Validations' do describe 'Validations' do
subject { Fabricate :access_grant } subject { Fabricate :access_grant }

View File

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Doorkeeper::AccessToken do RSpec.describe OAuth::AccessToken do
describe 'Associations' do describe 'Associations' do
it { is_expected.to have_many(:web_push_subscriptions).class_name('Web::PushSubscription').inverse_of(:access_token) } it { is_expected.to have_many(:web_push_subscriptions).class_name('Web::PushSubscription').inverse_of(:access_token) }
end end

View File

@ -2,7 +2,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Doorkeeper::Application do RSpec.describe OAuth::Application do
describe 'Associations' do describe 'Associations' do
it { is_expected.to have_many(:created_users).class_name('User').inverse_of(:created_by_application).with_foreign_key(:created_by_application_id) } it { is_expected.to have_many(:created_users).class_name('User').inverse_of(:created_by_application).with_foreign_key(:created_by_application_id) }
end end

View File

@ -345,7 +345,7 @@ RSpec.describe User do
it 'creates and returns a persisted token' do it 'creates and returns a persisted token' do
expect { user.token_for_app(app) } expect { user.token_for_app(app) }
.to change(Doorkeeper::AccessToken.where(resource_owner_id: user.id, application: app), :count).by(1) .to change(OAuth::AccessToken.where(resource_owner_id: user.id, application: app), :count).by(1)
end end
end end
@ -355,7 +355,7 @@ RSpec.describe User do
it 'returns a persisted token' do it 'returns a persisted token' do
expect(user.token_for_app(app)) expect(user.token_for_app(app))
.to be_a(Doorkeeper::AccessToken) .to be_a(OAuth::AccessToken)
.and eq(token) .and eq(token)
end end
end end
@ -437,7 +437,7 @@ RSpec.describe User do
end end
def remove_active_user_tokens def remove_active_user_tokens
change { Doorkeeper::AccessToken.active_for(user).count }.to(0) change { OAuth::AccessToken.active_for(user).count }.to(0)
end end
def remove_user_web_subscriptions def remove_user_web_subscriptions

View File

@ -31,7 +31,7 @@ RSpec.describe 'Apps' do
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name) app = OAuth::Application.find_by(name: client_name)
expect(app).to be_present expect(app).to be_present
expect(app.scopes.to_s).to eq scopes expect(app.scopes.to_s).to eq scopes
@ -64,7 +64,7 @@ RSpec.describe 'Apps' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
expect(Doorkeeper::Application.find_by(name: client_name)).to be_present expect(OAuth::Application.find_by(name: client_name)).to be_present
expect(response.parsed_body) expect(response.parsed_body)
.to include( .to include(
@ -84,7 +84,7 @@ RSpec.describe 'Apps' do
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name) app = OAuth::Application.find_by(name: client_name)
expect(app).to be_present expect(app).to be_present
expect(app.scopes.to_s).to eq 'read' expect(app.scopes.to_s).to eq 'read'
@ -117,12 +117,12 @@ RSpec.describe 'Apps' do
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read' expect(OAuth::Application.find_by(name: client_name).scopes.to_s).to eq 'read'
end end
end end
context 'with a too-long name' do context 'with a too-long name' do
let(:client_name) { 'a' * Doorkeeper::Application::APP_NAME_LIMIT * 2 } let(:client_name) { 'a' * OAuth::Application::APP_NAME_LIMIT * 2 }
it 'returns http unprocessable entity' do it 'returns http unprocessable entity' do
subject subject
@ -134,7 +134,7 @@ RSpec.describe 'Apps' do
end end
context 'with a too-long website' do context 'with a too-long website' do
let(:website) { "https://foo.bar/#{'a' * Doorkeeper::Application::APP_WEBSITE_LIMIT * 2}" } let(:website) { "https://foo.bar/#{'a' * OAuth::Application::APP_WEBSITE_LIMIT * 2}" }
it 'returns http unprocessable entity' do it 'returns http unprocessable entity' do
subject subject
@ -146,7 +146,7 @@ RSpec.describe 'Apps' do
end end
context 'with a too-long redirect_uri' do context 'with a too-long redirect_uri' do
let(:redirect_uris) { "https://app.example/#{'a' * Doorkeeper::Application::APP_REDIRECT_URI_LIMIT * 2}" } let(:redirect_uris) { "https://app.example/#{'a' * OAuth::Application::APP_REDIRECT_URI_LIMIT * 2}" }
it 'returns http unprocessable entity' do it 'returns http unprocessable entity' do
subject subject
@ -180,7 +180,7 @@ RSpec.describe 'Apps' do
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name) app = OAuth::Application.find_by(name: client_name)
expect(app).to be_present expect(app).to be_present
expect(app.redirect_uri).to eq redirect_uris expect(app.redirect_uri).to eq redirect_uris
@ -204,7 +204,7 @@ RSpec.describe 'Apps' do
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name) app = OAuth::Application.find_by(name: client_name)
expect(app).to be_present expect(app).to be_present
expect(app.redirect_uri).to eq redirect_uris.join "\n" expect(app.redirect_uri).to eq redirect_uris.join "\n"
@ -276,7 +276,7 @@ RSpec.describe 'Apps' do
expect(response.content_type) expect(response.content_type)
.to start_with('application/json') .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name) app = OAuth::Application.find_by(name: client_name)
expect(app).to be_present expect(app).to be_present
expect(app.website).to eq website expect(app.website).to eq website

View File

@ -169,7 +169,7 @@ RSpec.describe 'Caching behavior' do
let(:alice) { Account.find_by(username: 'alice') } let(:alice) { Account.find_by(username: 'alice') }
let(:user) { User.find_by(email: 'user@host.example') } let(:user) { User.find_by(email: 'user@host.example') }
let(:token) { Doorkeeper::AccessToken.find_by(resource_owner_id: user.id) } let(:token) { OAuth::AccessToken.find_by(resource_owner_id: user.id) }
before_all do before_all do
alice = Fabricate(:account, username: 'alice') alice = Fabricate(:account, username: 'alice')

View File

@ -25,7 +25,7 @@ RSpec.describe 'Settings / Exports' do
let(:params) do let(:params) do
{ {
doorkeeper_application: { oauth_application: {
name: 'My New App', name: 'My New App',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
website: 'http://google.com', website: 'http://google.com',
@ -36,13 +36,13 @@ RSpec.describe 'Settings / Exports' do
it 'supports passing scope values as string' do it 'supports passing scope values as string' do
expect { subject } expect { subject }
.to change(Doorkeeper::Application, :count).by(1) .to change(OAuth::Application, :count).by(1)
expect(response) expect(response)
.to redirect_to(settings_applications_path) .to redirect_to(settings_applications_path)
end end
it 'gracefully handles invalid nested params' do it 'gracefully handles invalid nested params' do
post settings_applications_path(doorkeeper_application: 'invalid') post settings_applications_path(oauth_application: 'invalid')
expect(response) expect(response)
.to have_http_status(400) .to have_http_status(400)
@ -53,7 +53,7 @@ RSpec.describe 'Settings / Exports' do
let(:application) { Fabricate :application, owner: user } let(:application) { Fabricate :application, owner: user }
it 'gracefully handles invalid nested params' do it 'gracefully handles invalid nested params' do
put settings_application_path(application.id, doorkeeper_application: 'invalid') put settings_application_path(application.id, oauth_application: 'invalid')
expect(response) expect(response)
.to have_http_status(400) .to have_http_status(400)

View File

@ -68,7 +68,7 @@ RSpec.describe 'Auth Passwords' do
end end
def user_token_count def user_token_count
Doorkeeper::AccessToken OAuth::AccessToken
.active_for(user) .active_for(user)
.count .count
end end

View File

@ -7,7 +7,7 @@ RSpec.describe 'Using OAuth from an external app' do
subject { visit "/oauth/authorize?#{params.to_query}" } subject { visit "/oauth/authorize?#{params.to_query}" }
let(:client_app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: about_url(host: Rails.application.config.x.local_domain), scopes: 'read') } let(:client_app) { OAuth::Application.create!(name: 'test', redirect_uri: about_url(host: Rails.application.config.x.local_domain), scopes: 'read') }
let(:params) do let(:params) do
{ client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' }
end end
@ -264,7 +264,7 @@ RSpec.describe 'Using OAuth from an external app' do
end end
def user_has_grant_with_client_app? def user_has_grant_with_client_app?
Doorkeeper::AccessGrant OAuth::AccessGrant
.exists?( .exists?(
application: client_app, application: client_app,
resource_owner_id: user.id resource_owner_id: user.id

View File

@ -34,7 +34,7 @@ RSpec.describe 'Settings applications page' do
fill_in_form fill_in_form
expect { submit_form } expect { submit_form }
.to change(Doorkeeper::Application, :count).by(1) .to change(OAuth::Application, :count).by(1)
expect(page) expect(page)
.to have_content(I18n.t('doorkeeper.applications.index.title')) .to have_content(I18n.t('doorkeeper.applications.index.title'))
.and have_content('My new app') .and have_content('My new app')
@ -47,7 +47,7 @@ RSpec.describe 'Settings applications page' do
visit new_settings_application_path visit new_settings_application_path
expect { submit_form } expect { submit_form }
.to not_change(Doorkeeper::Application, :count) .to not_change(OAuth::Application, :count)
expect(page) expect(page)
.to have_content("can't be blank") .to have_content("can't be blank")
end end
@ -60,9 +60,9 @@ RSpec.describe 'Settings applications page' do
fill_in I18n.t('activerecord.attributes.doorkeeper/application.redirect_uri'), fill_in I18n.t('activerecord.attributes.doorkeeper/application.redirect_uri'),
with: 'urn:ietf:wg:oauth:2.0:oob' with: 'urn:ietf:wg:oauth:2.0:oob'
check 'read', id: :doorkeeper_application_scopes_read check 'read', id: :oauth_application_scopes_read
check 'write', id: :doorkeeper_application_scopes_write check 'write', id: :oauth_application_scopes_write
check 'follow', id: :doorkeeper_application_scopes_follow check 'follow', id: :oauth_application_scopes_follow
end end
def submit_form def submit_form
@ -76,12 +76,12 @@ RSpec.describe 'Settings applications page' do
fill_in form_app_name_label, fill_in form_app_name_label,
with: 'My new app name with a new value' with: 'My new app name with a new value'
check 'push', id: :doorkeeper_application_scopes_push check 'push', id: :oauth_application_scopes_push
submit_form submit_form
expect(page) expect(page)
.to have_content('My new app name with a new value') .to have_content('My new app name with a new value')
.and have_checked_field('push', id: :doorkeeper_application_scopes_push) .and have_checked_field('push', id: :oauth_application_scopes_push)
end end
it 'does not update with wrong values' do it 'does not update with wrong values' do
@ -110,7 +110,7 @@ RSpec.describe 'Settings applications page' do
visit settings_applications_path visit settings_applications_path
expect { destroy_application } expect { destroy_application }
.to change(Doorkeeper::Application, :count).by(-1) .to change(OAuth::Application, :count).by(-1)
expect(page) expect(page)
.to have_no_content(application.name) .to have_no_content(application.name)
expect(redis_pipeline_stub) expect(redis_pipeline_stub)