Browse Source

Merge branch 'asonix/changes' into v2.9.0rc1-branch

Arlo (Hyena) 2 weeks ago
parent
commit
d4a7fdeec5
59 changed files with 6511 additions and 28 deletions
  1. 1
    0
      .gitignore
  2. 1
    0
      .node-version
  3. 1
    0
      app/controllers/auth/registrations_controller.rb
  4. 1
    0
      app/controllers/settings/preferences_controller.rb
  5. 3
    0
      app/helpers/settings_helper.rb
  6. 11
    0
      app/helpers/stream_entries_helper.rb
  7. 4
    1
      app/javascript/mastodon/components/status_content.js
  8. 1
    0
      app/javascript/mastodon/initial_state.js
  9. 388
    0
      app/javascript/mastodon/locales/dog.json
  10. 388
    0
      app/javascript/mastodon/locales/lion.json
  11. 115
    0
      app/javascript/mastodon/locales/locale-data/dog.js
  12. 115
    0
      app/javascript/mastodon/locales/locale-data/lion.js
  13. 115
    0
      app/javascript/mastodon/locales/locale-data/squeak.js
  14. 388
    0
      app/javascript/mastodon/locales/squeak.json
  15. 2
    0
      app/javascript/mastodon/locales/whitelist_dog.json
  16. 2
    0
      app/javascript/mastodon/locales/whitelist_lion.json
  17. 2
    0
      app/javascript/mastodon/locales/whitelist_squeak.json
  18. 2
    0
      app/javascript/styles/contrast-wider.scss
  19. 2
    0
      app/javascript/styles/mastodon-light-wider.scss
  20. 2
    0
      app/javascript/styles/mastodon-wider.scss
  21. 172
    5
      app/javascript/styles/mastodon/components.scss
  22. 2
    0
      app/javascript/styles/pop-light-wider.scss
  23. 55
    0
      app/javascript/styles/pop-light.scss
  24. 2
    0
      app/javascript/styles/pop-wider.scss
  25. 28
    0
      app/javascript/styles/pop.scss
  26. 2
    0
      app/javascript/styles/werefox-wider.scss
  27. 28
    0
      app/javascript/styles/werefox.scss
  28. 4
    0
      app/javascript/styles/wide.scss
  29. 19
    0
      app/lib/activitypub/activity/create.rb
  30. 135
    1
      app/lib/formatter.rb
  31. 7
    4
      app/lib/sanitize_config.rb
  32. 5
    0
      app/lib/user_settings_decorator.rb
  33. 1
    1
      app/models/user.rb
  34. 11
    10
      app/serializers/initial_state_serializer.rb
  35. 5
    0
      app/serializers/rest/preferences_serializer.rb
  36. 1
    1
      app/views/stream_entries/_detailed_status.html.haml
  37. 1
    1
      app/views/stream_entries/_simple_status.html.haml
  38. 3
    0
      config/application.rb
  39. 9
    0
      config/initializers/source.rb
  40. 17
    0
      config/locales/activerecord.dog.yml
  41. 17
    0
      config/locales/activerecord.lion.yml
  42. 17
    0
      config/locales/activerecord.squeak.yml
  43. 86
    0
      config/locales/devise.dog.yml
  44. 86
    0
      config/locales/devise.lion.yml
  45. 86
    0
      config/locales/devise.squeak.yml
  46. 1100
    0
      config/locales/dog.yml
  47. 142
    0
      config/locales/doorkeeper.dog.yml
  48. 142
    0
      config/locales/doorkeeper.lion.yml
  49. 142
    0
      config/locales/doorkeeper.squeak.yml
  50. 7
    0
      config/locales/en.yml
  51. 1100
    0
      config/locales/lion.yml
  52. 140
    0
      config/locales/simple_form.dog.yml
  53. 1
    0
      config/locales/simple_form.en.yml
  54. 140
    0
      config/locales/simple_form.lion.yml
  55. 140
    0
      config/locales/simple_form.squeak.yml
  56. 1100
    0
      config/locales/squeak.yml
  57. 2
    1
      config/settings.yml
  58. 10
    1
      config/themes.yml
  59. 2
    2
      lib/mastodon/version.rb

+ 1
- 0
.gitignore View File

@@ -58,3 +58,4 @@ yarn-debug.log
58 58
 # Ignore Docker option files
59 59
 docker-compose.override.yml
60 60
 
61
+public.tar.gz

+ 1
- 0
.node-version View File

@@ -0,0 +1 @@
1
+10.15.3

+ 1
- 0
app/controllers/auth/registrations_controller.rb View File

@@ -33,6 +33,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
33 33
     resource.agreement          = true
34 34
     resource.current_sign_in_ip = request.remote_ip
35 35
 
36
+    resource.current_sign_in_ip = request.remote_ip if resource.current_sign_in_ip.nil?
36 37
     resource.build_account if resource.account.nil?
37 38
   end
38 39
 

+ 1
- 0
app/controllers/settings/preferences_controller.rb View File

@@ -54,6 +54,7 @@ class Settings::PreferencesController < Settings::BaseController
54 54
       :setting_aggregate_reblogs,
55 55
       :setting_show_application,
56 56
       :setting_advanced_layout,
57
+      :setting_strip_formatting,
57 58
       notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account),
58 59
       interactions: %i(must_be_follower must_be_following must_be_following_dm)
59 60
     )

+ 3
- 0
app/helpers/settings_helper.rb View File

@@ -2,6 +2,9 @@
2 2
 
3 3
 module SettingsHelper
4 4
   HUMAN_LOCALES = {
5
+    squeak: 'Squeak',
6
+    dog: 'Dog',
7
+    lion: 'Lion',
5 8
     en: 'English',
6 9
     ar: 'العربية',
7 10
     ast: 'Asturianu',

+ 11
- 0
app/helpers/stream_entries_helper.rb View File

@@ -140,6 +140,17 @@ module StreamEntriesHelper
140 140
     end
141 141
   end
142 142
 
143
+  def text_formatting_classes
144
+    case current_user&.setting_strip_formatting
145
+    when 'none', nil
146
+      'rich-text rich-blocks'
147
+    when 'blocks'
148
+      'rich-text'
149
+    when 'all'
150
+      nil
151
+    end
152
+  end
153
+
143 154
   def style_classes(status, is_predecessor, is_successor, include_threads)
144 155
     classes = ['entry']
145 156
     classes << 'entry-predecessor' if is_predecessor

+ 4
- 1
app/javascript/mastodon/components/status_content.js View File

@@ -7,6 +7,7 @@ import Permalink from './permalink';
7 7
 import classnames from 'classnames';
8 8
 import PollContainer from 'mastodon/containers/poll_container';
9 9
 import Icon from 'mastodon/components/icon';
10
+import { stripFormatting } from 'mastodon/initial_state';
10 11
 
11 12
 const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
12 13
 
@@ -154,6 +155,8 @@ export default class StatusContent extends React.PureComponent {
154 155
       'status__content--with-action': this.props.onClick && this.context.router,
155 156
       'status__content--with-spoiler': status.get('spoiler_text').length > 0,
156 157
       'status__content--collapsed': this.state.collapsed === true,
158
+      'rich-text': stripFormatting !== 'all',
159
+      'rich-blocks': stripFormatting === 'none',
157 160
     });
158 161
 
159 162
     if (isRtl(status.get('search_index'))) {
@@ -225,7 +228,7 @@ export default class StatusContent extends React.PureComponent {
225 228
         <div
226 229
           tabIndex='0'
227 230
           ref={this.setRef}
228
-          className='status__content'
231
+          className={classNames}
229 232
           style={directionStyle}
230 233
           dangerouslySetInnerHTML={content}
231 234
           lang={status.get('language')}

+ 1
- 0
app/javascript/mastodon/initial_state.js View File

@@ -20,5 +20,6 @@ export const mascot = getMeta('mascot');
20 20
 export const profile_directory = getMeta('profile_directory');
21 21
 export const isStaff = getMeta('is_staff');
22 22
 export const forceSingleColumn = !getMeta('advanced_layout');
23
+export const stripFormatting = getMeta('strip_formatting');
23 24
 
24 25
 export default initialState;

+ 388
- 0
app/javascript/mastodon/locales/dog.json View File

@@ -0,0 +1,388 @@
1
+{
2
+  "account.add_or_remove_from_list": "Add or Remove from lists",
3
+  "account.badges.bot": "Bot",
4
+  "account.block": "Block @{name}",
5
+  "account.block_domain": "Hide everything from {domain}",
6
+  "account.blocked": "Blocked",
7
+  "account.direct": "Direct message @{name}",
8
+  "account.domain_blocked": "Domain hidden",
9
+  "account.edit_profile": "Edit profile",
10
+  "account.endorse": "Feature on profile",
11
+  "account.follow": "Join Pack",
12
+  "account.followers": "Pack Members",
13
+  "account.followers.empty": "No one follows this dog yet.",
14
+  "account.follows": "Joined Packs",
15
+  "account.follows.empty": "This dog doesn't follow anyone yet.",
16
+  "account.follows_you": "In your pack",
17
+  "account.hide_reblogs": "Hide awoos from @{name}",
18
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
19
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
20
+  "account.media": "Media",
21
+  "account.mention": "Bark at @{name}",
22
+  "account.moved_to": "{name} has moved to:",
23
+  "account.mute": "Mute @{name}",
24
+  "account.mute_notifications": "Mute notifications from @{name}",
25
+  "account.muted": "Muted",
26
+  "account.posts": "Toots",
27
+  "account.posts_with_replies": "Toots with barks",
28
+  "account.report": "Report @{name}",
29
+  "account.requested": "Awaiting approval. Click to cancel pack request",
30
+  "account.share": "Share @{name}'s profile",
31
+  "account.show_reblogs": "Show awoos from @{name}",
32
+  "account.unblock": "Unblock @{name}",
33
+  "account.unblock_domain": "Unhide {domain}",
34
+  "account.unendorse": "Don't feature on profile",
35
+  "account.unfollow": "Leave Pack",
36
+  "account.unmute": "Unmute @{name}",
37
+  "account.unmute_notifications": "Unmute notifications from @{name}",
38
+  "alert.unexpected.message": "An unexpected error occurred.",
39
+  "alert.unexpected.title": "Oops!",
40
+  "boost_modal.combo": "You can press {combo} to skip this next time",
41
+  "bundle_column_error.body": "Something went wrong while loading this component.",
42
+  "bundle_column_error.retry": "Try again",
43
+  "bundle_column_error.title": "Network error",
44
+  "bundle_modal_error.close": "Close",
45
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
46
+  "bundle_modal_error.retry": "Try again",
47
+  "column.blocks": "Blocked dogs",
48
+  "column.community": "Local timeline",
49
+  "column.direct": "Direct messages",
50
+  "column.domain_blocks": "Hidden domains",
51
+  "column.favourites": "Boops",
52
+  "column.follow_requests": "Pack requests",
53
+  "column.home": "Home",
54
+  "column.lists": "Lists",
55
+  "column.mutes": "Muted dogs",
56
+  "column.notifications": "Notifications",
57
+  "column.pins": "Pinned toots",
58
+  "column.public": "Federated timeline",
59
+  "column_back_button.label": "Back",
60
+  "column_header.hide_settings": "Hide settings",
61
+  "column_header.moveLeft_settings": "Move column to the left",
62
+  "column_header.moveRight_settings": "Move column to the right",
63
+  "column_header.pin": "Pin",
64
+  "column_header.show_settings": "Show settings",
65
+  "column_header.unpin": "Unpin",
66
+  "column_subheading.settings": "Settings",
67
+  "community.column_settings.media_only": "Media Only",
68
+  "compose_form.direct_message_warning": "This toot will only be sent to the mentioned dogs.",
69
+  "compose_form.direct_message_warning_learn_more": "Learn more",
70
+  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
71
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can join your pack to view your pack-only posts.",
72
+  "compose_form.lock_disclaimer.lock": "locked",
73
+  "compose_form.placeholder": "Bark???",
74
+  "compose_form.poll.add_option": "Add a choice",
75
+  "compose_form.poll.duration": "Poll duration",
76
+  "compose_form.poll.option_placeholder": "Choice {number}",
77
+  "compose_form.poll.remove_option": "Remove this choice",
78
+  "compose_form.publish": "Toot",
79
+  "compose_form.publish_loud": "{publish}!",
80
+  "compose_form.sensitive.hide": "Mark media as sensitive",
81
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
82
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
83
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
84
+  "compose_form.spoiler.unmarked": "Text is not hidden",
85
+  "compose_form.spoiler_placeholder": "Write your warning here",
86
+  "confirmation_modal.cancel": "Cancel",
87
+  "confirmations.block.block_and_report": "Block & Report",
88
+  "confirmations.block.confirm": "Block",
89
+  "confirmations.block.message": "Are you sure you want to block {name}?",
90
+  "confirmations.delete.confirm": "Delete",
91
+  "confirmations.delete.message": "Are you sure you want to delete this toot?",
92
+  "confirmations.delete_list.confirm": "Delete",
93
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
94
+  "confirmations.domain_block.confirm": "Hide entire domain",
95
+  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
96
+  "confirmations.mute.confirm": "Mute",
97
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
98
+  "confirmations.redraft.confirm": "Delete & redraft",
99
+  "confirmations.redraft.message": "Are you sure you want to delete this toot and re-draft it? Boops and awoos will be lost, and barks at the original post will be orphaned.",
100
+  "confirmations.reply.confirm": "Bark",
101
+  "confirmations.reply.message": "Barking now will overwrite the toot you are currently composing. Are you sure you want to proceed?",
102
+  "confirmations.unfollow.confirm": "Leave Pack",
103
+  "confirmations.unfollow.message": "Are you sure you want to leave {name}'s pack?",
104
+  "embed.instructions": "Embed this toot on your website by copying the code below.",
105
+  "embed.preview": "Here is what it will look like:",
106
+  "emoji_button.activity": "Activity",
107
+  "emoji_button.custom": "Custom",
108
+  "emoji_button.flags": "Flags",
109
+  "emoji_button.food": "Food & Drink",
110
+  "emoji_button.label": "Insert emoji",
111
+  "emoji_button.nature": "Nature",
112
+  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
113
+  "emoji_button.objects": "Objects",
114
+  "emoji_button.people": "Dogs",
115
+  "emoji_button.recent": "Frequently used",
116
+  "emoji_button.search": "Search...",
117
+  "emoji_button.search_results": "Search results",
118
+  "emoji_button.symbols": "Symbols",
119
+  "emoji_button.travel": "Travel & Places",
120
+  "empty_column.account_timeline": "No toots here!",
121
+  "empty_column.account_unavailable": "Profile unavailable",
122
+  "empty_column.blocks": "You haven't blocked any dogs yet.",
123
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
124
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
125
+  "empty_column.domain_blocks": "There are no hidden domains yet.",
126
+  "empty_column.favourited_statuses": "You don't have any booped toots yet. When you boop one, it will show up here.",
127
+  "empty_column.favourites": "No one has booped this toot yet. When someone does, they will show up here.",
128
+  "empty_column.follow_requests": "You don't have any pack requests yet. When you receive one, it will show up here.",
129
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
130
+  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other dogs.",
131
+  "empty_column.home.public_timeline": "the public timeline",
132
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
133
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
134
+  "empty_column.mutes": "You haven't muted any dogs yet.",
135
+  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
136
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow dogs from other instances to fill it up",
137
+  "follow_request.authorize": "Authorize",
138
+  "follow_request.reject": "Reject",
139
+  "getting_started.developers": "Developers",
140
+  "getting_started.directory": "Profile directory",
141
+  "getting_started.documentation": "Documentation",
142
+  "getting_started.heading": "Getting started",
143
+  "getting_started.invite": "Invite dogs",
144
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
145
+  "getting_started.security": "Security",
146
+  "getting_started.terms": "Terms of service",
147
+  "hashtag.column_header.tag_mode.all": "and {additional}",
148
+  "hashtag.column_header.tag_mode.any": "or {additional}",
149
+  "hashtag.column_header.tag_mode.none": "without {additional}",
150
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
151
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
152
+  "hashtag.column_settings.tag_mode.all": "All of these",
153
+  "hashtag.column_settings.tag_mode.any": "Any of these",
154
+  "hashtag.column_settings.tag_mode.none": "None of these",
155
+  "hashtag.column_settings.tag_toggle": "Include additional tags for this column",
156
+  "home.column_settings.basic": "Basic",
157
+  "home.column_settings.show_reblogs": "Show awoos",
158
+  "home.column_settings.show_replies": "Show barks",
159
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
160
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
161
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
162
+  "introduction.federation.action": "Next",
163
+  "introduction.federation.federated.headline": "Federated",
164
+  "introduction.federation.federated.text": "Public toots from other servers of the fediverse will appear in the federated timeline.",
165
+  "introduction.federation.home.headline": "Home",
166
+  "introduction.federation.home.text": "Toots from dogs you follow will appear in your home feed. You can follow anyone on any server!",
167
+  "introduction.federation.local.headline": "Local",
168
+  "introduction.federation.local.text": "Public toots from dogs on the same server as you will appear in the local timeline.",
169
+  "introduction.interactions.action": "Finish tutorial!",
170
+  "introduction.interactions.favourite.headline": "Boop",
171
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
172
+  "introduction.interactions.reblog.headline": "Awoo",
173
+  "introduction.interactions.reblog.text": "You can share other dogs' toots with your followers by awooing them.",
174
+  "introduction.interactions.reply.headline": "Bark",
175
+  "introduction.interactions.reply.text": "You can bark at other dogs' and your own toots, which will chain them together in a conversation.",
176
+  "introduction.welcome.action": "Let's go!",
177
+  "introduction.welcome.headline": "First steps",
178
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
179
+  "keyboard_shortcuts.back": "to navigate back",
180
+  "keyboard_shortcuts.blocked": "to open blocked dogs list",
181
+  "keyboard_shortcuts.boost": "to awoo",
182
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
183
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
184
+  "keyboard_shortcuts.description": "Description",
185
+  "keyboard_shortcuts.direct": "to open direct messages column",
186
+  "keyboard_shortcuts.down": "to move down in the list",
187
+  "keyboard_shortcuts.enter": "to open status",
188
+  "keyboard_shortcuts.favourite": "to boop",
189
+  "keyboard_shortcuts.favourites": "to open boops list",
190
+  "keyboard_shortcuts.federated": "to open federated timeline",
191
+  "keyboard_shortcuts.heading": "Keyboard shortcuts",
192
+  "keyboard_shortcuts.home": "to open home timeline",
193
+  "keyboard_shortcuts.hotkey": "Hotkey",
194
+  "keyboard_shortcuts.legend": "to display this legend",
195
+  "keyboard_shortcuts.local": "to open local timeline",
196
+  "keyboard_shortcuts.mention": "to mention author",
197
+  "keyboard_shortcuts.muted": "to open muted dogs list",
198
+  "keyboard_shortcuts.my_profile": "to open your profile",
199
+  "keyboard_shortcuts.notifications": "to open notifications column",
200
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
201
+  "keyboard_shortcuts.profile": "to open author's profile",
202
+  "keyboard_shortcuts.reply": "to bark",
203
+  "keyboard_shortcuts.requests": "to open pack requests list",
204
+  "keyboard_shortcuts.search": "to focus search",
205
+  "keyboard_shortcuts.start": "to open \"get started\" column",
206
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
207
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
208
+  "keyboard_shortcuts.toot": "to start a brand new toot",
209
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
210
+  "keyboard_shortcuts.up": "to move up in the list",
211
+  "lightbox.close": "Close",
212
+  "lightbox.next": "Next",
213
+  "lightbox.previous": "Previous",
214
+  "lightbox.view_context": "View context",
215
+  "lists.account.add": "Add to list",
216
+  "lists.account.remove": "Remove from list",
217
+  "lists.delete": "Delete list",
218
+  "lists.edit": "Edit list",
219
+  "lists.edit.submit": "Change title",
220
+  "lists.new.create": "Add list",
221
+  "lists.new.title_placeholder": "New list title",
222
+  "lists.search": "Search among dogs you follow",
223
+  "lists.subheading": "Your lists",
224
+  "loading_indicator.label": "Loading...",
225
+  "media_gallery.toggle_visible": "Toggle visibility",
226
+  "missing_indicator.label": "Not found",
227
+  "missing_indicator.sublabel": "This resource could not be found",
228
+  "mute_modal.hide_notifications": "Hide notifications from this dog?",
229
+  "navigation_bar.apps": "Mobile apps",
230
+  "navigation_bar.blocks": "Blocked dogs",
231
+  "navigation_bar.community_timeline": "Local timeline",
232
+  "navigation_bar.compose": "Compose new toot",
233
+  "navigation_bar.direct": "Direct messages",
234
+  "navigation_bar.discover": "Discover",
235
+  "navigation_bar.domain_blocks": "Hidden domains",
236
+  "navigation_bar.edit_profile": "Edit profile",
237
+  "navigation_bar.favourites": "Boops",
238
+  "navigation_bar.filters": "Muted words",
239
+  "navigation_bar.follow_requests": "Pack requests",
240
+  "navigation_bar.follows_and_followers": "Packs and Pack Members",
241
+  "navigation_bar.info": "About this server",
242
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
243
+  "navigation_bar.lists": "Lists",
244
+  "navigation_bar.logout": "Logout",
245
+  "navigation_bar.mutes": "Muted dogs",
246
+  "navigation_bar.personal": "Personal",
247
+  "navigation_bar.pins": "Pinned toots",
248
+  "navigation_bar.preferences": "Preferences",
249
+  "navigation_bar.profile_directory": "Dog directory",
250
+  "navigation_bar.public_timeline": "Federated timeline",
251
+  "navigation_bar.security": "Security",
252
+  "notification.favourite": "{name} booped your toot",
253
+  "notification.follow": "{name} joined your pack",
254
+  "notification.mention": "{name} barked at you",
255
+  "notification.poll": "A poll you have voted in has ended",
256
+  "notification.reblog": "{name} awooed your toot",
257
+  "notifications.clear": "Clear notifications",
258
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
259
+  "notifications.column_settings.alert": "Desktop notifications",
260
+  "notifications.column_settings.favourite": "Boops:",
261
+  "notifications.column_settings.follow": "New pack members:",
262
+  "notifications.column_settings.mention": "Barks:",
263
+  "notifications.column_settings.filter_bar.show": "Show",
264
+  "notifications.column_settings.follow": "New pack members:",
265
+  "notifications.column_settings.mention": "Barks:",
266
+  "notifications.column_settings.poll": "Poll results:",
267
+  "notifications.column_settings.push": "Push notifications",
268
+  "notifications.column_settings.reblog": "Awoos:",
269
+  "notifications.column_settings.show": "Show in column",
270
+  "notifications.column_settings.sound": "Play sound",
271
+  "notifications.filter.all": "All",
272
+  "notifications.filter.boosts": "Awoos",
273
+  "notifications.filter.favourites": "Boops",
274
+  "notifications.filter.follows": "Joined Packs",
275
+  "notifications.filter.mentions": "Barks",
276
+  "notifications.filter.polls": "Poll results",
277
+  "notifications.group": "{count} notifications",
278
+  "poll.closed": "Closed",
279
+  "poll.refresh": "Refresh",
280
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
281
+  "poll.vote": "Vote",
282
+  "poll_button.add_poll": "Add a poll",
283
+  "poll_button.remove_poll": "Remove poll",
284
+  "privacy.change": "Adjust status privacy",
285
+  "privacy.direct.long": "Post to mentioned dogs only",
286
+  "privacy.direct.short": "Direct",
287
+  "privacy.private.long": "Toot to followers only",
288
+  "privacy.private.short": "Pack Members-only",
289
+  "privacy.public.long": "Toot to public timelines",
290
+  "privacy.public.short": "Public",
291
+  "privacy.unlisted.long": "Do not toot to public timelines",
292
+  "privacy.unlisted.short": "Unlisted",
293
+  "regeneration_indicator.label": "Loading…",
294
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
295
+  "relative_time.days": "{number}d",
296
+  "relative_time.hours": "{number}h",
297
+  "relative_time.just_now": "now",
298
+  "relative_time.minutes": "{number}m",
299
+  "relative_time.seconds": "{number}s",
300
+  "reply_indicator.cancel": "Cancel",
301
+  "report.forward": "Forward to {target}",
302
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
303
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
304
+  "report.placeholder": "Additional comments",
305
+  "report.submit": "Submit",
306
+  "report.target": "Reporting {target}",
307
+  "search.placeholder": "Search",
308
+  "search_popout.search_format": "Advanced search format",
309
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, booped, awooed, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
310
+  "search_popout.tips.hashtag": "hashtag",
311
+  "search_popout.tips.status": "status",
312
+  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
313
+  "search_popout.tips.user": "dog",
314
+  "search_results.accounts": "Dogs",
315
+  "search_results.hashtags": "Hashtags",
316
+  "search_results.statuses": "Toots",
317
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
318
+  "status.admin_account": "Open moderation interface for @{name}",
319
+  "status.admin_status": "Open this status in the moderation interface",
320
+  "status.block": "Block @{name}",
321
+  "status.cancel_reblog_private": "Unawoo",
322
+  "status.cannot_reblog": "This toot cannot be awooed",
323
+  "status.copy": "Copy link to status",
324
+  "status.delete": "Delete",
325
+  "status.detailed_status": "Detailed conversation view",
326
+  "status.direct": "Direct message @{name}",
327
+  "status.embed": "Embed",
328
+  "status.favourite": "Boop",
329
+  "status.filtered": "Filtered",
330
+  "status.load_more": "Load more",
331
+  "status.media_hidden": "Media hidden",
332
+  "status.mention": "Bark at @{name}",
333
+  "status.more": "More",
334
+  "status.mute": "Mute @{name}",
335
+  "status.mute_conversation": "Mute conversation",
336
+  "status.open": "Expand this toot",
337
+  "status.pin": "Pin on profile",
338
+  "status.pinned": "Pinned toot",
339
+  "status.read_more": "Read more",
340
+  "status.reblog": "Awoo",
341
+  "status.reblog_private": "Awoo to original audience",
342
+  "status.reblogged_by": "{name} awooed",
343
+  "status.reblogs.empty": "No one has awooed this toot yet. When someone does, they will show up here.",
344
+  "status.redraft": "Delete & re-draft",
345
+  "status.reply": "Bark",
346
+  "status.replyAll": "Bark in thread",
347
+  "status.report": "Report @{name}",
348
+  "status.sensitive_warning": "Sensitive content",
349
+  "status.share": "Share",
350
+  "status.show_less": "Show less",
351
+  "status.show_less_all": "Show less for all",
352
+  "status.show_more": "Show more",
353
+  "status.show_more_all": "Show more for all",
354
+  "status.show_thread": "Show thread",
355
+  "status.unmute_conversation": "Unmute conversation",
356
+  "status.unpin": "Unpin from profile",
357
+  "suggestions.dismiss": "Dismiss suggestion",
358
+  "suggestions.header": "You might be interested in…",
359
+  "tabs_bar.federated_timeline": "Federated",
360
+  "tabs_bar.home": "Home",
361
+  "tabs_bar.local_timeline": "Local",
362
+  "tabs_bar.notifications": "Notifications",
363
+  "tabs_bar.search": "Search",
364
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
365
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
366
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
367
+  "time_remaining.moments": "Moments remaining",
368
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
369
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
370
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
371
+  "upload_area.title": "Drag & drop to upload",
372
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
373
+  "upload_error.limit": "File upload limit exceeded.",
374
+  "upload_error.poll": "File upload not allowed with polls.",
375
+  "upload_form.description": "Describe for the visually impaired",
376
+  "upload_form.focus": "Change preview",
377
+  "upload_form.undo": "Delete",
378
+  "upload_progress.label": "Uploading...",
379
+  "video.close": "Close video",
380
+  "video.exit_fullscreen": "Exit full screen",
381
+  "video.expand": "Expand video",
382
+  "video.fullscreen": "Full screen",
383
+  "video.hide": "Hide video",
384
+  "video.mute": "Mute sound",
385
+  "video.pause": "Pause",
386
+  "video.play": "Play",
387
+  "video.unmute": "Unmute sound"
388
+}

+ 388
- 0
app/javascript/mastodon/locales/lion.json View File

@@ -0,0 +1,388 @@
1
+{
2
+  "account.add_or_remove_from_list": "Add or Remove from lists",
3
+  "account.badges.bot": "Bot",
4
+  "account.block": "Block @{name}",
5
+  "account.block_domain": "Hide everything from {domain}",
6
+  "account.blocked": "Blocked",
7
+  "account.direct": "Direct message @{name}",
8
+  "account.domain_blocked": "Domain hidden",
9
+  "account.edit_profile": "Edit profile",
10
+  "account.endorse": "Feature on profile",
11
+  "account.follow": "Join pride",
12
+  "account.followers": "Pride Members",
13
+  "account.followers.empty": "No one follows this lion yet.",
14
+  "account.follows": "Joined Prides",
15
+  "account.follows.empty": "This lion doesn't follow anyone yet.",
16
+  "account.follows_you": "In your pride",
17
+  "account.hide_reblogs": "Hide roars from @{name}",
18
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
19
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
20
+  "account.media": "Media",
21
+  "account.mention": "Meow at @{name}",
22
+  "account.moved_to": "{name} has moved to:",
23
+  "account.mute": "Mute @{name}",
24
+  "account.mute_notifications": "Mute notifications from @{name}",
25
+  "account.muted": "Muted",
26
+  "account.posts": "Toots",
27
+  "account.posts_with_replies": "Toots with meows",
28
+  "account.report": "Report @{name}",
29
+  "account.requested": "Awaiting approval. Click to cancel pride request",
30
+  "account.share": "Share @{name}'s profile",
31
+  "account.show_reblogs": "Show roars from @{name}",
32
+  "account.unblock": "Unblock @{name}",
33
+  "account.unblock_domain": "Unhide {domain}",
34
+  "account.unendorse": "Don't feature on profile",
35
+  "account.unfollow": "Leave Pride",
36
+  "account.unmute": "Unmute @{name}",
37
+  "account.unmute_notifications": "Unmute notifications from @{name}",
38
+  "alert.unexpected.message": "An unexpected error occurred.",
39
+  "alert.unexpected.title": "Oops!",
40
+  "boost_modal.combo": "You can press {combo} to skip this next time",
41
+  "bundle_column_error.body": "Something went wrong while loading this component.",
42
+  "bundle_column_error.retry": "Try again",
43
+  "bundle_column_error.title": "Network error",
44
+  "bundle_modal_error.close": "Close",
45
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
46
+  "bundle_modal_error.retry": "Try again",
47
+  "column.blocks": "Blocked lions",
48
+  "column.community": "Local timeline",
49
+  "column.direct": "Direct messages",
50
+  "column.domain_blocks": "Hidden domains",
51
+  "column.favourites": "Boops",
52
+  "column.follow_requests": "Pride requests",
53
+  "column.home": "Home",
54
+  "column.lists": "Lists",
55
+  "column.mutes": "Muted lions",
56
+  "column.notifications": "Notifications",
57
+  "column.pins": "Pinned toots",
58
+  "column.public": "Federated timeline",
59
+  "column_back_button.label": "Back",
60
+  "column_header.hide_settings": "Hide settings",
61
+  "column_header.moveLeft_settings": "Move column to the left",
62
+  "column_header.moveRight_settings": "Move column to the right",
63
+  "column_header.pin": "Pin",
64
+  "column_header.show_settings": "Show settings",
65
+  "column_header.unpin": "Unpin",
66
+  "column_subheading.settings": "Settings",
67
+  "community.column_settings.media_only": "Media Only",
68
+  "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned lions.",
69
+  "compose_form.direct_message_warning_learn_more": "Learn more",
70
+  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
71
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can join your pride to view your pride-only toots.",
72
+  "compose_form.lock_disclaimer.lock": "locked",
73
+  "compose_form.placeholder": "Meow???",
74
+  "compose_form.poll.add_option": "Add a choice",
75
+  "compose_form.poll.duration": "Poll duration",
76
+  "compose_form.poll.option_placeholder": "Choice {number}",
77
+  "compose_form.poll.remove_option": "Remove this choice",
78
+  "compose_form.publish": "Toot",
79
+  "compose_form.publish_loud": "{publish}!",
80
+  "compose_form.sensitive.hide": "Mark media as sensitive",
81
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
82
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
83
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
84
+  "compose_form.spoiler.unmarked": "Text is not hidden",
85
+  "compose_form.spoiler_placeholder": "Write your warning here",
86
+  "confirmation_modal.cancel": "Cancel",
87
+  "confirmations.block.block_and_report": "Block & Report",
88
+  "confirmations.block.confirm": "Block",
89
+  "confirmations.block.message": "Are you sure you want to block {name}?",
90
+  "confirmations.delete.confirm": "Delete",
91
+  "confirmations.delete.message": "Are you sure you want to delete this toot?",
92
+  "confirmations.delete_list.confirm": "Delete",
93
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
94
+  "confirmations.domain_block.confirm": "Hide entire domain",
95
+  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
96
+  "confirmations.mute.confirm": "Mute",
97
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
98
+  "confirmations.redraft.confirm": "Delete & redraft",
99
+  "confirmations.redraft.message": "Are you sure you want to delete this toot and re-draft it? You will lose all meows, roars, and boops to it.",
100
+  "confirmations.reply.confirm": "Meow",
101
+  "confirmations.reply.message": "Meowing now will overwrite the toot you are currently composing. Are you sure you want to proceed?",
102
+  "confirmations.unfollow.confirm": "Leave Pride",
103
+  "confirmations.unfollow.message": "Are you sure you want to leave {name}'s pride?",
104
+  "embed.instructions": "Embed this toot on your website by copying the code below.",
105
+  "embed.preview": "Here is what it will look like:",
106
+  "emoji_button.activity": "Activity",
107
+  "emoji_button.custom": "Custom",
108
+  "emoji_button.flags": "Flags",
109
+  "emoji_button.food": "Food & Drink",
110
+  "emoji_button.label": "Insert emoji",
111
+  "emoji_button.nature": "Nature",
112
+  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
113
+  "emoji_button.objects": "Objects",
114
+  "emoji_button.people": "Lions",
115
+  "emoji_button.recent": "Frequently used",
116
+  "emoji_button.search": "Search...",
117
+  "emoji_button.search_results": "Search results",
118
+  "emoji_button.symbols": "Symbols",
119
+  "emoji_button.travel": "Travel & Places",
120
+  "empty_column.account_timeline": "No toots here!",
121
+  "empty_column.account_unavailable": "Profile unavailable",
122
+  "empty_column.blocks": "You haven't blocked any lions yet.",
123
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
124
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
125
+  "empty_column.domain_blocks": "There are no hidden domains yet.",
126
+  "empty_column.favourited_statuses": "You don't have any booped toots yet. When you boop one, it will show up here.",
127
+  "empty_column.favourites": "No one has booped this toot yet. When someone does, they will show up here.",
128
+  "empty_column.follow_requests": "You don't have any pride requests yet. When you receive one, it will show up here.",
129
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
130
+  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other lions.",
131
+  "empty_column.home.public_timeline": "the public timeline",
132
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
133
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
134
+  "empty_column.mutes": "You haven't muted any lions yet.",
135
+  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
136
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow lions from other instances to fill it up",
137
+  "follow_request.authorize": "Authorize",
138
+  "follow_request.reject": "Reject",
139
+  "getting_started.developers": "Developers",
140
+  "getting_started.directory": "Profile directory",
141
+  "getting_started.documentation": "Documentation",
142
+  "getting_started.heading": "Getting started",
143
+  "getting_started.invite": "Invite lions",
144
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
145
+  "getting_started.security": "Security",
146
+  "getting_started.terms": "Terms of service",
147
+  "hashtag.column_header.tag_mode.all": "and {additional}",
148
+  "hashtag.column_header.tag_mode.any": "or {additional}",
149
+  "hashtag.column_header.tag_mode.none": "without {additional}",
150
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
151
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
152
+  "hashtag.column_settings.tag_mode.all": "All of these",
153
+  "hashtag.column_settings.tag_mode.any": "Any of these",
154
+  "hashtag.column_settings.tag_mode.none": "None of these",
155
+  "hashtag.column_settings.tag_toggle": "Include additional tags for this column",
156
+  "home.column_settings.basic": "Basic",
157
+  "home.column_settings.show_reblogs": "Show roars",
158
+  "home.column_settings.show_replies": "Show meows",
159
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
160
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
161
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
162
+  "introduction.federation.action": "Next",
163
+  "introduction.federation.federated.headline": "Federated",
164
+  "introduction.federation.federated.text": "Public toots from other servers of the fediverse will appear in the federated timeline.",
165
+  "introduction.federation.home.headline": "Home",
166
+  "introduction.federation.home.text": "Toots from lions you follow will appear in your home feed. You can follow anyone on any server!",
167
+  "introduction.federation.local.headline": "Local",
168
+  "introduction.federation.local.text": "Public toots from lions on the same server as you will appear in the local timeline.",
169
+  "introduction.interactions.action": "Finish tutorial!",
170
+  "introduction.interactions.favourite.headline": "Favourite",
171
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
172
+  "introduction.interactions.reblog.headline": "Boost",
173
+  "introduction.interactions.reblog.text": "You can share other lions' toots with your followers by boosting them.",
174
+  "introduction.interactions.reply.headline": "Meow",
175
+  "introduction.interactions.reply.text": "You can meow at other lions' and your own toots, which will chain them together in a conversation.",
176
+  "introduction.welcome.action": "Let's go!",
177
+  "introduction.welcome.headline": "First steps",
178
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
179
+  "keyboard_shortcuts.back": "to navigate back",
180
+  "keyboard_shortcuts.blocked": "to open blocked dogs list",
181
+  "keyboard_shortcuts.boost": "to boost",
182
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
183
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
184
+  "keyboard_shortcuts.description": "Description",
185
+  "keyboard_shortcuts.direct": "to open direct messages column",
186
+  "keyboard_shortcuts.down": "to move down in the list",
187
+  "keyboard_shortcuts.enter": "to open status",
188
+  "keyboard_shortcuts.favourite": "to favourite",
189
+  "keyboard_shortcuts.favourites": "to open boops list",
190
+  "keyboard_shortcuts.federated": "to open federated timeline",
191
+  "keyboard_shortcuts.heading": "Keyboard shortcuts",
192
+  "keyboard_shortcuts.home": "to open home timeline",
193
+  "keyboard_shortcuts.hotkey": "Hotkey",
194
+  "keyboard_shortcuts.legend": "to display this legend",
195
+  "keyboard_shortcuts.local": "to open local timeline",
196
+  "keyboard_shortcuts.mention": "to mention author",
197
+  "keyboard_shortcuts.muted": "to open muted lions list",
198
+  "keyboard_shortcuts.my_profile": "to open your profile",
199
+  "keyboard_shortcuts.notifications": "to open notifications column",
200
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
201
+  "keyboard_shortcuts.profile": "to open author's profile",
202
+  "keyboard_shortcuts.reply": "to meow",
203
+  "keyboard_shortcuts.requests": "to open pride requests list",
204
+  "keyboard_shortcuts.search": "to focus search",
205
+  "keyboard_shortcuts.start": "to open \"get started\" column",
206
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
207
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
208
+  "keyboard_shortcuts.toot": "to start a brand new toot",
209
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
210
+  "keyboard_shortcuts.up": "to move up in the list",
211
+  "lightbox.close": "Close",
212
+  "lightbox.next": "Next",
213
+  "lightbox.previous": "Previous",
214
+  "lightbox.view_context": "View context",
215
+  "lists.account.add": "Add to list",
216
+  "lists.account.remove": "Remove from list",
217
+  "lists.delete": "Delete list",
218
+  "lists.edit": "Edit list",
219
+  "lists.edit.submit": "Change title",
220
+  "lists.new.create": "Add list",
221
+  "lists.new.title_placeholder": "New list title",
222
+  "lists.search": "Search among lions you follow",
223
+  "lists.subheading": "Your lists",
224
+  "loading_indicator.label": "Loading...",
225
+  "media_gallery.toggle_visible": "Toggle visibility",
226
+  "missing_indicator.label": "Not found",
227
+  "missing_indicator.sublabel": "This resource could not be found",
228
+  "mute_modal.hide_notifications": "Hide notifications from this lion?",
229
+  "navigation_bar.apps": "Mobile apps",
230
+  "navigation_bar.blocks": "Blocked lions",
231
+  "navigation_bar.community_timeline": "Local timeline",
232
+  "navigation_bar.compose": "Compose new toot",
233
+  "navigation_bar.direct": "Direct messages",
234
+  "navigation_bar.discover": "Discover",
235
+  "navigation_bar.domain_blocks": "Hidden domains",
236
+  "navigation_bar.edit_profile": "Edit profile",
237
+  "navigation_bar.favourites": "Boops",
238
+  "navigation_bar.filters": "Muted words",
239
+  "navigation_bar.follow_requests": "Pride requests",
240
+  "navigation_bar.follows_and_followers": "Prides and Pride Members",
241
+  "navigation_bar.info": "About this server",
242
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
243
+  "navigation_bar.lists": "Lists",
244
+  "navigation_bar.logout": "Logout",
245
+  "navigation_bar.mutes": "Muted lions",
246
+  "navigation_bar.personal": "Personal",
247
+  "navigation_bar.pins": "Pinned toots",
248
+  "navigation_bar.preferences": "Preferences",
249
+  "navigation_bar.profile_directory": "Lion directory",
250
+  "navigation_bar.public_timeline": "Federated timeline",
251
+  "navigation_bar.security": "Security",
252
+  "notification.favourite": "{name} booped your toot",
253
+  "notification.follow": "{name} joined your pride",
254
+  "notification.mention": "{name} meowed at you",
255
+  "notification.poll": "A poll you have voted in has ended",
256
+  "notification.reblog": "{name} roared your toot",
257
+  "notifications.clear": "Clear notifications",
258
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
259
+  "notifications.column_settings.alert": "Desktop notifications",
260
+  "notifications.column_settings.favourite": "Boops:",
261
+  "notifications.column_settings.follow": "New pride members:",
262
+  "notifications.column_settings.mention": "Meows:",
263
+  "notifications.column_settings.filter_bar.show": "Show",
264
+  "notifications.column_settings.follow": "New Pride Members:",
265
+  "notifications.column_settings.mention": "Meows:",
266
+  "notifications.column_settings.poll": "Poll results:",
267
+  "notifications.column_settings.push": "Push notifications",
268
+  "notifications.column_settings.reblog": "Roars:",
269
+  "notifications.column_settings.show": "Show in column",
270
+  "notifications.column_settings.sound": "Play sound",
271
+  "notifications.filter.all": "All",
272
+  "notifications.filter.boosts": "Roars",
273
+  "notifications.filter.favourites": "Boops",
274
+  "notifications.filter.follows": "Pride Members",
275
+  "notifications.filter.mentions": "Meows",
276
+  "notifications.filter.polls": "Poll results",
277
+  "notifications.group": "{count} notifications",
278
+  "poll.closed": "Closed",
279
+  "poll.refresh": "Refresh",
280
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
281
+  "poll.vote": "Vote",
282
+  "poll_button.add_poll": "Add a poll",
283
+  "poll_button.remove_poll": "Remove poll",
284
+  "privacy.change": "Adjust status privacy",
285
+  "privacy.direct.long": "Post to mentioned lions only",
286
+  "privacy.direct.short": "Direct",
287
+  "privacy.private.long": "Toot to followers only",
288
+  "privacy.private.short": "Pride Members-only",
289
+  "privacy.public.long": "Toot to public timelines",
290
+  "privacy.public.short": "Public",
291
+  "privacy.unlisted.long": "Do not toot to public timelines",
292
+  "privacy.unlisted.short": "Unlisted",
293
+  "regeneration_indicator.label": "Loading…",
294
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
295
+  "relative_time.days": "{number}d",
296
+  "relative_time.hours": "{number}h",
297
+  "relative_time.just_now": "now",
298
+  "relative_time.minutes": "{number}m",
299
+  "relative_time.seconds": "{number}s",
300
+  "reply_indicator.cancel": "Cancel",
301
+  "report.forward": "Forward to {target}",
302
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
303
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
304
+  "report.placeholder": "Additional comments",
305
+  "report.submit": "Submit",
306
+  "report.target": "Reporting {target}",
307
+  "search.placeholder": "Search",
308
+  "search_popout.search_format": "Advanced search format",
309
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, booped, roard, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
310
+  "search_popout.tips.hashtag": "hashtag",
311
+  "search_popout.tips.status": "status",
312
+  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
313
+  "search_popout.tips.user": "lion",
314
+  "search_results.accounts": "Lions",
315
+  "search_results.hashtags": "Hashtags",
316
+  "search_results.statuses": "Toots",
317
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
318
+  "status.admin_account": "Open moderation interface for @{name}",
319
+  "status.admin_status": "Open this status in the moderation interface",
320
+  "status.block": "Block @{name}",
321
+  "status.cancel_reblog_private": "Unroar",
322
+  "status.cannot_reblog": "This toot cannot be roared",
323
+  "status.copy": "Copy link to status",
324
+  "status.delete": "Delete",
325
+  "status.detailed_status": "Detailed conversation view",
326
+  "status.direct": "Direct message @{name}",
327
+  "status.embed": "Embed",
328
+  "status.favourite": "Boop",
329
+  "status.filtered": "Filtered",
330
+  "status.load_more": "Load more",
331
+  "status.media_hidden": "Media hidden",
332
+  "status.mention": "Meow at @{name}",
333
+  "status.more": "More",
334
+  "status.mute": "Mute @{name}",
335
+  "status.mute_conversation": "Mute conversation",
336
+  "status.open": "Expand this toot",
337
+  "status.pin": "Pin on profile",
338
+  "status.pinned": "Pinned toot",
339
+  "status.read_more": "Read more",
340
+  "status.reblog": "Roar",
341
+  "status.reblog_private": "Roar to original audience",
342
+  "status.reblogged_by": "{name} roared",
343
+  "status.reblogs.empty": "No one has roared this toot yet. When someone does, they will show up here.",
344
+  "status.redraft": "Delete & re-draft",
345
+  "status.reply": "Meow",
346
+  "status.replyAll": "Meow in thread",
347
+  "status.report": "Report @{name}",
348
+  "status.sensitive_warning": "Sensitive content",
349
+  "status.share": "Share",
350
+  "status.show_less": "Show less",
351
+  "status.show_less_all": "Show less for all",
352
+  "status.show_more": "Show more",
353
+  "status.show_more_all": "Show more for all",
354
+  "status.show_thread": "Show thread",
355
+  "status.unmute_conversation": "Unmute conversation",
356
+  "status.unpin": "Unpin from profile",
357
+  "suggestions.dismiss": "Dismiss suggestion",
358
+  "suggestions.header": "You might be interested in…",
359
+  "tabs_bar.federated_timeline": "Federated",
360
+  "tabs_bar.home": "Home",
361
+  "tabs_bar.local_timeline": "Local",
362
+  "tabs_bar.notifications": "Notifications",
363
+  "tabs_bar.search": "Search",
364
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
365
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
366
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
367
+  "time_remaining.moments": "Moments remaining",
368
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
369
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
370
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
371
+  "upload_area.title": "Drag & drop to upload",
372
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
373
+  "upload_error.limit": "File upload limit exceeded.",
374
+  "upload_error.poll": "File upload not allowed with polls.",
375
+  "upload_form.description": "Describe for the visually impaired",
376
+  "upload_form.focus": "Change preview",
377
+  "upload_form.undo": "Delete",
378
+  "upload_progress.label": "Uploading...",
379
+  "video.close": "Close video",
380
+  "video.exit_fullscreen": "Exit full screen",
381
+  "video.expand": "Expand video",
382
+  "video.fullscreen": "Full screen",
383
+  "video.hide": "Hide video",
384
+  "video.mute": "Mute sound",
385
+  "video.pause": "Pause",
386
+  "video.play": "Play",
387
+  "video.unmute": "Unmute sound"
388
+}

+ 115
- 0
app/javascript/mastodon/locales/locale-data/dog.js View File

@@ -0,0 +1,115 @@
1
+/*eslint eqeqeq: "off"*/
2
+/*eslint no-nested-ternary: "off"*/
3
+/*eslint quotes: "off"*/
4
+
5
+export default [
6
+    {
7
+        locale: "dog",
8
+        pluralRuleFunction: function(e, a) {
9
+            var n = String(e).split("."),
10
+                l = !n[1],
11
+                o = Number(n[0]) == e,
12
+                t = o && n[0].slice(-1),
13
+                r = o && n[0].slice(-2);
14
+            return a ? 1 == t && 11 != r ? "one" : 2 == t && 12 != r ? "two" : 3 == t && 13 != r ? "few" : "other" : 1 == e && l ? "one" : "other"
15
+        },
16
+        fields: {
17
+            year: {
18
+                displayName: "year",
19
+                relative: {
20
+                    0: "this year",
21
+                    1: "next year",
22
+                    "-1": "last year"
23
+                },
24
+                relativeTime: {
25
+                    future: {
26
+                        one: "in {0} year",
27
+                        other: "in {0} years"
28
+                    },
29
+                    past: {
30
+                        one: "{0} year ago",
31
+                        other: "{0} years ago"
32
+                    }
33
+                }
34
+            },
35
+            month: {
36
+                displayName: "month",
37
+                relative: {
38
+                    0: "this month",
39
+                    1: "next month",
40
+                    "-1": "last month"
41
+                },
42
+                relativeTime: {
43
+                    future: {
44
+                        one: "in {0} month",
45
+                        other: "in {0} months"
46
+                    },
47
+                    past: {
48
+                        one: "{0} month ago",
49
+                        other: "{0} months ago"
50
+                    }
51
+                }
52
+            },
53
+            day: {
54
+                displayName: "day",
55
+                relative: {
56
+                    0: "today",
57
+                    1: "tomorrow",
58
+                    "-1": "yesterday"
59
+                },
60
+                relativeTime: {
61
+                    future: {
62
+                        one: "in {0} day",
63
+                        other: "in {0} days"
64
+                    },
65
+                    past: {
66
+                        one: "{0} day ago",
67
+                        other: "{0} days ago"
68
+                    }
69
+                }
70
+            },
71
+            hour: {
72
+                displayName: "hour",
73
+                relativeTime: {
74
+                    future: {
75
+                        one: "in {0} hour",
76
+                        other: "in {0} hours"
77
+                    },
78
+                    past: {
79
+                        one: "{0} hour ago",
80
+                        other: "{0} hours ago"
81
+                    }
82
+                }
83
+            },
84
+            minute: {
85
+                displayName: "minute",
86
+                relativeTime: {
87
+                    future: {
88
+                        one: "in {0} minute",
89
+                        other: "in {0} minutes"
90
+                    },
91
+                    past: {
92
+                        one: "{0} minute ago",
93
+                        other: "{0} minutes ago"
94
+                    }
95
+                }
96
+            },
97
+            second: {
98
+                displayName: "second",
99
+                relative: {
100
+                    0: "now"
101
+                },
102
+                relativeTime: {
103
+                    future: {
104
+                        one: "in {0} second",
105
+                        other: "in {0} seconds"
106
+                    },
107
+                    past: {
108
+                        one: "{0} second ago",
109
+                        other: "{0} seconds ago"
110
+                    }
111
+                }
112
+            }
113
+        }
114
+    }
115
+];

+ 115
- 0
app/javascript/mastodon/locales/locale-data/lion.js View File

@@ -0,0 +1,115 @@
1
+/*eslint eqeqeq: "off"*/
2
+/*eslint no-nested-ternary: "off"*/
3
+/*eslint quotes: "off"*/
4
+
5
+export default [
6
+    {
7
+        locale: "lion",
8
+        pluralRuleFunction: function(e, a) {
9
+            var n = String(e).split("."),
10
+                l = !n[1],
11
+                o = Number(n[0]) == e,
12
+                t = o && n[0].slice(-1),
13
+                r = o && n[0].slice(-2);
14
+            return a ? 1 == t && 11 != r ? "one" : 2 == t && 12 != r ? "two" : 3 == t && 13 != r ? "few" : "other" : 1 == e && l ? "one" : "other"
15
+        },
16
+        fields: {
17
+            year: {
18
+                displayName: "year",
19
+                relative: {
20
+                    0: "this year",
21
+                    1: "next year",
22
+                    "-1": "last year"
23
+                },
24
+                relativeTime: {
25
+                    future: {
26
+                        one: "in {0} year",
27
+                        other: "in {0} years"
28
+                    },
29
+                    past: {
30
+                        one: "{0} year ago",
31
+                        other: "{0} years ago"
32
+                    }
33
+                }
34
+            },
35
+            month: {
36
+                displayName: "month",
37
+                relative: {
38
+                    0: "this month",
39
+                    1: "next month",
40
+                    "-1": "last month"
41
+                },
42
+                relativeTime: {
43
+                    future: {
44
+                        one: "in {0} month",
45
+                        other: "in {0} months"
46
+                    },
47
+                    past: {
48
+                        one: "{0} month ago",
49
+                        other: "{0} months ago"
50
+                    }
51
+                }
52
+            },
53
+            day: {
54
+                displayName: "day",
55
+                relative: {
56
+                    0: "today",
57
+                    1: "tomorrow",
58
+                    "-1": "yesterday"
59
+                },
60
+                relativeTime: {
61
+                    future: {
62
+                        one: "in {0} day",
63
+                        other: "in {0} days"
64
+                    },
65
+                    past: {
66
+                        one: "{0} day ago",
67
+                        other: "{0} days ago"
68
+                    }
69
+                }
70
+            },
71
+            hour: {
72
+                displayName: "hour",
73
+                relativeTime: {
74
+                    future: {
75
+                        one: "in {0} hour",
76
+                        other: "in {0} hours"
77
+                    },
78
+                    past: {
79
+                        one: "{0} hour ago",
80
+                        other: "{0} hours ago"
81
+                    }
82
+                }
83
+            },
84
+            minute: {
85
+                displayName: "minute",
86
+                relativeTime: {
87
+                    future: {
88
+                        one: "in {0} minute",
89
+                        other: "in {0} minutes"
90
+                    },
91
+                    past: {
92
+                        one: "{0} minute ago",
93
+                        other: "{0} minutes ago"
94
+                    }
95
+                }
96
+            },
97
+            second: {
98
+                displayName: "second",
99
+                relative: {
100
+                    0: "now"
101
+                },
102
+                relativeTime: {
103
+                    future: {
104
+                        one: "in {0} second",
105
+                        other: "in {0} seconds"
106
+                    },
107
+                    past: {
108
+                        one: "{0} second ago",
109
+                        other: "{0} seconds ago"
110
+                    }
111
+                }
112
+            }
113
+        }
114
+    }
115
+];

+ 115
- 0
app/javascript/mastodon/locales/locale-data/squeak.js View File

@@ -0,0 +1,115 @@
1
+/*eslint eqeqeq: "off"*/
2
+/*eslint no-nested-ternary: "off"*/
3
+/*eslint quotes: "off"*/
4
+
5
+export default [
6
+    {
7
+        locale: "squeak",
8
+        pluralRuleFunction: function(e, a) {
9
+            var n = String(e).split("."),
10
+                l = !n[1],
11
+                o = Number(n[0]) == e,
12
+                t = o && n[0].slice(-1),
13
+                r = o && n[0].slice(-2);
14
+            return a ? 1 == t && 11 != r ? "one" : 2 == t && 12 != r ? "two" : 3 == t && 13 != r ? "few" : "other" : 1 == e && l ? "one" : "other"
15
+        },
16
+        fields: {
17
+            year: {
18
+                displayName: "year",
19
+                relative: {
20
+                    0: "this year",
21
+                    1: "next year",
22
+                    "-1": "last year"
23
+                },
24
+                relativeTime: {
25
+                    future: {
26
+                        one: "in {0} year",
27
+                        other: "in {0} years"
28
+                    },
29
+                    past: {
30
+                        one: "{0} year ago",
31
+                        other: "{0} years ago"
32
+                    }
33
+                }
34
+            },
35
+            month: {
36
+                displayName: "month",
37
+                relative: {
38
+                    0: "this month",
39
+                    1: "next month",
40
+                    "-1": "last month"
41
+                },
42
+                relativeTime: {
43
+                    future: {
44
+                        one: "in {0} month",
45
+                        other: "in {0} months"
46
+                    },
47
+                    past: {
48
+                        one: "{0} month ago",
49
+                        other: "{0} months ago"
50
+                    }
51
+                }
52
+            },
53
+            day: {
54
+                displayName: "day",
55
+                relative: {
56
+                    0: "today",
57
+                    1: "tomorrow",
58
+                    "-1": "yesterday"
59
+                },
60
+                relativeTime: {
61
+                    future: {
62
+                        one: "in {0} day",
63
+                        other: "in {0} days"
64
+                    },
65
+                    past: {
66
+                        one: "{0} day ago",
67
+                        other: "{0} days ago"
68
+                    }
69
+                }
70
+            },
71
+            hour: {
72
+                displayName: "hour",
73
+                relativeTime: {
74
+                    future: {
75
+                        one: "in {0} hour",
76
+                        other: "in {0} hours"
77
+                    },
78
+                    past: {
79
+                        one: "{0} hour ago",
80
+                        other: "{0} hours ago"
81
+                    }
82
+                }
83
+            },
84
+            minute: {
85
+                displayName: "minute",
86
+                relativeTime: {
87
+                    future: {
88
+                        one: "in {0} minute",
89
+                        other: "in {0} minutes"
90
+                    },
91
+                    past: {
92
+                        one: "{0} minute ago",
93
+                        other: "{0} minutes ago"
94
+                    }
95
+                }
96
+            },
97
+            second: {
98
+                displayName: "second",
99
+                relative: {
100
+                    0: "now"
101
+                },
102
+                relativeTime: {
103
+                    future: {
104
+                        one: "in {0} second",
105
+                        other: "in {0} seconds"
106
+                    },
107
+                    past: {
108
+                        one: "{0} second ago",
109
+                        other: "{0} seconds ago"
110
+                    }
111
+                }
112
+            }
113
+        }
114
+    }
115
+];

+ 388
- 0
app/javascript/mastodon/locales/squeak.json View File

@@ -0,0 +1,388 @@
1
+{
2
+  "account.add_or_remove_from_list": "Add or Remove from lists",
3
+  "account.badges.bot": "Bot",
4
+  "account.block": "Block @{name}",
5
+  "account.block_domain": "Hide everything from {domain}",
6
+  "account.blocked": "Blocked",
7
+  "account.direct": "Direct message @{name}",
8
+  "account.domain_blocked": "Domain hidden",
9
+  "account.edit_profile": "Edit profile",
10
+  "account.endorse": "Feature on profile",
11
+  "account.follow": "Follow",
12
+  "account.followers": "Followers",
13
+  "account.followers.empty": "No one follows this user yet.",
14
+  "account.follows": "Follows",
15
+  "account.follows.empty": "This user doesn't follow anyone yet.",
16
+  "account.follows_you": "Follows you",
17
+  "account.hide_reblogs": "Hide pumps from @{name}",
18
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
19
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
20
+  "account.media": "Media",
21
+  "account.mention": "Mention @{name}",
22
+  "account.moved_to": "{name} has moved to:",
23
+  "account.mute": "Mute @{name}",
24
+  "account.mute_notifications": "Mute notifications from @{name}",
25
+  "account.muted": "Muted",
26
+  "account.posts": "Toots",
27
+  "account.posts_with_replies": "Toots and replies",
28
+  "account.report": "Report @{name}",
29
+  "account.requested": "Awaiting approval. Click to cancel follow request",
30
+  "account.share": "Share @{name}'s profile",
31
+  "account.show_reblogs": "Show pumps from @{name}",
32
+  "account.unblock": "Unblock @{name}",
33
+  "account.unblock_domain": "Unhide {domain}",
34
+  "account.unendorse": "Don't feature on profile",
35
+  "account.unfollow": "Unfollow",
36
+  "account.unmute": "Unmute @{name}",
37
+  "account.unmute_notifications": "Unmute notifications from @{name}",
38
+  "alert.unexpected.message": "An unexpected error occurred.",
39
+  "alert.unexpected.title": "Oops!",
40
+  "boost_modal.combo": "You can press {combo} to skip this next time",
41
+  "bundle_column_error.body": "Something went wrong while loading this component.",
42
+  "bundle_column_error.retry": "Try again",
43
+  "bundle_column_error.title": "Network error",
44
+  "bundle_modal_error.close": "Close",
45
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
46
+  "bundle_modal_error.retry": "Try again",
47
+  "column.blocks": "Blocked users",
48
+  "column.community": "Local timeline",
49
+  "column.direct": "Direct messages",
50
+  "column.domain_blocks": "Hidden domains",
51
+  "column.favourites": "Squeaks",
52
+  "column.follow_requests": "Follow requests",
53
+  "column.home": "Home",
54
+  "column.lists": "Lists",
55
+  "column.mutes": "Muted users",
56
+  "column.notifications": "Notifications",
57
+  "column.pins": "Pinned toots",
58
+  "column.public": "Federated timeline",
59
+  "column_back_button.label": "Back",
60
+  "column_header.hide_settings": "Hide settings",
61
+  "column_header.moveLeft_settings": "Move column to the left",
62
+  "column_header.moveRight_settings": "Move column to the right",
63
+  "column_header.pin": "Pin",
64
+  "column_header.show_settings": "Show settings",
65
+  "column_header.unpin": "Unpin",
66
+  "column_subheading.settings": "Settings",
67
+  "community.column_settings.media_only": "Media Only",
68
+  "compose_form.direct_message_warning": "This toot will only be sent to the mentioned users.",
69
+  "compose_form.direct_message_warning_learn_more": "Learn more",
70
+  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
71
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
72
+  "compose_form.lock_disclaimer.lock": "locked",
73
+  "compose_form.placeholder": "What's on your mind?",
74
+  "compose_form.poll.add_option": "Add a choice",
75
+  "compose_form.poll.duration": "Poll duration",
76
+  "compose_form.poll.option_placeholder": "Choice {number}",
77
+  "compose_form.poll.remove_option": "Remove this choice",
78
+  "compose_form.publish": "Toot",
79
+  "compose_form.publish_loud": "{publish}!",
80
+  "compose_form.sensitive.hide": "Mark media as sensitive",
81
+  "compose_form.sensitive.marked": "Media is marked as sensitive",
82
+  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
83
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
84
+  "compose_form.spoiler.unmarked": "Text is not hidden",
85
+  "compose_form.spoiler_placeholder": "Write your warning here",
86
+  "confirmation_modal.cancel": "Cancel",
87
+  "confirmations.block.block_and_report": "Block & Report",
88
+  "confirmations.block.confirm": "Block",
89
+  "confirmations.block.message": "Are you sure you want to block {name}?",
90
+  "confirmations.delete.confirm": "Delete",
91
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
92
+  "confirmations.delete_list.confirm": "Delete",
93
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
94
+  "confirmations.domain_block.confirm": "Hide entire domain",
95
+  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
96
+  "confirmations.mute.confirm": "Mute",
97
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
98
+  "confirmations.redraft.confirm": "Delete & redraft",
99
+  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Squeaks and pumps will be lost, and replies to the original post will be orphaned.",
100
+  "confirmations.reply.confirm": "Reply",
101
+  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
102
+  "confirmations.unfollow.confirm": "Unfollow",
103
+  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
104
+  "embed.instructions": "Embed this status on your website by copying the code below.",
105
+  "embed.preview": "Here is what it will look like:",
106
+  "emoji_button.activity": "Activity",
107
+  "emoji_button.custom": "Custom",
108
+  "emoji_button.flags": "Flags",
109
+  "emoji_button.food": "Food & Drink",
110
+  "emoji_button.label": "Insert emoji",
111
+  "emoji_button.nature": "Nature",
112
+  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
113
+  "emoji_button.objects": "Objects",
114
+  "emoji_button.people": "People",
115
+  "emoji_button.recent": "Frequently used",
116
+  "emoji_button.search": "Search...",
117
+  "emoji_button.search_results": "Search results",
118
+  "emoji_button.symbols": "Symbols",
119
+  "emoji_button.travel": "Travel & Places",
120
+  "empty_column.account_timeline": "No toots here!",
121
+  "empty_column.account_unavailable": "Profile unavailable",
122
+  "empty_column.blocks": "You haven't blocked any users yet.",
123
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
124
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
125
+  "empty_column.domain_blocks": "There are no hidden domains yet.",
126
+  "empty_column.favourited_statuses": "You don't have any squeaked toots yet. When you squeak one, it will show up here.",
127
+  "empty_column.favourites": "No one has squeaked this toot yet. When someone does, they will show up here.",
128
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
129
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
130
+  "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
131
+  "empty_column.home.public_timeline": "the public timeline",
132
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
133
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
134
+  "empty_column.mutes": "You haven't muted any users yet.",
135
+  "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
136
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
137
+  "follow_request.authorize": "Authorize",
138
+  "follow_request.reject": "Reject",
139
+  "getting_started.developers": "Developers",
140
+  "getting_started.directory": "Profile directory",
141
+  "getting_started.documentation": "Documentation",
142
+  "getting_started.heading": "Getting started",
143
+  "getting_started.invite": "Invite people",
144
+  "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
145
+  "getting_started.security": "Security",
146
+  "getting_started.terms": "Terms of service",
147
+  "hashtag.column_header.tag_mode.all": "and {additional}",
148
+  "hashtag.column_header.tag_mode.any": "or {additional}",
149
+  "hashtag.column_header.tag_mode.none": "without {additional}",
150
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
151
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
152
+  "hashtag.column_settings.tag_mode.all": "All of these",
153
+  "hashtag.column_settings.tag_mode.any": "Any of these",
154
+  "hashtag.column_settings.tag_mode.none": "None of these",
155
+  "hashtag.column_settings.tag_toggle": "Include additional tags for this column",
156
+  "home.column_settings.basic": "Basic",
157
+  "home.column_settings.show_reblogs": "Show pumps",
158
+  "home.column_settings.show_replies": "Show replies",
159
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
160
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
161
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
162
+  "introduction.federation.action": "Next",
163
+  "introduction.federation.federated.headline": "Federated",
164
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
165
+  "introduction.federation.home.headline": "Home",
166
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
167
+  "introduction.federation.local.headline": "Local",
168
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
169
+  "introduction.interactions.action": "Finish tutorial!",
170
+  "introduction.interactions.favourite.headline": "Squeak",
171
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by squeaking it.",
172
+  "introduction.interactions.reblog.headline": "Pump",
173
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by pumping them.",
174
+  "introduction.interactions.reply.headline": "Reply",
175
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
176
+  "introduction.welcome.action": "Let's go!",
177
+  "introduction.welcome.headline": "First steps",
178
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
179
+  "keyboard_shortcuts.back": "to navigate back",
180
+  "keyboard_shortcuts.blocked": "to open blocked users list",
181
+  "keyboard_shortcuts.boost": "to pump",
182
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
183
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
184
+  "keyboard_shortcuts.description": "Description",
185
+  "keyboard_shortcuts.direct": "to open direct messages column",
186
+  "keyboard_shortcuts.down": "to move down in the list",
187
+  "keyboard_shortcuts.enter": "to open status",
188
+  "keyboard_shortcuts.favourite": "to squeak",
189
+  "keyboard_shortcuts.favourites": "to open squeaks list",
190
+  "keyboard_shortcuts.federated": "to open federated timeline",
191
+  "keyboard_shortcuts.heading": "Keyboard shortcuts",
192
+  "keyboard_shortcuts.home": "to open home timeline",
193
+  "keyboard_shortcuts.hotkey": "Hotkey",
194
+  "keyboard_shortcuts.legend": "to display this legend",
195
+  "keyboard_shortcuts.local": "to open local timeline",
196
+  "keyboard_shortcuts.mention": "to mention author",
197
+  "keyboard_shortcuts.muted": "to open muted users list",
198
+  "keyboard_shortcuts.my_profile": "to open your profile",
199
+  "keyboard_shortcuts.notifications": "to open notifications column",
200
+  "keyboard_shortcuts.pinned": "to open pinned toots list",
201
+  "keyboard_shortcuts.profile": "to open author's profile",
202
+  "keyboard_shortcuts.reply": "to reply",
203
+  "keyboard_shortcuts.requests": "to open follow requests list",
204
+  "keyboard_shortcuts.search": "to focus search",
205
+  "keyboard_shortcuts.start": "to open \"get started\" column",
206
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
207
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
208
+  "keyboard_shortcuts.toot": "to start a brand new toot",
209
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
210
+  "keyboard_shortcuts.up": "to move up in the list",
211
+  "lightbox.close": "Close",
212
+  "lightbox.next": "Next",
213
+  "lightbox.previous": "Previous",
214
+  "lightbox.view_context": "View context",
215
+  "lists.account.add": "Add to list",
216
+  "lists.account.remove": "Remove from list",
217
+  "lists.delete": "Delete list",
218
+  "lists.edit": "Edit list",
219
+  "lists.edit.submit": "Change title",
220
+  "lists.new.create": "Add list",
221
+  "lists.new.title_placeholder": "New list title",
222
+  "lists.search": "Search among people you follow",
223
+  "lists.subheading": "Your lists",
224
+  "loading_indicator.label": "Loading...",
225
+  "media_gallery.toggle_visible": "Toggle visibility",
226
+  "missing_indicator.label": "Not found",
227
+  "missing_indicator.sublabel": "This resource could not be found",
228
+  "mute_modal.hide_notifications": "Hide notifications from this user?",
229
+  "navigation_bar.apps": "Mobile apps",
230
+  "navigation_bar.blocks": "Blocked users",
231
+  "navigation_bar.community_timeline": "Local timeline",
232
+  "navigation_bar.compose": "Compose new toot",
233
+  "navigation_bar.direct": "Direct messages",
234
+  "navigation_bar.discover": "Discover",
235
+  "navigation_bar.domain_blocks": "Hidden domains",
236
+  "navigation_bar.edit_profile": "Edit profile",
237
+  "navigation_bar.favourites": "Squeaks",
238
+  "navigation_bar.filters": "Muted words",
239
+  "navigation_bar.follow_requests": "Follow requests",
240
+  "navigation_bar.follows_and_followers": "Follows and followers",
241
+  "navigation_bar.info": "About this server",
242
+  "navigation_bar.keyboard_shortcuts": "Hotkeys",
243
+  "navigation_bar.lists": "Lists",
244
+  "navigation_bar.logout": "Logout",
245
+  "navigation_bar.mutes": "Muted users",
246
+  "navigation_bar.personal": "Personal",
247
+  "navigation_bar.pins": "Pinned toots",
248
+  "navigation_bar.preferences": "Preferences",
249
+  "navigation_bar.profile_directory": "Profile directory",
250
+  "navigation_bar.public_timeline": "Federated timeline",
251
+  "navigation_bar.security": "Security",
252
+  "notification.favourite": "{name} squeaked your status",
253
+  "notification.follow": "{name} followed you",
254
+  "notification.mention": "{name} mentioned you",
255
+  "notification.poll": "A poll you have voted in has ended",
256
+  "notification.reblog": "{name} pumped your status",
257
+  "notifications.clear": "Clear notifications",
258
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
259
+  "notifications.column_settings.alert": "Desktop notifications",
260
+  "notifications.column_settings.favourite": "Squeaks:",
261
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
262
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
263
+  "notifications.column_settings.filter_bar.show": "Show",
264
+  "notifications.column_settings.follow": "New followers:",
265
+  "notifications.column_settings.mention": "Mentions:",
266
+  "notifications.column_settings.poll": "Poll results:",
267
+  "notifications.column_settings.push": "Push notifications",
268
+  "notifications.column_settings.reblog": "Pumps:",
269
+  "notifications.column_settings.show": "Show in column",
270
+  "notifications.column_settings.sound": "Play sound",
271
+  "notifications.filter.all": "All",
272
+  "notifications.filter.boosts": "Pumps",
273
+  "notifications.filter.favourites": "Squeaks",
274
+  "notifications.filter.follows": "Follows",
275
+  "notifications.filter.mentions": "Mentions",
276
+  "notifications.filter.polls": "Poll results",
277
+  "notifications.group": "{count} notifications",
278
+  "poll.closed": "Closed",
279
+  "poll.refresh": "Refresh",
280
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
281
+  "poll.vote": "Vote",
282
+  "poll_button.add_poll": "Add a poll",
283
+  "poll_button.remove_poll": "Remove poll",
284
+  "privacy.change": "Adjust status privacy",
285
+  "privacy.direct.long": "Post to mentioned users only",
286
+  "privacy.direct.short": "Direct",
287
+  "privacy.private.long": "Post to followers only",
288
+  "privacy.private.short": "Followers-only",
289
+  "privacy.public.long": "Post to public timelines",
290
+  "privacy.public.short": "Public",
291
+  "privacy.unlisted.long": "Do not post to public timelines",
292
+  "privacy.unlisted.short": "Unlisted",
293
+  "regeneration_indicator.label": "Loading…",
294
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
295
+  "relative_time.days": "{number}d",
296
+  "relative_time.hours": "{number}h",
297
+  "relative_time.just_now": "now",
298
+  "relative_time.minutes": "{number}m",
299
+  "relative_time.seconds": "{number}s",
300
+  "reply_indicator.cancel": "Cancel",
301
+  "report.forward": "Forward to {target}",
302
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
303
+  "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
304
+  "report.placeholder": "Additional comments",
305
+  "report.submit": "Submit",
306
+  "report.target": "Reporting {target}",
307
+  "search.placeholder": "Search",
308
+  "search_popout.search_format": "Advanced search format",
309
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, squeaked, pumped, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
310
+  "search_popout.tips.hashtag": "hashtag",
311
+  "search_popout.tips.status": "status",
312
+  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
313
+  "search_popout.tips.user": "user",
314
+  "search_results.accounts": "People",
315
+  "search_results.hashtags": "Hashtags",
316
+  "search_results.statuses": "Toots",
317
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
318
+  "status.admin_account": "Open moderation interface for @{name}",
319
+  "status.admin_status": "Open this status in the moderation interface",
320
+  "status.block": "Block @{name}",
321
+  "status.cancel_reblog_private": "Unpump",
322
+  "status.cannot_reblog": "This post cannot be pumped",
323
+  "status.copy": "Copy link to status",
324
+  "status.delete": "Delete",
325
+  "status.detailed_status": "Detailed conversation view",
326
+  "status.direct": "Direct message @{name}",
327
+  "status.embed": "Embed",
328
+  "status.favourite": "Squeak",
329
+  "status.filtered": "Filtered",
330
+  "status.load_more": "Load more",
331
+  "status.media_hidden": "Media hidden",
332
+  "status.mention": "Mention @{name}",
333
+  "status.more": "More",
334
+  "status.mute": "Mute @{name}",
335
+  "status.mute_conversation": "Mute conversation",
336
+  "status.open": "Expand this status",
337
+  "status.pin": "Pin on profile",
338
+  "status.pinned": "Pinned toot",
339
+  "status.read_more": "Read more",
340
+  "status.reblog": "Pump",
341
+  "status.reblog_private": "Pump to original audience",
342
+  "status.reblogged_by": "{name} pumped",
343
+  "status.reblogs.empty": "No one has pumped this toot yet. When someone does, they will show up here.",
344
+  "status.redraft": "Delete & re-draft",
345
+  "status.reply": "Reply",
346
+  "status.replyAll": "Reply to thread",
347
+  "status.report": "Report @{name}",
348
+  "status.sensitive_warning": "Sensitive content",
349
+  "status.share": "Share",
350
+  "status.show_less": "Show less",
351
+  "status.show_less_all": "Show less for all",
352
+  "status.show_more": "Show more",
353
+  "status.show_more_all": "Show more for all",
354
+  "status.show_thread": "Show thread",
355
+  "status.unmute_conversation": "Unmute conversation",
356
+  "status.unpin": "Unpin from profile",
357
+  "suggestions.dismiss": "Dismiss suggestion",
358
+  "suggestions.header": "You might be interested in…",
359
+  "tabs_bar.federated_timeline": "Federated",
360
+  "tabs_bar.home": "Home",
361
+  "tabs_bar.local_timeline": "Local",
362
+  "tabs_bar.notifications": "Notifications",
363
+  "tabs_bar.search": "Search",
364
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
365
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
366
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
367
+  "time_remaining.moments": "Moments remaining",
368
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
369
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
370
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
371
+  "upload_area.title": "Drag & drop to upload",
372
+  "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
373
+  "upload_error.limit": "File upload limit exceeded.",
374
+  "upload_error.poll": "File upload not allowed with polls.",
375
+  "upload_form.description": "Describe for the visually impaired",
376
+  "upload_form.focus": "Change preview",
377
+  "upload_form.undo": "Delete",
378
+  "upload_progress.label": "Uploading...",
379
+  "video.close": "Close video",
380
+  "video.exit_fullscreen": "Exit full screen",
381
+  "video.expand": "Expand video",
382
+  "video.fullscreen": "Full screen",
383
+  "video.hide": "Hide video",
384
+  "video.mute": "Mute sound",
385
+  "video.pause": "Pause",
386
+  "video.play": "Play",
387
+  "video.unmute": "Unmute sound"
388
+}

+ 2
- 0
app/javascript/mastodon/locales/whitelist_dog.json View File

@@ -0,0 +1,2 @@
1
+[
2
+]

+ 2
- 0
app/javascript/mastodon/locales/whitelist_lion.json View File

@@ -0,0 +1,2 @@
1
+[
2
+]

+ 2
- 0
app/javascript/mastodon/locales/whitelist_squeak.json View File

@@ -0,0 +1,2 @@
1
+[
2
+]

+ 2
- 0
app/javascript/styles/contrast-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'contrast';

+ 2
- 0
app/javascript/styles/mastodon-light-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'mastodon-light';

+ 2
- 0
app/javascript/styles/mastodon-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'application';

+ 172
- 5
app/javascript/styles/mastodon/components.scss View File

@@ -714,10 +714,6 @@
714 714
 
715 715
   &.status__content--with-spoiler {
716 716
     white-space: normal;
717
-
718
-    .status__content__text {
719
-      white-space: pre-wrap;
720
-    }
721 717
   }
722 718
 
723 719
   .emojione {
@@ -726,7 +722,9 @@
726 722
     margin: -3px 0 0;
727 723
   }
728 724
 
729
-  p {
725
+  p,
726
+  pre,
727
+  blockquote {
730 728
     margin-bottom: 20px;
731 729
     white-space: pre-wrap;
732 730
 
@@ -735,6 +733,175 @@
735 733
     }
736 734
   }
737 735
 
736
+  h1,
737
+  h2,
738
+  h3,
739
+  h4,
740
+  h5 {
741
+    margin-bottom: 20px;
742
+  }
743
+
744
+  blockquote {
745
+    white-space: normal;
746
+
747
+    p:last-child {
748
+      margin-bottom: 0;
749
+    }
750
+  }
751
+
752
+  ul,
753
+  ol {
754
+    p {
755
+      margin-bottom: 0;
756
+    }
757
+  }
758
+
759
+  &:not(.rich-text) {
760
+    del {
761
+      text-decoration: none;
762
+
763
+      &::before,
764
+      &::after {
765
+        content: '~~';
766
+      }
767
+    }
768
+
769
+    code {
770
+      font-family: inherit;
771
+    }
772
+
773
+    u {
774
+      text-decoration: none;
775
+
776
+      &::before,
777
+      &::after {
778
+        content: '__';
779
+      }
780
+    }
781
+
782
+    h1::before {
783
+      content: '# ';
784
+    }
785
+
786
+    h2::before {
787
+      content: '## ';
788
+    }
789
+
790
+    h3::before {
791
+      content: '### ';
792
+    }
793
+
794
+    h4::before {
795
+      content: '#### ';
796
+    }
797
+
798
+    h5::before {
799
+      content: '##### ';
800
+    }
801
+
802
+    b,
803
+    strong {
804
+      &::before,
805
+      &::after {
806
+        content: '**';
807
+      }
808
+    }
809
+
810
+    em,
811
+    i {
812
+      &::before,
813
+      &::after {
814
+        content: '*';
815
+      }
816
+    }
817
+  }
818
+
819
+  &:not(.rich-blocks) {
820
+    blockquote {
821
+      position: relative;
822
+      padding-left: 1em;
823
+      overflow: hidden;
824
+    }
825
+
826
+    blockquote::before {
827
+      position: absolute;
828
+      content: '>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a>\a';
829
+      white-space: pre-wrap;
830
+      left: 0;
831
+      top: 0;
832
+    }
833
+
834
+    li::before {
835
+      position: absolute;
836
+      content: '*';
837
+      left: 0;
838
+      top: 0;
839
+    }
840
+
841
+    li {
842
+      position: relative;
843
+      padding-left: 1em;
844
+    }
845
+  }
846
+
847
+  &.rich-text {
848
+    h1,
849
+    h2 {
850
+      font-weight: 700;
851
+    }
852
+
853
+    h3,
854
+    h4,
855
+    h5 {
856
+      font-weight: 500;
857
+    }
858
+
859
+    b,
860
+    strong {
861
+      font-weight: 700;
862
+    }
863
+
864
+    em,
865
+    i {
866
+      font-style: italic;
867
+    }
868
+
869
+    sub {
870
+      font-size: smaller;
871
+      text-align: sub;
872
+    }
873
+  }
874
+
875
+  &.rich-blocks {
876
+    h1,
877
+    h2 {
878
+      font-size: 18px;
879
+    }
880
+
881
+    h2 {
882
+      font-size: 16px;
883
+    }
884
+
885
+    blockquote {
886
+      padding-left: 10px;
887
+      border-left: 3px solid $darker-text-color;
888
+      color: $darker-text-color;
889
+    }
890
+
891
+    ul,
892
+    ol {
893
+      margin-left: 1em;
894
+    }
895
+
896
+    ul {
897
+      list-style-type: disc;
898
+    }
899
+
900
+    ol {
901
+      list-style-type: decimal;
902
+    }
903
+  }
904
+
738 905
   a {
739 906
     color: $secondary-text-color;
740 907
     text-decoration: none;

+ 2
- 0
app/javascript/styles/pop-light-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'pop-light';

+ 55
- 0
app/javascript/styles/pop-light.scss View File

@@ -0,0 +1,55 @@
1
+// Commonly used web colors
2
+$black: #3b3633;            // Black
3
+$white: #fafafa;            // White
4
+
5
+$classic-base-color: #49423e;         // Midnight Express
6
+$classic-primary-color: #c9c7c5;      // Echo Blue
7
+$classic-secondary-color: #ebe9e8;    // Pattens Blue
8
+$classic-highlight-color: #48b9c7;    // Summer Sky
9
+
10
+// Differences
11
+$success-green: #3e935b;    // Padua
12
+
13
+$base-overlay-background: $white !default;
14
+$valid-value-color: $success-green !default;
15
+
16
+$ui-base-color: $classic-secondary-color !default;         // Midnight Express
17
+$ui-base-lighter-color: #ababab;
18
+$ui-primary-color: #9a938e;      // Echo Blue
19
+$ui-secondary-color: $classic-base-color !default;    // Pattens Blue
20
+$ui-highlight-color: #48b9c7;    // Summer Sky
21
+
22
+$primary-text-color: $black !default;
23
+$darker-text-color: $classic-base-color !default;
24
+$dark-text-color: #0c0c0c;
25
+$action-button-color: #635d58;
26
+
27
+$error-red: #a3360a;        // Cerise
28
+$warning-red: #f9dfb6;      // Sunset Orange
29
+$gold-star: #faa41a;        // Dark Goldenrod
30
+
31
+$inverted-text-color: $black !default;
32
+$lighter-text-color: $classic-base-color !default;
33
+$light-text-color: #444b5d;
34
+
35
+$base-shadow-color: #3b3633;
36
+$base-overlay-background: #3b3633;
37
+$base-border-color: #fafafa;
38
+$simple-background-color: #fafafa;
39
+$valid-value-color: #3e935b;
40
+$error-value-color: #a3360a;
41
+
42
+//Newly added colors
43
+$account-background-color: $white !default;
44
+
45
+//Invert darkened and lightened colors
46
+@function darken($color, $amount) {
47
+  @return hsl(hue($color), saturation($color), lightness($color) + $amount);
48
+}
49
+
50
+@function lighten($color, $amount) {
51
+  @return hsl(hue($color), saturation($color), lightness($color) - $amount);
52
+}
53
+
54
+@import 'application';
55
+@import 'mastodon-light/diff';

+ 2
- 0
app/javascript/styles/pop-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'pop';

+ 28
- 0
app/javascript/styles/pop.scss View File

@@ -0,0 +1,28 @@
1
+// Commonly used web colors
2
+$black: #3b3633;            // Black
3
+$white: #fafafa;            // White
4
+$success-green: #3e935b;    // Padua
5
+$error-red: #a3360a;        // Cerise
6
+$warning-red: #f9dfb6;      // Sunset Orange
7
+$gold-star: #faa41a;        // Dark Goldenrod
8
+
9
+$base-shadow-color: #3b3633;
10
+$base-overlay-background: #3b3633;
11
+$base-border-color: #fafafa;
12
+$simple-background-color: #fafafa;
13
+$primary-text-color: #fafafa;
14
+$valid-value-color: #3e935b;
15
+$error-value-color: #a3360a;
16
+
17
+// Values from the classic Mastodon UI
18
+$classic-base-color: #49423e;         // Midnight Express
19
+$classic-primary-color: #c9c7c5;      // Echo Blue
20
+$classic-secondary-color: #ebe9e8;    // Pattens Blue
21
+$classic-highlight-color: #48b9c7;    // Summer Sky
22
+
23
+$ui-base-color: #49423e;         // Midnight Express
24
+$ui-primary-color: #c9c7c5;      // Echo Blue
25
+$ui-secondary-color: #ebe9e8;    // Pattens Blue
26
+$ui-highlight-color: #48b9c7;    // Summer Sky
27
+
28
+@import 'application';

+ 2
- 0
app/javascript/styles/werefox-wider.scss View File

@@ -0,0 +1,2 @@
1
+@import 'wide';
2
+@import 'werefox';

+ 28
- 0
app/javascript/styles/werefox.scss View File

@@ -0,0 +1,28 @@
1
+// Commonly used web colors
2
+$black: #3b3633;            // Black
3
+$white: #fafafa;            // White
4
+$success-green: #3e935b;    // Padua
5
+$error-red: #a3360a;        // Cerise
6
+$warning-red: #f9dfb6;      // Sunset Orange
7
+$gold-star: #faa41a;        // Dark Goldenrod
8
+
9
+$base-shadow-color: #999;
10
+$base-overlay-background: #3b3633;
11
+$base-border-color: #fafafa;
12
+$simple-background-color: #fafafa;
13
+$primary-text-color: #fafafa;
14
+$valid-value-color: #3e935b;
15
+$error-value-color: #a3360a;
16
+
17
+// Values from the classic Mastodon UI
18
+$classic-base-color: #2a2a2a;         // WS Black
19
+$classic-primary-color: #aaaaaa;      // WS Light Gray
20
+$classic-secondary-color: #9e9e9e;    // WS Gray
21
+$classic-highlight-color: #1c70ce;    // WS Blue
22
+
23
+$ui-base-color: #2a2a2a;         // WS Black
24
+$ui-primary-color: #aaaaaa;      // WS Light Gray
25
+$ui-secondary-color: #9e9e9e;    // WS Gray
26
+$ui-highlight-color: #1c70ce;    // WS Blue
27
+
28
+@import 'application';

+ 4
- 0
app/javascript/styles/wide.scss View File

@@ -0,0 +1,4 @@
1
+.column {
2
+  flex-grow: 1 !important;
3
+  max-width: 540px;
4
+}

+ 19
- 0
app/lib/activitypub/activity/create.rb View File

@@ -406,6 +406,25 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
406 406
     Account.local.where(username: local_usernames).exists?
407 407
   end
408 408
 
409
+  def related_to_local_activity?
410
+    fetch? || followed_by_local_accounts? || requested_through_relay? ||
411
+      responds_to_followed_account? || addresses_local_accounts?
412
+  end
413
+
414
+  def responds_to_followed_account?
415
+    !replied_to_status.nil? && (replied_to_status.account.local? || replied_to_status.account.passive_relationships.exists?)
416
+  end
417
+
418
+  def addresses_local_accounts?
419
+    return true if @options[:delivered_to_account_id]
420
+
421
+    local_usernames = (as_array(@object['to']) + as_array(@object['cc'])).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
422
+
423
+    return false if local_usernames.empty?
424
+
425
+    Account.local.where(username: local_usernames).exists?
426
+  end
427
+
409 428
   def forward_for_reply
410 429
     return unless @json['signature'].present? && reply_to_local?
411 430
     ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id, [@account.preferred_inbox_url])

+ 135
- 1
app/lib/formatter.rb View File

@@ -260,13 +260,147 @@ class Formatter
260 260
 
261 261
   def link_to_mention(entity, linkable_accounts)
262 262
     acct = entity[:screen_name]
263
+    username, domain = acct.split('@')
263 264
 
264
-    return link_to_account(acct) unless linkable_accounts
265
+    case domain
266
+    when 'twitter.com'
267
+      return link_to_twitter(username)
268
+    when 'tumblr.com'
269
+      return link_to_tumblr(username)
270
+    when 'weasyl.com'
271
+      return link_to_weasyl(username)
272
+    when 'furaffinity.net'
273
+      return link_to_furaffinity(username)
274
+    when 'furrynetwork.com', 'beta.furrynetwork.com'
275
+      return link_to_furrynetwork(username)
276
+    when 'sofurry.com'
277
+      return link_to_sofurry(username)
278
+    when 'inkbunny.net'
279
+      return link_to_inkbunny(username)
280
+    when 'e621.net'
281
+      return link_to_e621(username)
282
+    when 'e926.net'
283
+      return link_to_e926(username)
284
+    when 'f-list.net'
285
+      return link_to_flist(username)
286
+    when 'deviantart.com'
287
+      return link_to_deviantart(username)
288
+    when 'artstation.com'
289
+      return link_to_artstation(username)
290
+    when 'github.com'
291
+      return link_to_github(username)
292
+    when 'gitlab.com'
293
+      return link_to_gitlab(username)
294
+    when 'bitbucket.org'
295
+      return link_to_bitbucket(username)
296
+    when 'telegram.org'
297
+      return link_to_telegram(username)
298
+    when 'picarto.tv'
299
+      return link_to_picarto(username)
300
+    when 'twitch.tv'
301
+      return link_to_twitch(username)
302
+    when 'reddit.com'
303
+      return link_to_reddit(username)
304
+    when 'poizen.me'
305
+      return link_to_poizen(username)
306
+    when 'patreon.com'
307
+      return link_to_patreon(username)
308
+    else
309
+      return link_to_account(acct) unless linkable_accounts
310
+    end
265 311
 
266 312
     account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) }
267 313
     account ? mention_html(account) : "@#{encode(acct)}"
268 314
   end
269 315
 
316
+  def link_to_twitter(username)
317
+    link_to(username, "https://twitter.com/#{username}", "twitter.com")
318
+  end
319
+
320
+  def link_to_tumblr(username)
321
+    link_to(username, "https://#{username}.tumblr.com", "tumblr.com")
322
+  end
323
+
324
+  def link_to_weasyl(username)
325
+    link_to username "https://weasyl.com/~#{username}" "weasyl.com"
326
+  end
327
+
328
+  def link_to_furaffinity(username)
329
+    link_to(username, "https://furaffinity.net/user/#{username}", "furaffinity.net")
330
+  end
331
+
332
+  def link_to_furrynetwork(username)
333
+    link_to(username, "https://furrynetwork.com/#{username}", "furrynetwork.com")
334
+  end
335
+
336
+  def link_to_inkbunny(username)
337
+    link_to(username, "https://inkbunny.net/#{username}", "inkbunny.net")
338
+  end
339
+
340
+  def link_to_sofurry(username)
341
+    link_to(username, "https://#{username}.sofurry.com", "sofurry.com")
342
+  end
343
+
344
+  def link_to_e621(username)
345
+    link_to username "https://e621.net/user/show/#{username}" "e621.net"
346
+  end
347
+
348
+  def link_to_e926(username)
349
+    link_to username "https://e926.net/user/show/#{username}" "e926.net"
350
+  end
351
+
352
+  def link_to_flist(username)
353
+    link_to username "https://f-list.net/c/#{username}" "f-list.net"
354
+  end
355
+
356
+  def link_to_deviantart(username)
357
+    link_to(username, "https://#{username}.deviantart.com", "deviantart.com")
358
+  end
359
+
360
+  def link_to_artstation(username)
361
+    link_to(username, "https://www.artstation.com/#{username}", "artstation.com")
362
+  end
363
+
364
+  def link_to_github(username)
365
+    link_to(username, "https://github.com/#{username}", "github.com")
366
+  end
367
+
368
+  def link_to_gitlab(username)
369
+    link_to(username, "https://gitlab.com/#{username}", "gitlab.com")
370
+  end
371
+
372
+  def link_to_bitbucket(username)
373
+    link_to(username, "https://bitbucket.org/#{username}", "bitbucket.org")
374
+  end
375
+
376
+  def link_to_telegram(username)
377
+    link_to(username, "https://t.me/#{username}", "telegram.org")
378
+  end
379
+
380
+  def link_to_picarto(username)
381
+    link_to(username, "https://picarto.tv/#{username}", "picarto.tv")
382
+  end
383
+
384
+  def link_to_twitch(username)
385
+    link_to(username, "https://twitch.tv/#{username}", "twitch.tv")
386
+  end
387
+
388
+  def link_to_reddit(username)
389
+    link_to(username, "https://reddit.com/u/#{username}", "reddit.com")
390
+  end
391
+
392
+  def link_to_poizen(username)
393
+    link_to(username, "https://poizen.me/#{username}", "poizen.me")
394
+  end
395
+
396
+  def link_to_patreon(username)
397
+    link_to(username, "https://www.patreon.com/#{username}", "patreon.com")
398
+  end
399
+
400
+  def link_to(username, url, domain)
401
+    "<span class=\"h-card\"><a href=\"#{url}\" target=\"blank\" rel=\"noopener noreferrer\" class=\"u-url mention\">@<span>#{username}@#{domain}</span></a></span>"
402
+  end
403
+
270 404
   def link_to_account(acct)
271 405
     username, domain = acct.split('@')
272 406
 

+ 7
- 4
app/lib/sanitize_config.rb View File

@@ -20,11 +20,13 @@ class Sanitize
20 20
     end
21 21
 
22 22
     MASTODON_STRICT ||= freeze_config(
23
-      elements: %w(p br span a),
23
+      elements: %w(p br span a abbr del pre blockquote code b strong u sub i em h1 h2 h3 h4 h5 ul ol li),
24 24
 
25 25
       attributes: {
26
-        'a'    => %w(href rel class),
27
-        'span' => %w(class),
26
+        'a'          => %w(href rel class title),
27
+        'span'       => %w(class),
28
+        'abbr'       => %w(title),
29
+        'blockquote' => %w(cite),
28 30
       },
29 31
 
30 32
       add_attributes: {
@@ -35,7 +37,8 @@ class Sanitize
35 37
       },
36 38
 
37 39
       protocols: {
38
-        'a' => { 'href' => HTTP_PROTOCOLS },
40
+        'a'          => { 'href' => HTTP_PROTOCOLS },
41
+        'blockquote' => { 'cite' => HTTP_PROTOCOLS },
39 42
       },
40 43
 
41 44
       transformers: [

+ 5
- 0
app/lib/user_settings_decorator.rb View File

@@ -34,6 +34,7 @@ class UserSettingsDecorator
34 34
     user.settings['aggregate_reblogs']   = aggregate_reblogs_preference if change?('setting_aggregate_reblogs')
35 35
     user.settings['show_application']    = show_application_preference if change?('setting_show_application')
36 36
     user.settings['advanced_layout']     = advanced_layout_preference if change?('setting_advanced_layout')
37
+    user.settings['strip_formatting']    = strip_formatting_preference if change?('setting_strip_formatting')
37 38
   end
38 39
 
39 40
   def merged_notification_emails
@@ -112,6 +113,10 @@ class UserSettingsDecorator
112 113
     boolean_cast_setting 'setting_advanced_layout'
113 114
   end
114 115
 
116
+  def strip_formatting_preference
117
+    settings['setting_strip_formatting']
118
+  end
119
+
115 120
   def boolean_cast_setting(key)
116 121
     ActiveModel::Type::Boolean.new.cast(settings[key])
117 122
   end

+ 1
- 1
app/models/user.rb View File

@@ -105,7 +105,7 @@ class User < ApplicationRecord
105 105
   delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
106 106
            :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network,
107 107
            :expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
108
-           :advanced_layout, to: :settings, prefix: :setting, allow_nil: false
108
+           :advanced_layout, :strip_formatting, to: :settings, prefix: :setting, allow_nil: false
109 109
 
110 110
   attr_reader :invite_code
111 111
   attr_writer :external

+ 11
- 10
app/serializers/initial_state_serializer.rb View File

@@ -23,16 +23,17 @@ class InitialStateSerializer < ActiveModel::Serializer
23 23
     }
24 24
 
25 25
     if object.current_account
26
-      store[:me]              = object.current_account.id.to_s
27
-      store[:unfollow_modal]  = object.current_account.user.setting_unfollow_modal
28
-      store[:boost_modal]     = object.current_account.user.setting_boost_modal
29
-      store[:delete_modal]    = object.current_account.user.setting_delete_modal
30
-      store[:auto_play_gif]   = object.current_account.user.setting_auto_play_gif
31
-      store[:display_media]   = object.current_account.user.setting_display_media
32
-      store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
33
-      store[:reduce_motion]   = object.current_account.user.setting_reduce_motion
34
-      store[:advanced_layout] = object.current_account.user.setting_advanced_layout
35
-      store[:is_staff]        = object.current_account.user.staff?
26
+      store[:me]               = object.current_account.id.to_s
27
+      store[:unfollow_modal]   = object.current_account.user.setting_unfollow_modal
28
+      store[:boost_modal]      = object.current_account.user.setting_boost_modal
29
+      store[:delete_modal]     = object.current_account.user.setting_delete_modal
30
+      store[:auto_play_gif]    = object.current_account.user.setting_auto_play_gif
31
+      store[:display_media]    = object.current_account.user.setting_display_media
32
+      store[:expand_spoilers]  = object.current_account.user.setting_expand_spoilers
33
+      store[:reduce_motion]    = object.current_account.user.setting_reduce_motion
34
+      store[:advanced_layout]  = object.current_account.user.setting_advanced_layout
35
+      store[:is_staff]         = object.current_account.user.staff?
36
+      store[:strip_formatting] = object.current_account.user.setting_strip_formatting
36 37
     end
37 38
 
38 39
     store

+ 5
- 0
app/serializers/rest/preferences_serializer.rb View File

@@ -7,6 +7,7 @@ class REST::PreferencesSerializer < ActiveModel::Serializer
7 7
 
8 8
   attribute :reading_default_sensitive_media, key: 'reading:expand:media'
9 9
   attribute :reading_default_sensitive_text, key: 'reading:expand:spoilers'
10
+  attribute :reading_strip_formatting, key: 'reading:formatting:strip'
10 11
 
11 12
   def posting_default_privacy
12 13
     object.user.setting_default_privacy
@@ -27,4 +28,8 @@ class REST::PreferencesSerializer < ActiveModel::Serializer
27 28
   def reading_default_sensitive_text
28 29
     object.user.setting_expand_spoilers
29 30
   end
31
+
32
+  def reading_strip_formatting
33
+    object.user.setting_strip_formatting
34
+  end
30 35
 end

+ 1
- 1
app/views/stream_entries/_detailed_status.html.haml View File

@@ -15,7 +15,7 @@
15 15
 
16 16
   = account_action_button(status.account)
17 17
 
18
-  .status__content.emojify<
18
+  .status__content.emojify{ class: text_formatting_classes }<
19 19
     - if status.spoiler_text?
20 20
       %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
21 21
         %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}&nbsp;

+ 1
- 1
app/views/stream_entries/_simple_status.html.haml View File

@@ -19,7 +19,7 @@
19 19
           %span.display-name__account
20 20
             = acct(status.account)
21 21
             = fa_icon('lock') if status.account.locked?
22
-  .status__content.emojify<
22
+  .status__content.emojify{ class: text_formatting_classes }<
23 23
     - if status.spoiler_text?
24 24
       %p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
25 25
         %span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}&nbsp;

+ 3
- 0
config/application.rb View File

@@ -36,6 +36,9 @@ module Mastodon
36 36
     # All translations from config/locales/*.rb,yml are auto loaded.
37 37
     # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
38 38
     config.i18n.available_locales = [
39
+      :dog,
40
+      :lion,
41
+      :squeak,
39 42
       :en,
40 43
       :ar,
41 44
       :ast,

+ 9
- 0
config/initializers/source.rb View File

@@ -0,0 +1,9 @@
1
+# frozen_string_literal: true
2
+module Mastodon
3
+  module Version
4
+    module_function
5
+    def source_base_url
6
+      'https://git.asonix.dog/asonix/mastodon'
7
+    end
8
+  end
9
+end

+ 17
- 0
config/locales/activerecord.dog.yml View File

@@ -0,0 +1,17 @@
1
+---
2
+dog:
3
+  activerecord:
4
+    attributes:
5
+      poll:
6
+        expires_at: Deadline
7
+        options: Choices
8
+    errors:
9
+      models:
10
+        account:
11
+          attributes:
12
+            username:
13
+              invalid: only letters, numbers and underscores
14
+        status:
15
+          attributes:
16
+            reblog:
17
+              taken: of status already exists

+ 17
- 0
config/locales/activerecord.lion.yml View File

@@ -0,0 +1,17 @@
1
+---
2
+lion:
3
+  activerecord:
4
+    attributes:
5
+      poll:
6
+        expires_at: Deadline
7
+        options: Choices
8
+    errors:
9
+      models:
10
+        account:
11
+          attributes:
12
+            username:
13
+              invalid: only letters, numbers and underscores
14
+        status:
15
+          attributes:
16
+            reblog:
17
+              taken: of status already exists

+ 17
- 0
config/locales/activerecord.squeak.yml View File

@@ -0,0 +1,17 @@
1
+---
2
+squeak:
3
+  activerecord:
4
+    attributes:
5
+      poll:
6
+        expires_at: Deadline
7
+        options: Choices
8
+    errors:
9
+      models:
10
+        account:
11
+          attributes:
12
+            username:
13
+              invalid: only letters, numbers and underscores
14
+        status:
15
+          attributes:
16
+            reblog:
17
+              taken: of status already exists

+ 86
- 0
config/locales/devise.dog.yml View File

@@ -0,0 +1,86 @@
1
+---
2
+dog:
3
+  devise:
4
+    confirmations:
5
+      confirmed: Your email address has been successfully confirmed.
6
+      send_instructions: You will receive an email with instructions for how to confirm your email address in a few minutes. Please check your spam folder if you didn't receive this email.
7
+      send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes. Please check your spam folder if you didn't receive this email.
8
+    failure:
9
+      already_authenticated: You are already signed in.
10
+      inactive: Your account is not activated yet.
11
+      invalid: Invalid %{authentication_keys} or password.
12
+      last_attempt: You have one more attempt before your account is locked.
13
+      locked: Your account is locked.
14
+      not_found_in_database: Invalid %{authentication_keys} or password.
15
+      pending: Your account is still under review.
16
+      timeout: Your session expired. Please sign in again to continue.
17
+      unauthenticated: You need to sign in or sign up before continuing.
18
+      unconfirmed: You have to confirm your email address before continuing.
19
+    mailer:
20
+      confirmation_instructions:
21
+        action: Verify email address
22
+        action_with_app: Confirm and return to %{app}
23
+        explanation: You have created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email.
24
+        explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your e-mail address, we will review your application. You can't login until then. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email.
25
+        extra_html: Please also check out <a href="%{terms_path}">the rules of the server</a> and <a href="%{policy_path}">our terms of service</a>.
26
+        subject: 'Mastodon: Confirmation instructions for %{instance}'
27
+        title: Verify email address
28
+      email_changed:
29
+        explanation: 'The email address for your account is being changed to:'
30
+        extra: If you did not change your email, it is likely that someone has gained access to your account. Please change your password immediately or contact the instance admin if you're locked out of your account.
31
+        subject: 'Mastodon: Email changed'
32
+        title: New email address
33
+      password_change:
34
+        explanation: The password for your account has been changed.
35
+        extra: If you did not change your password, it is likely that someone has gained access to your account. Please change your password immediately or contact the instance admin if you're locked out of your account.
36
+        subject: 'Mastodon: Password changed'
37
+        title: Password changed
38
+      reconfirmation_instructions:
39
+        explanation: Confirm the new address to change your email.
40
+        extra: If this change wasn't initiated by you, please ignore this email. The email address for the Mastodon account won't change until you access the link above.
41
+        subject: 'Mastodon: Confirm email for %{instance}'
42
+        title: Verify email address
43
+      reset_password_instructions:
44
+        action: Change password
45
+        explanation: You requested a new password for your account.
46
+        extra: If you didn't request this, please ignore this email. Your password won't change until you access the link above and create a new one.
47
+        subject: 'Mastodon: Reset password instructions'
48
+        title: Password reset
49
+      unlock_instructions:
50
+        subject: 'Mastodon: Unlock instructions'
51
+    omniauth_callbacks:
52
+      failure: Could not authenticate you from %{kind} because "%{reason}".
53
+      success: Successfully authenticated from %{kind} account.
54
+    passwords: