diff --git a/Gemfile.lock b/Gemfile.lock index c4c8d9904..4960f1b4d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -346,7 +346,9 @@ GEM mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2020.0512) - mimemagic (0.3.5) + mimemagic (0.3.10) + nokogiri (~> 1) + rake mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.14.2) @@ -808,3 +810,9 @@ DEPENDENCIES webpacker (~> 5.2) webpush xorcist (~> 1.1) + +RUBY VERSION + ruby 2.6.5p114 + +BUNDLED WITH + 1.17.2 diff --git a/README.md b/README.md index 3c6daf4f8..f9d555b0e 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,90 @@ -![Mastodon](https://i.imgur.com/NhZc40l.png) -======== +# Hometown: a Mastodon fork -[![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases] -[![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci] -[![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate] -[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin] -[![Docker Pulls](https://img.shields.io/docker/pulls/tootsuite/mastodon.svg)][docker] +photo of a village of stone huts nestled in a lush green valley -[releases]: https://github.com/tootsuite/mastodon/releases -[circleci]: https://circleci.com/gh/tootsuite/mastodon -[code_climate]: https://codeclimate.com/github/tootsuite/mastodon -[crowdin]: https://crowdin.com/project/mastodon -[docker]: https://hub.docker.com/r/tootsuite/mastodon/ +Photo by [Joana Mujollari](https://www.flickr.com/photos/141654969@N04/26777339042/), CC0 / Public Domain. -Mastodon is a **free, open-source social network server** based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub)! +Mastodon is a **free, open-source social network server** based on ActivityPub. This is *not* the official version of Mastodon; this is a separate version (i.e. a fork) maintained by [Darius Kazemi](https://friend.camp/@darius). For more information on Mastodon, you can see the [official website](https://joinmastodon.org) and the [upstream repo](https://github.com/tootsuite/mastodon). -Click below to **learn more** in a video: +__Hometown__ is a light weight fork of Mastodon. This fork is based on the principle of: minimum code change for maximum user experience change. By our best understanding, our major changes are not wanted by the Mastodon project, hence maintaining this fork instead of trying to commit the changes to Mastodon. -[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo] +Please [check out our wiki](https://github.com/hometown-fork/hometown/wiki) for a list of Hometown-exclusive features. Some but not all of these are covered in this document. -[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE +You can also find [a list of running Hometown instances](https://github.com/hometown-fork/hometown/wiki/Hometown-servers), don't hesitate to open an issue to add yours! -## Navigation +## Support this project -- [Project homepage 🐘](https://joinmastodon.org) -- [Support the development via Patreon][patreon] -- [View sponsors](https://joinmastodon.org/sponsors) -- [Blog](https://blog.joinmastodon.org) -- [Documentation](https://docs.joinmastodon.org) -- [Browse Mastodon servers](https://joinmastodon.org/#getting-started) -- [Browse Mastodon apps](https://joinmastodon.org/apps) +Please consider [supporting Hometown by pledging to my Patreon](https://www.patreon.com/tinysubversions), which supports all my open source projects including this one! -[patreon]: https://www.patreon.com/mastodon +Of course this project couldn't exist without Mastodon so maybe [support the Mastodon project Patreon](https://www.patreon.com/mastodon) too. -## Features +## Migrating from Mastodon to Hometown - +Please see [this article in the wiki](https://github.com/hometown-fork/hometown/wiki/Initial-migration) for directions on migration from Mastodon to Hometown. -**No vendor lock-in: Fully interoperable with any conforming platform** +## Local only posting -It doesn't have to be Mastodon, whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/) +Mastodon right now is designed to get your messages out to the entire fediverse. This is great, but there is a huge need for more private communities. And in a federated network I think it makes the most sense for your home server to be that community (hence "Hometown"). -**Real-time, chronological timeline updates** +**In the context of Hometown, local only posting is a per-post security option that lets you set whether that post can federate out to other servers or not.** -See the updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well! +I've been running Friend Camp, a Mastodon fork with local only posting, for about a year. Being able to have conversations with people on your server that don't federate is a hugely liberating thing. It allows inside jokes to develop. It allows people the freedom to complain about things that they wouldn't necessarily feel comfortable leaving a trusted server (cops, employers, etc). It also lets us do things like have a server-wide movie night where we flood the local timeline with posts about the movie, and it doesn't pollute the rest of the Fediverse. -**Media attachments like images and short videos** +This feature is based on [the work of Renato Lond](https://github.com/tootsuite/mastodon/pull/8427), which is itself based on a feature in the [Mastodon Glitch Edition](https://glitch-soc.github.io/docs/) fork. -Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos are looped - like vines! +## Reading more content types -**Safety and moderation tools** +Mastodon is microblogging software, meant for Twitter-style shortform posting. -Private posts, locked accounts, phrase filtering, muting, blocking and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/) +Hometown is microblogging for _writing_, but its goal is to accept many content types for _reading_. So while I don't plan to let Hometown users publish massive blog posts, I would like your Hometown instance to be your one-stop shop for viewing all sorts of things on the Fediverse. -**OAuth2 and a straightforward REST API** +For Hometown this means if you subscribe to a service that sends out `Article` objects over ActivityPub (such as a blog on [Write As](https://write.as)), then those full articles render in your home timeline, behind a cut for length. Also, Hometown will render a variety of rich text like _italic_ and **bold**. -Mastodon acts as an OAuth2 provider so 3rd party apps can use the REST and Streaming APIs, resulting in a rich app ecosystem with a lot of choices! +Click on this GIF for a brief video demo: -## Deployment +Video demo of someone clicking 'read article' on an incoming article post, which then renders a full article. -**Tech stack:** +This is based on rich text work by [Thibaut Girka](https://sitedethib.com), and my own work on `Article` support. -- **Ruby on Rails** powers the REST API and other web pages -- **React.js** and Redux are used for the dynamic parts of the interface -- **Node.js** powers the streaming API +### It's more than just reading more stuff -**Requirements:** +Reading more content types also helps make the fediverse better. ActivityPub supports all kinds of content, but most ActivityPub servers shoehorn all their content into `Note` because that's the type that Mastodon treats as first-class. This has important implications for the fediverse and also on your day to do user experience. -- **PostgreSQL** 9.5+ -- **Redis** 4+ -- **Ruby** 2.5+ -- **Node.js** 10.13+ +Take the "quote tweet" debate for example. -The repository includes deployment configurations for **Docker and docker-compose**, but also a few specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. The [**stand-alone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation. +Twitter has a feature called "quote tweeting" that lets you embed what someone else tweets, with your own comment right next to it. It's really useful for provide commentary in context, like this, where I point people to a sale and they can read both my comment on the sale and the original tweet about the sale in one post: -A **Vagrant** configuration is included for development purposes. +An example of a quote tweet from Twitter. -## Contributing +But it's also open to abuse with people quote-tweeting things they disagree with to encourage a pile-on from their followers. There's been a lot of debate among Mastodon users as to whether the good of this feature outweighs the bad. So far, Mastodon has avoided implementing quoting. -Mastodon is **free, open-source software** licensed under **AGPLv3**. +What does this have to do with content types? Well, if we support an `Article` content type and a `Note` content type, we can support quoting for an `Article` but not for a `Note`. In practice this means that you can quote blog posts and news articles, but you can't quote a quick personal microblog note. -You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository, or submit translations using Crowdin. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon). +> Hometown doesn't support quoting articles yet... but it will. -**IRC channel**: #mastodon on irc.freenode.net +## Better list management + +If Hometown is going to be a universal reader, you're going to need better control over organizing your feeds than mainline Mastodon provides. + +I've introduced a new kind of [exclusive list](https://github.com/hometown-fork/hometown/wiki/Exclusive-lists). In vanilla Mastodon, if you add an account to your "friends I like" list, posts from people on that list appear on that list. But they also appear on your home timeline, and maybe you don't want that! You'd rather treat your "friends I like" list as your "real" home timeline, and then check your home timeline when you're bored. Check out [more details about exclusive lists on the wiki](https://github.com/hometown-fork/hometown/wiki/Exclusive-lists). + +## Better accessibility defaults + +Look, right now this pretty much just means that we underline hyperlinks by default. I'm of course open to implementing other obviously beneficial accessibilty defaults that Mastodon itself doesn't implement. + +## Hometown is still 99.999% Mastodon + +I don't intend to stray very far from mainline Mastodon with this fork. If you want something that provides a ton of new features and widgets and stuff, the [Mastodon Glitch Edition](https://glitch-soc.github.io/docs/) fork is a wondrous kitchen sink of major and minor tweaks. + +Part of why I don't want to stray far from mainline Mastodon is that this project is going to be just me for the foreseeable future, and I'd like to keep it up to date with new Mastodon versions as easily as possible. The less code I change from Mastodon, the easier that is. Hence the principle of "minimum code change for maximum user experience change." + +## Versioning + +Hometown uses [semantic versioning](https://semver.org) and follows a versioning convention like `v1.0.0+2.9.3`. The 1.0.0 part is the actual Hometown version number, and then the 2.9.3 after the + sign is what's known in semantic versioning as "build metadata". It just means that a particular release is synchronized with Mastodon version 2.9.3, so for example an upgrade from `v1.0.0+2.9.2` to `v1.0.0+2.9.3` would upgrade _Mastodon_ but not provide any new Hometown features or fixes. + +## Contributing to Hometown + +Setting up your Hometown development environment is [exactly like setting up your Mastodon development environment](https://docs.joinmastodon.org/dev/overview/). Pull requests should be made to the `hometown-dev` branch, which is our default branch in Github. ## License diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index ca08f71ba..67fa2d1a2 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -28,7 +28,11 @@ class AccountsController < ApplicationController return end - @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses? + if current_user.nil? + @pinned_statuses = cache_collection(@account.pinned_statuses.without_local_only, Status) if show_pinned_statuses? + else + @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses? + end @statuses = cached_filtered_status_page @rss_url = rss_url diff --git a/app/controllers/api/v1/lists_controller.rb b/app/controllers/api/v1/lists_controller.rb index e5ac45fef..938811bd2 100644 --- a/app/controllers/api/v1/lists_controller.rb +++ b/app/controllers/api/v1/lists_controller.rb @@ -38,6 +38,6 @@ class Api::V1::ListsController < Api::BaseController end def list_params - params.permit(:title, :replies_policy) + params.permit(:title, :replies_policy, :is_exclusive) end end diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 134217734..37b75a5b1 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -99,10 +99,6 @@ module AccountsHelper end def svg_logo - content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo'), 'viewBox' => '0 0 216.4144 232.00976') - end - - def svg_logo_full - content_tag(:svg, tag(:use, 'xlink:href' => '#mastodon-svg-logo-full'), 'viewBox' => '0 0 713.35878 175.8678') + content_tag(:svg, tag(:use, 'xlink:href' => '#hometownlogo'), 'viewBox' => '0 0 216.4144 232.00976') end end diff --git a/app/javascript/images/defaultmascot.svg b/app/javascript/images/defaultmascot.svg new file mode 100644 index 000000000..e1381af8a --- /dev/null +++ b/app/javascript/images/defaultmascot.svg @@ -0,0 +1 @@ +Asset 5 diff --git a/app/javascript/images/hometown.svg b/app/javascript/images/hometown.svg new file mode 100644 index 000000000..055a5c40f --- /dev/null +++ b/app/javascript/images/hometown.svg @@ -0,0 +1 @@ + diff --git a/app/javascript/mastodon/actions/lists.js b/app/javascript/mastodon/actions/lists.js index 5ab922436..b4d2679a9 100644 --- a/app/javascript/mastodon/actions/lists.js +++ b/app/javascript/mastodon/actions/lists.js @@ -10,9 +10,10 @@ export const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST'; export const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS'; export const LISTS_FETCH_FAIL = 'LISTS_FETCH_FAIL'; -export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE'; -export const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET'; -export const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP'; +export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE'; +export const LIST_EDITOR_IS_EXCLUSIVE_CHANGE = 'LIST_EDITOR_IS_EXCLUSIVE_CHANGE'; +export const LIST_EDITOR_RESET = 'LIST_EDITOR_RESET'; +export const LIST_EDITOR_SETUP = 'LIST_EDITOR_SETUP'; export const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST'; export const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS'; @@ -100,13 +101,14 @@ export const fetchListsFail = error => ({ }); export const submitListEditor = shouldReset => (dispatch, getState) => { - const listId = getState().getIn(['listEditor', 'listId']); - const title = getState().getIn(['listEditor', 'title']); + const listId = getState().getIn(['listEditor', 'listId']); + const title = getState().getIn(['listEditor', 'title']); + const isExclusive = getState().getIn(['listEditor', 'isExclusive']); if (listId === null) { dispatch(createList(title, shouldReset)); } else { - dispatch(updateList(listId, title, shouldReset)); + dispatch(updateList(listId, title, shouldReset, isExclusive)); } }; @@ -124,6 +126,11 @@ export const changeListEditorTitle = value => ({ value, }); +export const changeListEditorIsExclusive = value => ({ + type: LIST_EDITOR_IS_EXCLUSIVE_CHANGE, + value, +}); + export const createList = (title, shouldReset) => (dispatch, getState) => { dispatch(createListRequest()); @@ -150,10 +157,10 @@ export const createListFail = error => ({ error, }); -export const updateList = (id, title, shouldReset, replies_policy) => (dispatch, getState) => { +export const updateList = (id, title, shouldReset, replies_policy, isExclusive) => (dispatch, getState) => { dispatch(updateListRequest(id)); - api(getState).put(`/api/v1/lists/${id}`, { title, replies_policy }).then(({ data }) => { + api(getState).put(`/api/v1/lists/${id}`, { title, replies_policy, is_exclusive: !!isExclusive }).then(({ data }) => { dispatch(updateListSuccess(data)); if (shouldReset) { diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 295e83f58..e08b9b9c2 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -461,7 +461,7 @@ class Status extends ImmutablePureComponent { return ( -
+
{prepend}
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 0f05dda34..3097334d5 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -315,7 +315,7 @@ class StatusActionBar extends ImmutablePureComponent { reblogTitle = intl.formatMessage(messages.cannot_reblog); } - const shareButton = ('share' in navigator) && publicStatus && ( + const shareButton = ('share' in navigator) && publicStatus && federated && ( ); @@ -326,6 +326,7 @@ class StatusActionBar extends ImmutablePureComponent { {shareButton} +
); + const readArticleButton = ( + + ); + if (status.get('spoiler_text').length > 0) { let mentionsPlaceholder = ''; @@ -218,12 +224,12 @@ export default class StatusContent extends React.PureComponent { mentionsPlaceholder =
{mentionLinks}
; } - return ( + const output = [
{mentionsPlaceholder} @@ -231,10 +237,15 @@ export default class StatusContent extends React.PureComponent {
{!hidden && !!status.get('poll') && } - {renderViewThread && showThreadButton} -
- ); +
, + ]; + + if (status.get('activity_pub_type') === 'Article' && !this.props.expanded) { + output.push(readArticleButton); + } + + return output; } else if (this.props.onClick) { const output = [
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index b47ebed62..b05d1968f 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -38,7 +38,7 @@ const messages = defineMessages({ showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' }, enableNotifications: { id: 'account.enable_notifications', defaultMessage: 'Notify me when @{name} posts' }, disableNotifications: { id: 'account.disable_notifications', defaultMessage: 'Stop notifying me when @{name} posts' }, - pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, + pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index 6b52defe4..efdbd649c 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -123,8 +123,8 @@ export default class Header extends ImmutablePureComponent { {!hideTabs && (
- - + +
)} diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js index fa4239d6f..7cbf50463 100644 --- a/app/javascript/mastodon/features/account_timeline/index.js +++ b/app/javascript/mastodon/features/account_timeline/index.js @@ -37,7 +37,7 @@ const mapStateToProps = (state, { params: { accountId }, withReplies = false }) }; const RemoteHint = ({ url }) => ( - } /> + } /> ); RemoteHint.propTypes = { @@ -143,7 +143,7 @@ class AccountTimeline extends ImmutablePureComponent { } else if (remote && statusIds.isEmpty()) { emptyMessage = ; } else { - emptyMessage = ; + emptyMessage = ; } const remoteMessage = remote ? : null; diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.js index 07d92bb7e..4ff0b7b94 100644 --- a/app/javascript/mastodon/features/compose/components/action_bar.js +++ b/app/javascript/mastodon/features/compose/components/action_bar.js @@ -6,7 +6,7 @@ import { defineMessages, injectIntl } from 'react-intl'; const messages = defineMessages({ edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, - pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, + pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index f30fa520d..961081d00 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -21,13 +21,14 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { length } from 'stringz'; import { countableText } from '../util/counter'; import Icon from 'mastodon/components/icon'; +import { maxChars } from '../../../initial_state'; const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d'; const messages = defineMessages({ placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }, spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' }, - publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }, + publish: { id: 'compose_form.publish', defaultMessage: 'Post' }, publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, }); @@ -88,7 +89,7 @@ class ComposeForm extends ImmutablePureComponent { const fulltext = this.getFulltextForCharacterCounting(); const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0; - return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia)); + return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia)); } handleSubmit = () => { @@ -252,7 +253,7 @@ class ComposeForm extends ImmutablePureComponent {
-
+
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js index dc4f48060..c2781095e 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -359,11 +359,11 @@ class EmojiPickerDropdown extends React.PureComponent { return (
- {button || 🙂} + src={`${assetHost}/emoji/1f600.svg`} + />
diff --git a/app/javascript/mastodon/features/compose/components/federation_dropdown.js b/app/javascript/mastodon/features/compose/components/federation_dropdown.js index adcf60c7c..99a3c0164 100644 --- a/app/javascript/mastodon/features/compose/components/federation_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/federation_dropdown.js @@ -10,9 +10,9 @@ import classNames from 'classnames'; const messages = defineMessages({ federate_short: { id: 'federation.federated.short', defaultMessage: 'Federated' }, - federate_long: { id: 'federation.federated.long', defaultMessage: 'Allow toot to reach other instances' }, + federate_long: { id: 'federation.federated.long', defaultMessage: 'Allow post to reach other instances' }, local_only_short: { id: 'federation.local_only.short', defaultMessage: 'Local-only' }, - local_only_long: { id: 'federation.local_only.long', defaultMessage: 'Restrict this toot only to my instance' }, + local_only_long: { id: 'federation.local_only.long', defaultMessage: 'Restrict this post only to my instance' }, change_federation: { id: 'federation.change', defaultMessage: 'Adjust status federation' }, }); diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js index 4b4cdff74..7c59eebd2 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.js +++ b/app/javascript/mastodon/features/compose/components/search_results.js @@ -85,7 +85,7 @@ class SearchResults extends ImmutablePureComponent { count += results.get('statuses').size; statuses = (
-
+
{results.get('statuses').map(statusId => )} @@ -95,10 +95,10 @@ class SearchResults extends ImmutablePureComponent { } else if(results.get('statuses') && results.get('statuses').size === 0 && !searchEnabled && !(searchTerm.startsWith('@') || searchTerm.startsWith('#') || searchTerm.includes(' '))) { statuses = (
-
+
- +
); diff --git a/app/javascript/mastodon/features/compose/containers/warning_container.js b/app/javascript/mastodon/features/compose/containers/warning_container.js index bf0660ea9..2cf219caf 100644 --- a/app/javascript/mastodon/features/compose/containers/warning_container.js +++ b/app/javascript/mastodon/features/compose/containers/warning_container.js @@ -42,7 +42,7 @@ const WarningWrapper = ({ needsLockWarning, hashtagWarning, directMessageWarning } if (hashtagWarning) { - return } />; + return } />; } if (directMessageWarning) { diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index e2de8b0e6..deb6748e4 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -26,7 +26,7 @@ const messages = defineMessages({ community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, - compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' }, + compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new post' }, logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' }, logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' }, }); @@ -36,6 +36,25 @@ const mapStateToProps = (state, ownProps) => ({ showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage, }); +let instanceMascot; +if (mascot) { + instanceMascot = ; +} else { + instanceMascot = ; +} + export default @connect(mapStateToProps) @injectIntl class Compose extends React.PureComponent { @@ -129,7 +148,7 @@ class Compose extends React.PureComponent {
- + {instanceMascot}
} diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.js index db8a3f815..23fce4e11 100644 --- a/app/javascript/mastodon/features/favourited_statuses/index.js +++ b/app/javascript/mastodon/features/favourited_statuses/index.js @@ -71,7 +71,7 @@ class Favourites extends ImmutablePureComponent { const { intl, shouldUpdateScroll, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props; const pinned = !!columnId; - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/favourites/index.js b/app/javascript/mastodon/features/favourites/index.js index 75cb00c0e..3636045f0 100644 --- a/app/javascript/mastodon/features/favourites/index.js +++ b/app/javascript/mastodon/features/favourites/index.js @@ -60,7 +60,7 @@ class Favourites extends ImmutablePureComponent { ); } - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index 1b9994612..c874f7908 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -29,7 +29,7 @@ const messages = defineMessages({ blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, - pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, + pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, discover: { id: 'navigation_bar.discover', defaultMessage: 'Discover' }, personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' }, diff --git a/app/javascript/mastodon/features/introduction/index.js b/app/javascript/mastodon/features/introduction/index.js index 5820750a4..28d3c0b58 100644 --- a/app/javascript/mastodon/features/introduction/index.js +++ b/app/javascript/mastodon/features/introduction/index.js @@ -75,22 +75,22 @@ const FrameInteractions = ({ onNext }) => (

-

+

-

+

-

+

- +
); diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.js b/app/javascript/mastodon/features/keyboard_shortcuts/index.js index d278d2b26..8f1631d82 100644 --- a/app/javascript/mastodon/features/keyboard_shortcuts/index.js +++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.js @@ -86,7 +86,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { alt+n - + alt+x @@ -134,7 +134,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { g+p - + g+u diff --git a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js index 3ccab12a8..56842c38f 100644 --- a/app/javascript/mastodon/features/list_editor/components/edit_list_form.js +++ b/app/javascript/mastodon/features/list_editor/components/edit_list_form.js @@ -1,9 +1,10 @@ import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import { changeListEditorTitle, submitListEditor } from '../../../actions/lists'; +import { changeListEditorTitle, changeListEditorIsExclusive, submitListEditor } from '../../../actions/lists'; import IconButton from '../../../components/icon_button'; -import { defineMessages, injectIntl } from 'react-intl'; +import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import Toggle from 'react-toggle'; const messages = defineMessages({ title: { id: 'lists.edit.submit', defaultMessage: 'Change title' }, @@ -17,6 +18,7 @@ const mapStateToProps = state => ({ const mapDispatchToProps = dispatch => ({ onChange: value => dispatch(changeListEditorTitle(value)), onSubmit: () => dispatch(submitListEditor(false)), + onToggle: value => dispatch(changeListEditorIsExclusive(value)), }); export default @connect(mapStateToProps, mapDispatchToProps) @@ -26,6 +28,7 @@ class ListForm extends React.PureComponent { static propTypes = { value: PropTypes.string.isRequired, disabled: PropTypes.bool, + isExclusive: PropTypes.bool, intl: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired, onSubmit: PropTypes.func.isRequired, @@ -44,8 +47,12 @@ class ListForm extends React.PureComponent { this.props.onSubmit(); } + handleToggle = e => { + this.props.onToggle(e.target.checked); + } + render () { - const { value, disabled, intl } = this.props; + const { value, disabled, intl, isExclusive, hello } = this.props; const title = intl.formatMessage(messages.title); @@ -57,6 +64,11 @@ class ListForm extends React.PureComponent { onChange={this.handleChange} /> + + - + diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js index 02b018247..48b2ed9e2 100644 --- a/app/javascript/mastodon/features/list_timeline/index.js +++ b/app/javascript/mastodon/features/list_timeline/index.js @@ -113,7 +113,7 @@ class ListTimeline extends React.PureComponent { } handleEditClick = () => { - this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id })); + this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id, isExclusive: this.props.list.get('is_exclusive') })); } handleDeleteClick = () => { diff --git a/app/javascript/mastodon/features/pinned_statuses/index.js b/app/javascript/mastodon/features/pinned_statuses/index.js index ad5c9cafc..6c0ef7638 100644 --- a/app/javascript/mastodon/features/pinned_statuses/index.js +++ b/app/javascript/mastodon/features/pinned_statuses/index.js @@ -10,7 +10,7 @@ import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; const messages = defineMessages({ - heading: { id: 'column.pins', defaultMessage: 'Pinned toot' }, + heading: { id: 'column.pins', defaultMessage: 'Pinned post' }, }); const mapStateToProps = state => ({ diff --git a/app/javascript/mastodon/features/reblogs/index.js b/app/javascript/mastodon/features/reblogs/index.js index 4becb5fb7..df9079b8e 100644 --- a/app/javascript/mastodon/features/reblogs/index.js +++ b/app/javascript/mastodon/features/reblogs/index.js @@ -60,7 +60,7 @@ class Reblogs extends ImmutablePureComponent { ); } - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index d7d504bc5..3402d83ed 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -18,6 +18,7 @@ const messages = defineMessages({ reblog_private: { id: 'status.reblog_private', defaultMessage: 'Boost with original visibility' }, cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' }, + local_only: { id: 'status.local_only', defaultMessage: 'This post is only visible by other users of your instance' }, favourite: { id: 'status.favourite', defaultMessage: 'Favourite' }, bookmark: { id: 'status.bookmark', defaultMessage: 'Bookmark' }, more: { id: 'status.more', defaultMessage: 'More' }, @@ -189,6 +190,7 @@ class ActionBar extends React.PureComponent { const publicStatus = ['public', 'unlisted'].includes(status.get('visibility')); const mutingConversation = status.get('muted'); + const federated = !status.get('local_only'); const account = status.get('account'); let menu = []; @@ -247,7 +249,7 @@ class ActionBar extends React.PureComponent { } } - const shareButton = ('share' in navigator) && publicStatus && ( + const shareButton = ('share' in navigator) && publicStatus && federated && (
); diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 575ebfce5..9d483689a 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -251,7 +251,7 @@ class DetailedStatus extends ImmutablePureComponent { - + {media} diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 6837450eb..95136ec5a 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -50,7 +50,7 @@ const componentMap = { }; const messages = defineMessages({ - publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }, + publish: { id: 'compose_form.publish', defaultMessage: 'Post' }, }); const shouldHideFAB = path => path.match(/^\/statuses\/|^\/search|^\/getting-started/); diff --git a/app/javascript/mastodon/features/ui/components/link_footer.js b/app/javascript/mastodon/features/ui/components/link_footer.js index 3c4cff9f9..55f7c936a 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.js +++ b/app/javascript/mastodon/features/ui/components/link_footer.js @@ -64,6 +64,11 @@ class LinkFooter extends React.PureComponent { defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.' values={{ github: {repository} (v{version}) }} /> + hometown-fork/hometown }} + />

); diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 507ac1df1..4faa464c6 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -61,7 +61,7 @@ import { previewState as previewVideoState } from './components/video_modal'; import '../../components/status'; const messages = defineMessages({ - beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' }, + beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave.' }, }); const mapStateToProps = state => ({ diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 80d43907d..89b59051c 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -12,6 +12,7 @@ export const boostModal = getMeta('boost_modal'); export const deleteModal = getMeta('delete_modal'); export const me = getMeta('me'); export const searchEnabled = getMeta('search_enabled'); +export const maxChars = (initialState && initialState.max_toot_chars) || 500; export const invitesEnabled = getMeta('invites_enabled'); export const repository = getMeta('repository'); export const source_url = getMeta('source_url'); diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index 0d77f7ff7..c8d04b6fb 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -86,7 +86,7 @@ "community.column_settings.remote_only": "Remote only", "compose_form.direct_message_warning": "Esti barritu namái va unviase a los usuarios mentaos.", "compose_form.direct_message_warning_learn_more": "Learn more", - "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.", + "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer.lock": "locked", "compose_form.placeholder": "¿En qué pienses?", @@ -219,7 +219,7 @@ "introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.text": "Pues guardar un barritu pa dempués y facer que l'autor sepa que te prestó marcándolu como favoritu.", "introduction.interactions.reblog.headline": "Boost", - "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reblog.text": "You can share other people's posts with your followers by boosting them.", "introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.welcome.action": "¡Vamos!", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 1f1cc9c10..ac67200ab 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -86,7 +86,7 @@ "community.column_settings.remote_only": "Remote only", "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", "compose_form.direct_message_warning_learn_more": "Learn more", - "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.", + "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer.lock": "locked", "compose_form.placeholder": "Какво си мислиш?", @@ -157,8 +157,8 @@ "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", "empty_column.domain_blocks": "There are no hidden domains yet.", - "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", - "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", + "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.", + "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", "empty_column.hashtag": "There is nothing in this hashtag yet.", "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", @@ -219,12 +219,12 @@ "introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.reblog.headline": "Boost", - "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reblog.text": "You can share other people's posts with your followers by boosting them.", "introduction.interactions.reply.headline": "Reply", - "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", + "introduction.interactions.reply.text": "You can reply to other people's and your own posts, which will chain them together in a conversation.", "introduction.welcome.action": "Let's go!", "introduction.welcome.headline": "First steps", - "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.", + "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.", "keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.boost": "to boost", @@ -247,7 +247,7 @@ "keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.open_media": "to open media", - "keyboard_shortcuts.pinned": "to open pinned toots list", + "keyboard_shortcuts.pinned": "to open pinned posts list", "keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.requests": "to open follow requests list", @@ -304,7 +304,7 @@ "navigation_bar.logout": "Излизане", "navigation_bar.mutes": "Muted users", "navigation_bar.personal": "Personal", - "navigation_bar.pins": "Pinned toots", + "navigation_bar.pins": "Pinned posts", "navigation_bar.preferences": "Предпочитания", "navigation_bar.public_timeline": "Публичен канал", "navigation_bar.security": "Security", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index 9b73c3597..4c254cd59 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "স্টেকট্রেস ক্লিপবোর্ডে কপি করুন", "errors.unexpected_crash.report_issue": "সমস্যার প্রতিবেদন করুন", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "অনুমতি দিন", "follow_request.reject": "প্রত্যাখ্যান করুন", "follow_requests.unlocked_explanation": "আপনার অ্যাকাউন্টটি লক না থাকলেও, {domain} কর্মীরা ভেবেছিলেন যে আপনি এই অ্যাকাউন্টগুলি থেকে ম্যানুয়ালি অনুসরণের অনুরোধগুলি পর্যালোচনা করতে চাইতে পারেন।", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index c28dc6d19..be695225b 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Copïo'r olrhain stac i'r clipfwrdd", "errors.unexpected_crash.report_issue": "Rhoi gwybod am broblem", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Caniatau", "follow_request.reject": "Gwrthod", "follow_requests.unlocked_explanation": "Er nid yw eich cyfrif wedi'i gloi, oedd y staff {domain} yn meddwl efallai hoffech adolygu ceisiadau dilyn o'r cyfrifau rhain wrth law.", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 1cf0770f0..f65b4cd9f 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Kopiér stack trace til udklipsholderen", "errors.unexpected_crash.report_issue": "Rapportér problem", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Godkend", "follow_request.reject": "Afvis", "follow_requests.unlocked_explanation": "Selvom din konto ikke er låst, troede {domain} -personalet, at du måske vil gennemgå dine anmodninger manuelt.", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 9d19ba725..bd0d2a65a 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -568,7 +568,7 @@ "id": "status.filtered" }, { - "defaultMessage": "Pinned toot", + "defaultMessage": "Pinned post", "id": "status.pinned" }, { @@ -670,11 +670,11 @@ { "descriptors": [ { - "defaultMessage": "Toots", + "defaultMessage": "Posts", "id": "account.posts" }, { - "defaultMessage": "Toots and replies", + "defaultMessage": "Posts and replies", "id": "account.posts_with_replies" }, { @@ -729,7 +729,7 @@ "id": "empty_column.account_unavailable" }, { - "defaultMessage": "No toots here!", + "defaultMessage": "No posts here!", "id": "empty_column.account_timeline" } ], @@ -843,7 +843,7 @@ "id": "account.disable_notifications" }, { - "defaultMessage": "Pinned toots", + "defaultMessage": "Pinned posts", "id": "navigation_bar.pins" }, { @@ -997,7 +997,7 @@ "id": "account.edit_profile" }, { - "defaultMessage": "Pinned toots", + "defaultMessage": "Pinned posts", "id": "navigation_bar.pins" }, { @@ -1054,7 +1054,7 @@ "id": "compose_form.spoiler_placeholder" }, { - "defaultMessage": "Toot", + "defaultMessage": "Post", "id": "compose_form.publish" }, { @@ -1132,7 +1132,7 @@ "id": "federation.federated.short" }, { - "defaultMessage": "Allow toot to reach other instances", + "defaultMessage": "Allow post to reach other instances", "id": "federation.federated.long" }, { @@ -1140,7 +1140,7 @@ "id": "federation.local_only.short" }, { - "defaultMessage": "Restrict this toot only to my instance", + "defaultMessage": "Restrict this post only to my instance", "id": "federation.local_only.long" }, { @@ -1278,7 +1278,7 @@ "id": "search_results.accounts" }, { - "defaultMessage": "Toots", + "defaultMessage": "Posts", "id": "search_results.statuses" }, { @@ -1414,11 +1414,11 @@ "id": "compose_form.lock_disclaimer.lock" }, { - "defaultMessage": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.", + "defaultMessage": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "id": "compose_form.hashtag_warning" }, { - "defaultMessage": "This toot will only be sent to all the mentioned users.", + "defaultMessage": "This post will only be sent to all the mentioned users.", "id": "compose_form.direct_message_warning" }, { @@ -1459,7 +1459,7 @@ "id": "navigation_bar.logout" }, { - "defaultMessage": "Compose new toot", + "defaultMessage": "Compose new post", "id": "navigation_bar.compose" }, { @@ -1634,7 +1634,7 @@ "id": "column.favourites" }, { - "defaultMessage": "You don't have any favourite toots yet. When you favourite one, it will show up here.", + "defaultMessage": "You don't have any favourite posts yet. When you favourite one, it will show up here.", "id": "empty_column.favourited_statuses" } ], @@ -1802,7 +1802,7 @@ "id": "navigation_bar.mutes" }, { - "defaultMessage": "Pinned toots", + "defaultMessage": "Pinned posts", "id": "navigation_bar.pins" }, { @@ -1975,7 +1975,7 @@ "id": "introduction.interactions.reply.headline" }, { - "defaultMessage": "You can reply to other people's and your own toots, which will chain them together in a conversation.", + "defaultMessage": "You can reply to other people's and your own posts, which will chain them together in a conversation.", "id": "introduction.interactions.reply.text" }, { @@ -1983,7 +1983,7 @@ "id": "introduction.interactions.reblog.headline" }, { - "defaultMessage": "You can share other people's toots with your followers by boosting them.", + "defaultMessage": "You can share other people's posts with your followers by boosting them.", "id": "introduction.interactions.reblog.text" }, { @@ -1991,11 +1991,11 @@ "id": "introduction.interactions.favourite.headline" }, { - "defaultMessage": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", + "defaultMessage": "You can save a post for later, and let the author know that you liked it, by favouriting it.", "id": "introduction.interactions.favourite.text" }, { - "defaultMessage": "Finish toot-orial!", + "defaultMessage": "Finish tutorial!", "id": "introduction.interactions.action" } ], @@ -2068,7 +2068,7 @@ "id": "keyboard_shortcuts.compose" }, { - "defaultMessage": "to start a brand new toot", + "defaultMessage": "to start a brand new post", "id": "keyboard_shortcuts.toot" }, { @@ -2116,7 +2116,7 @@ "id": "keyboard_shortcuts.favourites" }, { - "defaultMessage": "to open pinned toots list", + "defaultMessage": "to open pinned posts list", "id": "keyboard_shortcuts.pinned" }, { @@ -2548,7 +2548,7 @@ { "descriptors": [ { - "defaultMessage": "Pinned toot", + "defaultMessage": "Pinned post", "id": "column.pins" } ], @@ -2587,7 +2587,7 @@ "id": "refresh" }, { - "defaultMessage": "No one has boosted this toot yet. When someone does, they will show up here.", + "defaultMessage": "No one has boosted this post yet. When someone does, they will show up here.", "id": "status.reblogs.empty" } ], @@ -2712,6 +2712,10 @@ }, { "descriptors": [ + { + "defaultMessage": "This post is only visible by other users of your instance", + "id": "status.local_only" + }, { "defaultMessage": "Sensitive content", "id": "status.sensitive_warning" @@ -2913,7 +2917,7 @@ { "descriptors": [ { - "defaultMessage": "Toot", + "defaultMessage": "Post", "id": "compose_form.publish" } ], diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 2de36e81e..93fabfe07 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -32,13 +32,13 @@ "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", "account.never_active": "Never", - "account.posts": "Toots", - "account.posts_with_replies": "Toots and replies", + "account.posts": "Posts", + "account.posts_with_replies": "Posts and replies", "account.report": "Report @{name}", "account.requested": "Awaiting approval. Click to cancel follow request", "account.share": "Share @{name}'s profile", "account.show_reblogs": "Show boosts from @{name}", - "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", + "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}", "account.unblock": "Unblock @{name}", "account.unblock_domain": "Unblock domain {domain}", "account.unendorse": "Don't feature on profile", @@ -71,7 +71,7 @@ "column.lists": "Lists", "column.mutes": "Muted users", "column.notifications": "Notifications", - "column.pins": "Pinned toots", + "column.pins": "Pinned posts", "column.public": "Federated timeline", "column_back_button.label": "Back", "column_header.hide_settings": "Hide settings", @@ -84,9 +84,9 @@ "community.column_settings.local_only": "Local only", "community.column_settings.media_only": "Media Only", "community.column_settings.remote_only": "Remote only", - "compose_form.direct_message_warning": "This toot will only be sent to the mentioned users.", + "compose_form.direct_message_warning": "This post will only be sent to the mentioned users.", "compose_form.direct_message_warning_learn_more": "Learn more", - "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.", + "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer.lock": "locked", "compose_form.placeholder": "What's on your mind?", @@ -96,7 +96,7 @@ "compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice", - "compose_form.publish": "Toot", + "compose_form.publish": "Post", "compose_form.publish_loud": "{publish}!", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", @@ -109,7 +109,7 @@ "confirmations.block.confirm": "Block", "confirmations.block.message": "Are you sure you want to block {name}?", "confirmations.delete.confirm": "Delete", - "confirmations.delete.message": "Are you sure you want to delete this toot?", + "confirmations.delete.message": "Are you sure you want to delete this post?", "confirmations.delete_list.confirm": "Delete", "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Block entire domain", @@ -120,7 +120,7 @@ "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", - "confirmations.redraft.message": "Are you sure you want to delete this toot and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", + "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", "confirmations.reply.confirm": "Reply", "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", @@ -133,7 +133,7 @@ "directory.local": "From {domain} only", "directory.new_arrivals": "New arrivals", "directory.recently_active": "Recently active", - "embed.instructions": "Embed this toot on your website by copying the code below.", + "embed.instructions": "Embed this post on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", "emoji_button.custom": "Custom", @@ -150,20 +150,20 @@ "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.account_suspended": "Account suspended", - "empty_column.account_timeline": "No toots here!", + "empty_column.account_timeline": "No posts here!", "empty_column.account_unavailable": "Profile unavailable", "empty_column.blocks": "You haven't blocked any users yet.", - "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", + "empty_column.bookmarked_statuses": "You don't have any bookmarked posts yet. When you bookmark one, it will show up here.", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", "empty_column.domain_blocks": "There are no blocked domains yet.", - "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", - "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", + "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.", + "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", "empty_column.hashtag": "There is nothing in this hashtag yet.", "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", "empty_column.home.public_timeline": "the public timeline", - "empty_column.list": "There is nothing in this list yet. When members of this list post new toots, they will appear here.", + "empty_column.list": "There is nothing in this list yet. When members of this list post new posts, they will appear here.", "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", "empty_column.mutes": "You haven't muted any users yet.", "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", @@ -175,9 +175,9 @@ "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard", "errors.unexpected_crash.report_issue": "Report issue", "federation.change": "Adjust status federation", - "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.long": "Allow post to reach other instances", "federation.federated.short": "Federated", - "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.long": "Restrict this post only to my instance", "federation.local_only.short": "Local-only", "follow_request.authorize": "Authorize", "follow_request.reject": "Reject", @@ -187,6 +187,7 @@ "getting_started.directory": "Profile directory", "getting_started.documentation": "Documentation", "getting_started.heading": "Getting started", + "getting_started.hometown_open_source_notice": "Hometown is also open source, at {hometown} (v1.0.5).", "getting_started.invite": "Invite people", "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", "getting_started.security": "Account settings", @@ -217,23 +218,23 @@ "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.interactions.action": "Finish tutorial!", "introduction.interactions.favourite.headline": "Favourite", - "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", + "introduction.interactions.favourite.text": "You can save a post for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.reblog.headline": "Boost", - "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reblog.text": "You can share other people's posts with your followers by boosting them.", "introduction.interactions.reply.headline": "Reply", - "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", + "introduction.interactions.reply.text": "You can reply to other people's and your own posts, which will chain them together in a conversation.", "introduction.welcome.action": "Let's go!", "introduction.welcome.headline": "First steps", "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.", "keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.boost": "to boost", - "keyboard_shortcuts.column": "to focus a toot in one of the columns", + "keyboard_shortcuts.column": "to focus a post in one of the columns", "keyboard_shortcuts.compose": "to focus the compose textarea", "keyboard_shortcuts.description": "Description", "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "to move down in the list", - "keyboard_shortcuts.enter": "to open toot", + "keyboard_shortcuts.enter": "to open post", "keyboard_shortcuts.favourite": "to favourite", "keyboard_shortcuts.favourites": "to open favourites list", "keyboard_shortcuts.federated": "to open federated timeline", @@ -247,7 +248,7 @@ "keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.open_media": "to open media", - "keyboard_shortcuts.pinned": "to open pinned toots list", + "keyboard_shortcuts.pinned": "to open pinned posts list", "keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.requests": "to open follow requests list", @@ -256,7 +257,7 @@ "keyboard_shortcuts.start": "to open \"get started\" column", "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", - "keyboard_shortcuts.toot": "to start a brand new toot", + "keyboard_shortcuts.toot": "to start a brand new post", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", "lightbox.close": "Close", @@ -289,7 +290,7 @@ "navigation_bar.blocks": "Blocked users", "navigation_bar.bookmarks": "Bookmarks", "navigation_bar.community_timeline": "Local timeline", - "navigation_bar.compose": "Compose new toot", + "navigation_bar.compose": "Compose new post", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", "navigation_bar.domain_blocks": "Blocked domains", @@ -304,17 +305,17 @@ "navigation_bar.logout": "Logout", "navigation_bar.mutes": "Muted users", "navigation_bar.personal": "Personal", - "navigation_bar.pins": "Pinned toots", + "navigation_bar.pins": "Pinned posts", "navigation_bar.preferences": "Preferences", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", - "notification.favourite": "{name} favourited your toot", + "notification.favourite": "{name} favourited your post", "notification.follow": "{name} followed you", "notification.follow_request": "{name} has requested to follow you", "notification.mention": "{name} mentioned you", "notification.own_poll": "Your poll has ended", "notification.poll": "A poll you have voted in has ended", - "notification.reblog": "{name} boosted your toot", + "notification.reblog": "{name} boosted your post", "notification.status": "{name} just posted", "notifications.clear": "Clear notifications", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", @@ -357,7 +358,7 @@ "poll.voted": "You voted for this answer", "poll_button.add_poll": "Add a poll", "poll_button.remove_poll": "Remove poll", - "privacy.change": "Adjust toot privacy", + "privacy.change": "Adjust post privacy", "privacy.direct.long": "Visible for mentioned users only", "privacy.direct.short": "Direct", "privacy.private.long": "Visible for followers only", @@ -384,23 +385,23 @@ "report.target": "Reporting {target}", "search.placeholder": "Search", "search_popout.search_format": "Advanced search format", - "search_popout.tips.full_text": "Simple text returns toots you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", + "search_popout.tips.full_text": "Simple text returns posts you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", "search_popout.tips.hashtag": "hashtag", - "search_popout.tips.status": "toot", + "search_popout.tips.status": "post", "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", "search_popout.tips.user": "user", "search_results.accounts": "People", "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", - "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", + "search_results.statuses": "Posts", + "search_results.statuses_fts_disabled": "Searching posts by their content is not enabled on this Mastodon server.", "search_results.total": "{count, number} {count, plural, one {result} other {results}}", "status.admin_account": "Open moderation interface for @{name}", - "status.admin_status": "Open this toot in the moderation interface", + "status.admin_status": "Open this post in the moderation interface", "status.block": "Block @{name}", "status.bookmark": "Bookmark", "status.cancel_reblog_private": "Unboost", "status.cannot_reblog": "This post cannot be boosted", - "status.copy": "Copy link to toot", + "status.copy": "Copy link to post", "status.delete": "Delete", "status.detailed_status": "Detailed conversation view", "status.direct": "Direct message @{name}", @@ -414,14 +415,14 @@ "status.more": "More", "status.mute": "Mute @{name}", "status.mute_conversation": "Mute conversation", - "status.open": "Expand this toot", + "status.open": "Expand this post", "status.pin": "Pin on profile", - "status.pinned": "Pinned toot", + "status.pinned": "Pinned post", "status.read_more": "Read more", "status.reblog": "Boost", "status.reblog_private": "Boost with original visibility", "status.reblogged_by": "{name} boosted", - "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", + "status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.", "status.redraft": "Delete & re-draft", "status.remove_bookmark": "Remove bookmark", "status.reply": "Reply", @@ -452,7 +453,7 @@ "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.", "timeline_hint.resources.followers": "Followers", "timeline_hint.resources.follows": "Follows", - "timeline_hint.resources.statuses": "Older toots", + "timeline_hint.resources.statuses": "Older posts", "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking", "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index b062ec18b..8181b8e76 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "لطفاً از کارشان انداخته و صفحه را نوسازی کنید. اگر کمکی نکرد، شاید همچنان بتوانید با مرورگری دیگر یا با کاره‌ای بومی از ماستودون استفاده کنید.", "errors.unexpected_crash.copy_stacktrace": "رونوشت از جزئیات اشکال", "errors.unexpected_crash.report_issue": "گزارش مشکل", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "اجازه دهید", "follow_request.reject": "رد کنید", "follow_requests.unlocked_explanation": "با این که حسابتان قفل نیست، کارکنان {domain} فکر کردند که ممکن است بخواهید درخواست‌ها از این حساب‌ها را به صورت دستی بازبینی کنید.", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 8df7535b8..5cd7972d6 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Essayez de les désactiver et de rafraîchir la page. Si cela ne vous aide pas, vous pouvez toujours utiliser Mastodon via un autre navigateur ou une application native.", "errors.unexpected_crash.copy_stacktrace": "Copier la trace d'appels dans le presse-papier", "errors.unexpected_crash.report_issue": "Signaler le problème", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Accepter", "follow_request.reject": "Rejeter", "follow_requests.unlocked_explanation": "Même si votre compte n’est pas verrouillé, l’équipe de {domain} a pensé que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 854e31554..ad0df994d 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Intenta desactivalas e actualiza a páxina. Se isto non funciona, podes seguir usando Mastodon nun navegador diferente ou aplicación nativa.", "errors.unexpected_crash.copy_stacktrace": "Copiar trazas (stacktrace) ó portapapeis", "errors.unexpected_crash.report_issue": "Informar sobre un problema", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Autorizar", "follow_request.reject": "Rexeitar", "follow_requests.unlocked_explanation": "Malia que a túa conta non é privada, a administración de {domain} pensou que quizabes terías que revisar de xeito manual as solicitudes de seguiminto.", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index 7aabca57d..2defe57ee 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "स्टैकट्रेस को क्लिपबोर्ड पर कॉपी करें", "errors.unexpected_crash.report_issue": "समस्या सूचित करें", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "अधिकार दें", "follow_request.reject": "अस्वीकार करें", "follow_requests.unlocked_explanation": "हालाँकि आपका खाता लॉक नहीं है, फिर भी {domain} डोमेन स्टाफ ने सोचा कि आप इन खातों के मैन्युअल अनुरोधों की समीक्षा करना चाहते हैं।", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 3c0645c02..f04ac588b 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Próbáld letiltani őket és frissíteni az oldalt. Ha ez nem segít, egy másik böngészőn vagy appon keresztül még mindig használhatod a Mastodont.", "errors.unexpected_crash.copy_stacktrace": "Veremkiíratás vágólapra másolása", "errors.unexpected_crash.report_issue": "Probléma jelentése", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Engedélyezés", "follow_request.reject": "Elutasítás", "follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni a fiók követési kéréseit.", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 5cdba58e8..8c9aad72b 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Փորձիր անջատել յաւելուածները եւ թարմացնել էջը։ Եթե դա չօգնի, կարող ես օգտուել Մաստադոնից այլ դիտարկիչով կամ յաւելուածով։", "errors.unexpected_crash.copy_stacktrace": "Պատճենել սթաքթրեյսը սեղմատախտակին", "errors.unexpected_crash.report_issue": "Զեկուցել խնդրի մասին", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Վաւերացնել", "follow_request.reject": "Մերժել", "follow_requests.unlocked_explanation": "Այս հարցումը ուղարկուած է հաշուից, որի համար {domain}-ի անձնակազմը միացրել է ձեռքով ստուգում։", @@ -403,6 +408,7 @@ "status.favourite": "Հաւանել", "status.filtered": "Զտուած", "status.load_more": "Բեռնել աւելին", + "status.local_only": "This post is only visible by other users of your instance", "status.media_hidden": "մեդիաբովանդակութիւնը թաքցուած է", "status.mention": "Նշել @{name}֊ին", "status.more": "Աւելին", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 21869524b..0983dee27 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Prova a disabilitarli e ad aggiornare la pagina. Se questo non funziona, potresti ancora essere in grado di utilizzare Mastodon attraverso un browser o un'app diversi.", "errors.unexpected_crash.copy_stacktrace": "Copia stacktrace negli appunti", "errors.unexpected_crash.report_issue": "Segnala il problema", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Autorizza", "follow_request.reject": "Rifiuta", "follow_requests.unlocked_explanation": "Anche se il tuo account non è bloccato, lo staff di {domain} ha pensato che potresti voler esaminare manualmente le richieste di seguirti di questi account.", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index daaa523b4..382a363b8 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Жиынтықты көшіріп ал клипбордқа", "errors.unexpected_crash.report_issue": "Мәселені хабарла", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Авторизация", "follow_request.reject": "Қабылдамау", "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index e86ff15e6..fa8971104 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Kopier stacktrace-en til utklippstavlen", "errors.unexpected_crash.report_issue": "Rapporter en feil", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Autorisér", "follow_request.reject": "Avvis", "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 65d5815ed..122fbe5a7 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Tente desabilitá-los e atualizar a página. Se isso não ajudar, você ainda poderá usar o Mastodon por meio de um navegador diferente ou de um aplicativo nativo.", "errors.unexpected_crash.copy_stacktrace": "Copiar stacktrace para área de transferência", "errors.unexpected_crash.report_issue": "Denunciar problema", + "federation.change": "Ajustar federação do toot", + "federation.federated.long": "Permitir que o toot chegue a outras instâncias", + "federation.federated.short": "Federado", + "federation.local_only.long": "Restringir o toot somente à minha instância", + "federation.local_only.short": "Somente local", "follow_request.authorize": "Aprovar", "follow_request.reject": "Vetar", "follow_requests.unlocked_explanation": "Embora sua conta não esteja trancada, o staff de {domain} achou que você podia querer revisar pedidos para te seguir destas contas manualmente.", diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json index 459417ab0..d9145ed10 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Tente desabilitá-los e atualizar a página. Se isso não ajudar, você ainda poderá usar o Mastodon por meio de um navegador diferente ou de um aplicativo nativo.", "errors.unexpected_crash.copy_stacktrace": "Copiar a stacktrace para o clipboard", "errors.unexpected_crash.report_issue": "Reportar problema", + "federation.change": "Ajustar federação do toot", + "federation.federated.long": "Permitir que o toot chegue a outras instâncias", + "federation.federated.short": "Federado", + "federation.local_only.long": "Restringir o toot somente à minha instância", + "federation.local_only.short": "Somente local", "follow_request.authorize": "Autorizar", "follow_request.reject": "Rejeitar", "follow_requests.unlocked_explanation": "Apesar de a sua não estar bloqueada, a administração de {domain} pensa que poderá querer rever os pedidos dessas contas manualmente.", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index df0848bc8..d6fbcda2a 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Copiați stiva în clipboard", "errors.unexpected_crash.report_issue": "Raportați o problemă", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Autorizează", "follow_request.reject": "Respinge", "follow_requests.unlocked_explanation": "Chiar dacă contul dvs nu este blocat, personalul {domain} a crezut că ați putea dori să revizuiți cererile de la aceste conturi în mod manual.", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 65db63c27..09f91aacc 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Provoni t’i çaktivizoni dhe të rifreskoni faqen. Nëse kjo s’bën punë, mundeni prapë të jeni në gjendje të përdorni Mastodon-in përmes një shfletuesi tjetër, apo një aplikacioni prej Mastodon-it.", "errors.unexpected_crash.copy_stacktrace": "Kopjo stacktrace-in në të papastër", "errors.unexpected_crash.report_issue": "Raportoni problemin", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Autorizoje", "follow_request.reject": "Hidhe tej", "follow_requests.unlocked_explanation": "Edhe pse llogaria juaj s’është e kyçur, ekipi i {domain} mendoi se mund të donit të shqyrtonit dorazi kërkesa ndjekjeje prej këtyre llogarive.", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index e8a93dfc6..d8c7d7ebc 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Копирај \"stacktrace\" у клипборд", "errors.unexpected_crash.report_issue": "Пријави проблем", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Одобри", "follow_request.reject": "Одбиј", "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 509a745e1..f72d629d6 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Stacktrace-ஐ clipboard-ல் நகலெடு", "errors.unexpected_crash.report_issue": "புகாரளி", + "federation.change": "Adjust status federation", + "federation.federated.short": "Federated", + "federation.federated.long": "Allow toot to reach other instances", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "அனுமதியளி", "follow_request.reject": "நிராகரி", "follow_requests.unlocked_explanation": "உங்கள் கணக்கு பூட்டப்படவில்லை என்றாலும், இந்தக் கணக்குகளிலிருந்து உங்களைப் பின்தொடர விரும்பும் கோரிக்கைகளை நீங்கள் பரீசீலிப்பது நலம் என்று {domain} ஊழியர் எண்ணுகிறார்.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 941e43c99..77f7b3ddc 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.", "errors.unexpected_crash.copy_stacktrace": "Скопіювати трасування стека у буфер обміну", "errors.unexpected_crash.report_issue": "Повідомити про проблему", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "Авторизувати", "follow_request.reject": "Відмовити", "follow_requests.unlocked_explanation": "Хоча ваш обліковий запис не заблоковано, працівники {domain} припускають, що, можливо, ви хотіли б переглянути ці запити на підписку.", @@ -403,6 +408,7 @@ "status.favourite": "Подобається", "status.filtered": "Відфільтровано", "status.load_more": "Завантажити більше", + "status.local_only": "This post is only visible by other users of your instance", "status.media_hidden": "Медіа приховано", "status.mention": "Згадати @{name}", "status.more": "Більше", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 6c746bf96..82db058a1 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "请尝试禁用它们并刷新页面。如果没有帮助,你仍可以尝试使用其他浏览器或原生应用来使用 Mastodon。", "errors.unexpected_crash.copy_stacktrace": "把堆栈跟踪信息复制到剪贴板", "errors.unexpected_crash.report_issue": "报告问题", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "同意", "follow_request.reject": "拒绝", "follow_requests.unlocked_explanation": "虽说你没有锁嘟,但是 {domain} 的工作人员觉得你可能想手工审核关注请求。", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index e0bd4473f..1055b7b97 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "請嘗試停止使用這些附加元件然後重新載入頁面。如果問題沒有解決,你仍然可以使用不同的瀏覽器或 Mastodon 應用程式來檢視。", "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿", "errors.unexpected_crash.report_issue": "舉報問題", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "批准", "follow_request.reject": "拒絕", "follow_requests.unlocked_explanation": "即使您的帳戶未上鎖,{domain} 的工作人員認為您可能想手動審核來自這些帳戶的關注請求。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index c219a4a9a..4c287dc3b 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -174,6 +174,11 @@ "error.unexpected_crash.next_steps_addons": "請嘗試關閉他們然後重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式來檢視來使用 Mastodon。", "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿", "errors.unexpected_crash.report_issue": "回報問題", + "federation.change": "Adjust status federation", + "federation.federated.long": "Allow toot to reach other instances", + "federation.federated.short": "Federated", + "federation.local_only.long": "Restrict this toot only to my instance", + "federation.local_only.short": "Local-only", "follow_request.authorize": "授權", "follow_request.reject": "拒絕", "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的員工認為您可能想要自己審核這些帳號的追蹤請求。", diff --git a/app/javascript/mastodon/reducers/list_editor.js b/app/javascript/mastodon/reducers/list_editor.js index 91e524dd5..d21c376d8 100644 --- a/app/javascript/mastodon/reducers/list_editor.js +++ b/app/javascript/mastodon/reducers/list_editor.js @@ -9,6 +9,7 @@ import { LIST_EDITOR_RESET, LIST_EDITOR_SETUP, LIST_EDITOR_TITLE_CHANGE, + LIST_EDITOR_IS_EXCLUSIVE_CHANGE, LIST_ACCOUNTS_FETCH_REQUEST, LIST_ACCOUNTS_FETCH_SUCCESS, LIST_ACCOUNTS_FETCH_FAIL, @@ -52,6 +53,11 @@ export default function listEditorReducer(state = initialState, action) { map.set('title', action.value); map.set('isChanged', true); }); + case LIST_EDITOR_IS_EXCLUSIVE_CHANGE: + return state.withMutations(map => { + map.set('isExclusive', action.value); + map.set('isChanged', true); + }); case LIST_CREATE_REQUEST: case LIST_UPDATE_REQUEST: return state.withMutations(map => { diff --git a/app/javascript/mastodon/svg_select.js b/app/javascript/mastodon/svg_select.js new file mode 100644 index 000000000..346f4f5f7 --- /dev/null +++ b/app/javascript/mastodon/svg_select.js @@ -0,0 +1,21 @@ +export function svgSelect(light, dark) { + + var svgbg = window.getComputedStyle(document.getElementsByClassName("drawer__inner")[0], null).getPropertyValue("background-color"); + var rgbArray = ((svgbg.replace(/[^0-9,]/g, "")).split(",")).map(Number).map(x => x/255); + + for ( var i = 0; i < rgbArray.length; ++i ) { + if ( rgbArray[i] <= 0.03928 ) { + rgbArray[i] = rgbArray[i] / 12.92 + } else { + rgbArray[i] = Math.pow( ( rgbArray[i] + 0.055 ) / 1.055, 2.4); + } + } + + var luminance = 0.2126 * rgbArray[0] + 0.7152 * rgbArray[1] + 0.0722 * rgbArray[2]; + + if ( luminance <= 0.179 ) { + return light; + } else { + return dark; + } +} diff --git a/app/javascript/styles/fairy-floss.scss b/app/javascript/styles/fairy-floss.scss new file mode 100644 index 000000000..6b26aeed5 --- /dev/null +++ b/app/javascript/styles/fairy-floss.scss @@ -0,0 +1,3 @@ +@import 'fairy-floss/variables'; +@import 'application'; +@import 'fairy-floss/diff' diff --git a/app/javascript/styles/fairy-floss/diff.scss b/app/javascript/styles/fairy-floss/diff.scss new file mode 100644 index 000000000..a746c5bab --- /dev/null +++ b/app/javascript/styles/fairy-floss/diff.scss @@ -0,0 +1,544 @@ +// components.scss +.compose-form { + .compose-form__modifiers { + .compose-form__upload { + &-description { + input { + &::placeholder { + opacity: 1; + } + } + } + } + } +} + +.rich-formatting a, +.rich-formatting p a, +.rich-formatting li a, +.landing-page__short-description p a, +.status__content a, +.reply-indicator__content a { + color: lighten($ui-highlight-color, 12%); + text-decoration: underline; + + &.mention { + text-decoration: none; + } + + &.mention span { + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } + } + + &:hover, + &:focus, + &:active { + text-decoration: none; + } + + &.status__content__spoiler-link { + color: $secondary-text-color; + text-decoration: none; + } +} + +.status__content__read-more-button { + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } +} + +.getting-started__footer a { + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + } +} + +.nothing-here { + color: $darker-text-color; +} + +.public-layout .public-account-header__tabs__tabs .counter.active::after { + border-bottom: 4px solid $ui-highlight-color; +} + + +// FAIRY FLOSS CHANGES + +html { + scrollbar-color: $purple3 rgba($purple3, 0.25); +} + +::-webkit-scrollbar-thumb { + background: $purplescrollbar; + border: 0 #f8f8f2; + border-radius: 50px; +} + +::-webkit-scrollbar-thumb:hover { + background: $purplescrollbar; + border: 0; +} + +::-webkit-scrollbar-track:hover { + background: darken($purple2, 6%); +} + +.loading-bar + { + background-color: $mint; + } + +// text +.status__display-name, .column-header, .column-link, .navigation-bar strong { + color: $purple4; +} + +.ui, +.notification__filter-bar button, .account__section-headline button, body, body.admin { + background: $purple1; +} + +.drawer__header { + background: $purple3; + + a { + &:hover, &:focus { + background: darken($purple3, 8%); + } + } +} + +.search__input { + &:hover, &:focus { + background: $purple2; + color: $purple4; + } + background: $purple2; + color: $purple4; +} + +::placeholder { + color: $purple4; +} + +.search-popout, .search-popout h4 { + color: $purple1; + background-color: $purple4; +} + +.drawer__inner, .drawer__inner__mastodon { + background: $purple3; +} + +.compose-form .compose-form__buttons-wrapper { + background: lighten($purple4, 8%); +} + +.text-icon-button.active { + color: darken($pink, 12%); +} + + +.column-header, .column-header__button, .column-header__back-button { + background: $purple5; +} + +.notification__filter-bar button.active::after, .notification__filter-bar a.active::after, .account__section-headline button.active::after, .account__section-headline a.active::after { + border-color: transparent transparent $purple2; +} + +.column>.scrollable { + background: $purple2; +} + +.load-more:hover { + background: darken($purple2, 4%); +} + +.empty-column-indicator, .error-column { + background: $purple2; +} + +.column-link__badge, .column-subheading { + background: $purple2; +} + +.column-link { + background: $purple3; +} + +// link previews + +.status-card.compact { + border-color: darken($purple5, 8%); + background: $purple5; +} + +.status-card__image { + background: $purple3; +} + +.status-card__content { + background: $purple5; + + &:hover, &:focus { + background: darken($purple5, 4%); + } +} + +.notification__filter-bar button.active, .notification__filter-bar a.active, .account__section-headline button.active, .account__section-headline a.active, .column-header>.column-header__back-button { + color: $mint; +} + +.react-toggle--checked .react-toggle-track, .react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track { + background: $pink; +} + +.react-toggle-track, .react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { + background: $purple2; +} + +.column-header__collapsible-inner, .column-header__button.active, .column-header__button.active:hover, .column-header__button.active:focus { + background: $purple3; + color: $purpleicon; +} + +.column-inline-form, .column-back-button { + background: $purplescrollbar; +} + +.flex-spacer, .getting-started, .getting-started__wrapper { + background: $purple2; +} + +.status { + border-bottom: 1px solid lighten($purple2, 8%); +} + +.detailed-status, .detailed-status__action-bar { + background: $purplescrollbar; +} + +.detailed-status__action-bar { + border-top: 1px solid lighten($purple3, 8%); + border-bottom: 1px solid lighten($purple3, 8%); +} + +.focusable:focus { + background: $purplescrollbar; +} + +.focusable { + &:focus { + outline: 0; + background: $purplescrollbar; + + .detailed-status, + .detailed-status__action-bar { + background: lighten($purplescrollbar, 2%); + } + } +} + +.icon-button.active { + color: $pink; +} + +button.icon-button i.fa-retweet { + background-image: url("data:image/svg+xml;utf8,"); +} +button.icon-button i.fa-retweet:hover { + background-image: url("data:image/svg+xml;utf8,"); +} + +.notification__favourite-icon-wrapper .star-icon, .star-icon.active, a.mention.hashtag { + color: $lemon; +} + +.reply-indicator__content a, .status__content a { + color: $mint; +} + +a.mention, .notification__message .fa { + color: $pink; +} + +.poll__link { + color: $purple4; +} + +.poll__chart { + color: lighten($coral, 4%); +} + +.poll__chart.leading { + color: $coral; +} + +.emoji-mart-bar:first-child { + background: $purple4; +} + +.emoji-mart-anchor-selected { + color: $purple2; + &:hover, &:focus { + color: $purple1; + } +} + +.emoji-mart-anchor-bar { + background: $purple1; +} + +// profile in deck view + +.account__header__bar { + background: $purple5; +} + +.account__header__image { + background: $purple1; +} + +.notification__filter-bar, .account__section-headline { + background: $purple1; +} + +.dropdown-menu, .dropdown-menu__item a { + background: $purple4; +} + +.dropdown-menu__item a { + &:hover, &:focus { + background: $purple2; + } +} + +.dropdown-menu__separator { + border-bottom: 1px solid darken($purple4, 4%); +} + +.button.logo-button.button--destructive:active, .button.logo-button.button--destructive:focus, .button.logo-button.button--destructive:hover { + background: $pink; +} + +// public profiles + +.public-layout .header { + background: $purple3; +} + +.public-layout .header .brand:active, .public-layout .header .brand:focus, .public-layout .header .brand:hover { + background: darken($purple3, 4%); +} + +.public-layout .public-account-header__bar .avatar img { + background: $purple2; + border: 4px solid $purple2; +} + +.public-layout .public-account-header__image { + background: $ui-base-color; +} + +.public-layout .public-account-header__image .originalheader svg, .originalmascotimg svg { + fill: $ui-primary-color; +} + +.public-layout .public-account-header__image .originalheader h1 a.brand { + color: $ui-primary-color; +} + +.public-layout .header .nav-button { + background: darken($purple3, 4%); + &:hover, &:focus { + background: darken($purple3, 8%); + } +} + +.public-layout .public-account-header__bar:before { + background: $purplescrollbar; +} + +.public-layout .public-account-header__tabs__tabs .counter.active::after { + border-bottom: 4px solid $lemon; +} + +.public-layout .public-account-bio { + background: $purple3; +} + +.hero-widget__text { + background: $purple2; +} + +.activity-stream .entry { + background: $purple2; +} + +.simple_form .hint a { + color: $mint; +} + +.oauth-prompt strong, .follow-prompt strong { + color: $purple4; +} + +.simple_form input[type=text]:active, .simple_form input[type=text]:focus, .simple_form input[type=number]:active, .simple_form input[type=number]:focus, .simple_form input[type=email]:active, .simple_form input[type=email]:focus, .simple_form input[type=password]:active, .simple_form input[type=password]:focus, .simple_form textarea:active, .simple_form textarea:focus { + border-color: $mint; +} + +.nothing-here { + background: $purple2; +} + + +// admin zone + +.admin-wrapper .content h2 { + color: $purple4; +} + +.admin-wrapper .sidebar-wrapper { + background: $purple2; +} + +.admin-wrapper .sidebar ul .simple-navigation-active-leaf a { + background: $purpleborder; + &:hover, &:focus { + background: lighten($purpleborder, 8%); + } +} + +.admin-wrapper .sidebar ul ul { + background: $purple1; +} + +.admin-wrapper .sidebar ul a:hover, .admin-wrapper .sidebar ul a:focus { + background: $purpleborder; +} + +.admin-wrapper .content .muted-hint a { + color: $mint; +} + +.card__bar { + background: $purplescrollbar; +} + +.simple_form input[type=text], .simple_form input[type=number], .simple_form input[type=email], .simple_form input[type=password], .simple_form textarea { + background: darken($purple1, 6%); +} + +.simple_form select { + background: darken($purple1, 6%) url("data:image/svg+xml;utf8,") no-repeat right 8px center/auto 16px +} + +.table th, .table td { + background: darken($purple2, 6%); +} + +.table > thead > tr > th { + color: $lemon; +} + +.table > tbody > tr:nth-child(odd) > td, .table > tbody > tr:nth-child(odd) > th { + background: $purple3; +} + +// directory + +.accounts-table tbody td { + background: $purple3; +} + +.page-header { + background: $purpleborder; + + h1 { + color: $purple4; + } +} + +.box-widget, .contact-widget, .landing-page__information.contact-widget { + background: $purple2; +} + +.notice-widget a { + color: $mint; +} + +.directory__tag a { + background: $purple2; + &:hover, &:focus { + background: lighten($purple2, 4%); + } +} + +// about/more + +.landing-page__call-to-action { + background: $purple3; +} + +.rich-formatting h3, .rich-formatting h4, .rich-formatting h2, .rich-formatting h1 { + color: lighten($purpleicon, 8%); +} + +.landing-page__information strong { + color: lighten($purpleicon, 10%); +} + +// about + +.simple_form .input.boolean label a { + color: $mint; +} + +::-webkit-input-placeholder { /* Edge */ + color: $purpleicon; +} + +:-ms-input-placeholder { /* Internet Explorer 10-11 */ + color: $purpleicon; +} + +::placeholder { + color: $purpleicon; +} + +.landing .hero-widget__footer { + background: $purple3; +} + +.status.status-direct:not(.read), .account { + border-bottom: 1px solid lighten($purple2, 8%); +} + +.drawer__inner__mastodon svg#hometownlogo { + fill: $ui-primary-color; +} + +.audio-player, +.audio-player .video-player__controls { + background: $ui-base-color; +} + +.video-player__buttons button { + color: $ui-primary-color; +} diff --git a/app/javascript/styles/fairy-floss/variables.scss b/app/javascript/styles/fairy-floss/variables.scss new file mode 100644 index 000000000..6a714f3ff --- /dev/null +++ b/app/javascript/styles/fairy-floss/variables.scss @@ -0,0 +1,70 @@ +// FAIRY FLOSS VARIABLES + +// Purples +$purple1: #2e2b3b; +$purple2: #504b68; +$purple3: #5f5676; +$purple4: #c8c4d4; +$purple5: #474059; +$purpleicon: #ada6bf; +$purpleborder: #5f5676; +$purplescrollbar: #5a5475; +$mint: #c2ffdf; +$pink: #ffb8d1; +$lemon: #fff683; +$coral: #ff857f; + +// Commonly used web colors +$black: #000000; // Black +$white: #ffffff; // White +$success-green: #79bd9a !default; // Padua +$error-red: #df405a !default; // Cerise +$warning-red: #ff5050 !default; // Sunset Orange +$gold-star: #ca8f04 !default; // Dark Goldenrod + +// Values from the classic Mastodon UI +$classic-base-color: $purple1; // Midnight Express +$classic-primary-color: $purple4; // Echo Blue +$classic-secondary-color: #d9e1e8; // Pattens Blue +$classic-highlight-color: #ff857f; // Summer Sky + +// Variables for defaults in UI +$base-shadow-color: $black !default; +$base-overlay-background: $black !default; +$base-border-color: $white !default; +$simple-background-color: $white !default; +$valid-value-color: $success-green !default; +$error-value-color: $error-red !default; + +// Tell UI to use selected colors +$ui-base-color: $classic-base-color !default; // Darkest +$ui-base-lighter-color: lighten($ui-base-color, 26%) !default; // Lighter darkest +$ui-primary-color: $classic-primary-color !default; // Lighter +$ui-secondary-color: $classic-secondary-color !default; // Lightest +$ui-highlight-color: $classic-highlight-color !default; + +// Variables for texts +$primary-text-color: $white !default; +$darker-text-color: $ui-primary-color !default; +$dark-text-color: $purpleicon !default; +$secondary-text-color: $ui-secondary-color !default; +$highlight-text-color: $ui-highlight-color !default; +$action-button-color: $purpleicon !default; +// For texts on inverted backgrounds +$inverted-text-color: $ui-base-color !default; +$lighter-text-color: $ui-base-lighter-color !default; +$light-text-color: $ui-primary-color !default; + +// Language codes that uses CJK fonts +$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW; + +// Variables for components +$media-modal-media-max-width: 100%; +// put margins on top and bottom of image to avoid the screen covered by image. +$media-modal-media-max-height: 80%; + +$no-gap-breakpoint: 415px; + +$font-sans-serif: 'mastodon-font-sans-serif' !default; +$font-display: 'mastodon-font-display' !default; +$font-monospace: 'mastodon-font-monospace' !default; diff --git a/app/javascript/styles/macaron.scss b/app/javascript/styles/macaron.scss new file mode 100644 index 000000000..98677275d --- /dev/null +++ b/app/javascript/styles/macaron.scss @@ -0,0 +1,3 @@ +@import 'macaron/variables'; +@import 'application'; +@import 'macaron/diff'; diff --git a/app/javascript/styles/macaron/diff.scss b/app/javascript/styles/macaron/diff.scss new file mode 100644 index 000000000..6600c7717 --- /dev/null +++ b/app/javascript/styles/macaron/diff.scss @@ -0,0 +1,1097 @@ +// Notes! +// Sass color functions, "darken" and "lighten" are automatically replaced. + +html { + scrollbar-color: $pink rgba($pink, 0.25); +} + +.loading-bar + { + background-color: $green; + } + +.status__content a, .reply-indicator__content a { + &:hover, &:active, &:focus { + color: $bilberry; + } +} + +::-webkit-scrollbar-thumb { + background: $pink; + border: 0; +} + +::-webkit-scrollbar-thumb { + background: $pink; + border: 0; +} + +::-webkit-scrollbar-thumb:hover { + background: $pink; + border: 0; +} + +::-webkit-scrollbar-track:hover { + background: $green; +} + +.ui { + background: $cream; +} + +// Change the colors of button texts +.button { + color: $white; + + &.button-alternative-2 { + color: $white; + } +} + +// Change default background colors of columns +.column > .scrollable, +.getting-started, +.column-inline-form { + background: $white; + border: 1px solid lighten(#eeeeee, 4%); + border-top: 0; +} + +.getting-started { + background: $green; + border: 1px solid lighten($green, 8%); +} + +.column-back-button, +.column-header { + background: #c8c4dd; + border: 1px solid lighten($purple, 8%); + + @media screen and (max-width: $no-gap-breakpoint) { + border-top: 0; + } + + &--slim-button { + border: 0; + top: -49px; + right: 1px; + } +} + + + +.column-header__back-button, +.column-header__button, +.column-header__button.active, +.account__header__bar { + background: $purple; +} + +.column-header__button.active { + color: $ui-highlight-color; + + &:hover, + &:active, + &:focus { + color: $ui-highlight-color; + background: lighten($purple, 4%); + } +} + +.account__header__bar .avatar .account__avatar { + border-color: $white; +} + +.getting-started__footer a { + color: $ui-secondary-color; + text-decoration: underline; +} + +.column-subheading { + background: $green; + border-bottom: 1px solid lighten($green, 8%); +} + +.getting-started, +.scrollable { + .column-link { + background: $blue; + border-bottom: 1px solid lighten($blue, 8%); + + &:hover, + &:active, + &:focus { + background: lighten($blue, 8%); + } + } +} + +.getting-started .navigation-bar { + border-top: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid lighten($ui-base-color, 8%); + + @media screen and (max-width: $no-gap-breakpoint) { + border-top: 0; + } +} + +.compose-form__autosuggest-wrapper, +.poll__text input[type="text"], +.compose-form .spoiler-input__input, +.compose-form__poll-wrapper select, +.search__input, +.setting-text, +.box-widget input[type="text"], +.box-widget input[type="email"], +.box-widget input[type="password"], +.box-widget textarea, +.statuses-grid .detailed-status +.audio-player { + border: 1px solid lighten(#eeeeee, 4%); +} + +.poll__chart { + background: darken($purple, 4%); +} + +.muted .poll__chart { + background: rgba($purple, 0.8); +} + +.poll__chart.leading { + background: $pink; +} + +.muted .poll__chart.leading { + background: rgba($pink, 0.8); +} + +.status { + border-bottom: 1px solid lighten(#eeeeee, 4%); +} + +.detailed-status__action-bar { + border-top: 1px solid lighten($purple, 4%); + border-bottom: 1px solid lighten($purple, 4%); +} + +.search__input { + @media screen and (max-width: $no-gap-breakpoint) { + border-top: 0; + border-bottom: 0; + } + + background: $green; + border: 1px solid lighten($green, 8%); +} + +.search__input { + &:focus{ + background: $purple; + border: 1px solid lighten($purple, 8%); + } +} + +.list-editor .search .search__input { + border-top: 0; + border-bottom: 0; +} + +.compose-form__poll-wrapper select { + background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; +} + +.compose-form__poll-wrapper, +.compose-form__poll-wrapper .poll__footer { + border-top-color: lighten($ui-base-color, 8%); +} + +.notification__filter-bar, .account__section-headline { + background: $green; + border: 1px solid lighten($green, 8%); + border-top: 0; +} + +.notification__filter-bar button { + background: $green; +} + +.compose-form .compose-form__buttons-wrapper { + background: $ui-base-color; + border: 1px solid lighten($ui-base-color, 8%); + border-top: 0; +} + +.drawer__inner { + background: $pink; + border: 1px solid lighten($pink, 8%); +} + +.drawer__header { + background: $blue; + border: 1px solid lighten($blue, 8%); +} + +.drawer__header a { + &:active, + &:focus, + &:hover { + background: lighten($blue, 4%); + } +} + +.drawer__inner__mastodon { + background: $pink; +} + +// Change the colors used in compose-form +.compose-form { + .compose-form__modifiers { + .compose-form__upload__actions .icon-button { + color: lighten($white, 7%); + + &:active, + &:focus, + &:hover { + color: $white; + } + } + + .compose-form__upload-description input { + color: lighten($white, 7%); + + &::placeholder { + color: lighten($white, 7%); + } + } + } + + .compose-form__buttons-wrapper { + background: darken($ui-base-color, 6%); + } + + .autosuggest-textarea__suggestions { + background: darken($ui-base-color, 6%); + } + + .autosuggest-textarea__suggestions__item { + &:hover, + &:focus, + &:active, + &.selected { + background: lighten($ui-base-color, 4%); + } + } +} + +.account__header__tabs__buttons .icon-button { + border-color: lighten($purple, 8%); +} + +.emoji-mart-bar { + border-color: lighten($ui-base-color, 4%); + + &:first-child { + background: darken($ui-base-color, 6%); + } +} + +.emoji-mart-search input { + background: rgba($ui-base-color, 0.3); + border-color: $ui-base-color; +} + +// Change the background colors of statuses +.focusable:focus { + background: darken($green, 2%); +} + +.status.status-direct { + background: darken($ui-base-color, 2%); +} + +.focusable:focus .status.status-direct { + background: $ui-base-color; +} + +.status.status-direct:not(.read) { + background: $ui-base-color; + border-bottom-color: lighten($ui-base-color, 4%); +} + +.detailed-status, +.detailed-status__action-bar { + background: darken($purple, 10%); +} + +.reply-indicator { + background: darken($purple, 8%); +} + +// Change the background colors of status__content__spoiler-link +.reply-indicator__content .status__content__spoiler-link, +.status__content .status__content__spoiler-link { + background: $pink; + + &:hover { + background: lighten($pink, 4%); + } +} + +// Change the background colors of media and video spoilers +.media-spoiler, +.video-player__spoiler { + background: $ui-base-color; +} + +.privacy-dropdown.active .privacy-dropdown__value.active .icon-button { + color: $white; +} + +.account-gallery__item a { + background-color: $ui-base-color; +} + +// Change the colors used in the dropdown menu +.dropdown-menu { + background: $white; + + &__arrow { + &.left { + border-left-color: $white; + } + + &.top { + border-top-color: $white; + } + + &.bottom { + border-bottom-color: $white; + } + + &.right { + border-right-color: $white; + } + } + + &__item { + a { + background: $white; + color: $darker-text-color; + } + } +} + +body.admin { + background: $cream; +} + +.card>a:hover { + .card__bar { + background: $blue; + } +} + +.batch-table__toolbar { + background: $green; +} + +.batch-table__row { + border-top: 0; + border: 1px solid #fffdef; + background: $blue; +} + +.batch-table__row:nth-child(2n) { + background: $green; +} + +.filters .filter-subset a { + border-bottom: 2px solid $green; +} + +.filters .filter-subset a:hover, +.filters .filter-subset a:focus { + border-bottom: 2px solid lighten($green, 8%); +} + +.filters .filter-subset a.selected:hover, +.filters .filter-subset a.selected:focus { + border-bottom: 2px solid lighten($blueberry, 8%); +} + +.table>tbody>tr:nth-child(odd)>td, .table>tbody>tr:nth-child(odd)>th { + background: $green; +} + +.table td, .table th { + padding: 8px; + line-height: 18px; + vertical-align: top; + border-top: 1px solid $green; + text-align: left; + background: $blue; +} + +.card__bar { + background: $purple; +} + +.admin-wrapper .sidebar { + background: $green; +} + +.admin-wrapper .content h2, .admin-wrapper .content h4 { + border-bottom: 1px solid #eeeeee; +} + +.admin-wrapper .sidebar ul a.selected { + background: $purple; + border-bottom: 1px solid $purple; +} + +.admin-wrapper .sidebar ul a:hover { + background: lighten($blue, 8%); + border-bottom: 1px solid lighten($blue, 8%); +} + +.admin-wrapper .sidebar ul a.selected:hover { + background: lighten($purple, 4%); + border-bottom: 1px solid lighten($purple, 4%); +} + +.selected ul li a { + background: $blue; + border-bottom: 1px solid $blue; +} + +.admin-wrapper .sidebar ul .simple-navigation-active-leaf a { + background: $blueberry; + border-bottom: 1px solid $blueberry; +} + +.admin-wrapper .sidebar ul .simple-navigation-active-leaf a:hover { + background: lighten($blueberry, 4%); + border-bottom: 1px solid lighten($blueberry, 4%); +} + +.dashboard__counters > div > div, +.dashboard__counters > div > a { + background: $pink; +} + +.dashboard__counters > div > a:hover, +.dashboard__counters > div > a:focus { + background: lighten($pink, 4%); +} + +// Change the text colors on inverted background +.privacy-dropdown__option.active, +.privacy-dropdown__option:hover, +.privacy-dropdown__option.active .privacy-dropdown__option__content, +.privacy-dropdown__option.active .privacy-dropdown__option__content strong, +.privacy-dropdown__option:hover .privacy-dropdown__option__content, +.privacy-dropdown__option:hover .privacy-dropdown__option__content strong, +.dropdown-menu__item a:active, +.dropdown-menu__item a:focus, +.dropdown-menu__item a:hover, +.actions-modal ul li:not(:empty) a.active, +.actions-modal ul li:not(:empty) a.active button, +.actions-modal ul li:not(:empty) a:active, +.actions-modal ul li:not(:empty) a:active button, +.actions-modal ul li:not(:empty) a:focus, +.actions-modal ul li:not(:empty) a:focus button, +.actions-modal ul li:not(:empty) a:hover, +.actions-modal ul li:not(:empty) a:hover button, +.admin-wrapper .sidebar ul .simple-navigation-active-leaf a, +.simple_form .block-button, +.simple_form .button, +.simple_form button { + color: $white; +} + +.dropdown-menu__separator { + border-bottom-color: lighten($ui-base-color, 4%); +} + +// Change the background colors of modals +.actions-modal, +.boost-modal, +.confirmation-modal, +.mute-modal, +.report-modal, +.embed-modal, +.error-modal, +.onboarding-modal { + background: $ui-base-color; +} + +.column-header__collapsible-inner { + background: darken($blue, 4%); + border: 1px solid lighten($blue, 8%); + border-top: 0; +} + +.boost-modal__action-bar, +.confirmation-modal__action-bar, +.mute-modal__action-bar, +.onboarding-modal__paginator, +.error-modal__footer { + background: darken($ui-base-color, 6%); + + .onboarding-modal__nav, + .error-modal__nav { + &:hover, + &:focus, + &:active { + background-color: darken($ui-base-color, 12%); + } + } +} + +.display-case__case { + background: $white; +} + +.embed-modal .embed-modal__container .embed-modal__html { + background: $white; + + &:focus { + background: darken($ui-base-color, 6%); + } +} + +.react-toggle-track { + background: $ui-secondary-color; +} + +.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { + background: darken($ui-secondary-color, 10%); +} + +.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track { + background: lighten($ui-highlight-color, 10%); +} + +// Change the default color used for the text in an empty column or on the error column +.empty-column-indicator, +.error-column { + color: $primary-text-color; + background: $white; +} + +.tabs-bar { + background: $blue; + border: 1px solid lighten($blue, 8%); + border-bottom: 0; + + @media screen and (max-width: $no-gap-breakpoint) { + border-top: 0; + } + + &__link { + padding-bottom: 14px; + border-bottom-width: 1px; + border-bottom-color: lighten($blue, 8%); + + &:hover, + &:active, + &:focus { + background: lighten($blue,4%); + } + + &.active { + &:hover, + &:active, + &:focus { + background: transparent; + border-bottom-color: $ui-highlight-color; + } + } + } +} + +// Change the default colors used on some parts of the profile pages +.activity-stream-tabs { + background: $account-background-color; + border-bottom-color: lighten($ui-base-color, 8%); +} + +.getting-started__wrapper, .getting-started, .flex-spacer { + background: $purple; +} + +.box-widget, +.nothing-here, +.page-header, +.directory__tag > a, +.directory__tag > div, +.landing-page__call-to-action, +.contact-widget, +.landing .hero-widget__text, +.landing-page__information.contact-widget { + background: $white; + border: 1px solid lighten(#eeeeee, 4%); + + @media screen and (max-width: $no-gap-breakpoint) { + border-left: 0; + border-right: 0; + border-top: 0; + } +} + +.directory__tag a:hover, .directory__tag a:focus { + background: $blue; + border: 1px solid lighten($blue, 4%); +} + +.page-header { + background: $purple; + border: 1px solid lighten($purple, 4%); +} + +.directory, .nothing-here, .directory__tag a { + background: $green; + border: 1px solid lighten($green, 4%); +} + +.box-widget { + background: $blue; + border: 1px solid lighten($blue, 4%); +} + +.landing__grid__column-login .box-widget { + background: $pink; + border: 1px solid lighten($pink, 4%); +} + +.landing .hero-widget__text { + border-top: 0; + border-bottom: 0; +} + +.simple_form { + input[type=text], + input[type=number], + input[type=email], + input[type=password], + select, + textarea { + border-color: $blueberry; + &:hover { + border-color: $bilberry; + } + } +} + +.landing .hero-widget__footer { + background: $purple; + border: 1px solid lighten($purple, 8%); + border-top: 0; + + @media screen and (max-width: $no-gap-breakpoint) { + border: 0; + } +} + +.brand__tagline { + color: $ui-secondary-color; +} + +.landing-page__call-to-action { + background: $purple; +} + +.landing-page__information.contact-widget { + background: $green; +} + +.directory__tag > a { + &:hover, + &:active, + &:focus { + background: $ui-base-color; + } + + @media screen and (max-width: $no-gap-breakpoint) { + border: 0; + } +} + +.directory__tag.active > a, +.directory__tag.active > div { + border-color: $ui-highlight-color; + + &, + h4, + h4 small, + .fa, + .trends__item__current { + color: $white; + } + + &:hover, + &:active, + &:focus { + background: $ui-highlight-color; + } +} + + +.batch-table { + &__toolbar, + &__row, + .nothing-here { + border-color: lighten($ui-base-color, 8%); + } +} + +.activity-stream { + border: 1px solid lighten($ui-base-color, 8%); + + &--under-tabs { + border-top: 0; + } + + .entry { + background: $account-background-color; + + .detailed-status.light, + .more.light, + .status.light { + border-bottom-color: lighten($ui-base-color, 8%); + } + } + + .status.light { + .status__content { + color: $primary-text-color; + } + + .display-name { + strong { + color: $primary-text-color; + } + } + } +} + +.accounts-grid { + .account-grid-card { + .controls { + .icon-button { + color: $darker-text-color; + } + } + + .name { + a { + color: $primary-text-color; + } + } + + .username { + color: $darker-text-color; + } + + .account__header__content { + color: $primary-text-color; + } + } +} + +.simple_form, +.table-form { + .warning { + box-shadow: none; + background: rgba($error-red, 0.5); + text-shadow: none; + } + + .recommended { + border-color: $ui-highlight-color; + color: $ui-highlight-color; + background-color: $blue; + } +} + +.compose-form .compose-form__warning { + border-color: $ui-highlight-color; + background-color: darken($blue, 6%); + + &, + a { + color: $ui-highlight-color; + } +} + +.status__content, +.reply-indicator__content { + a { + color: $highlight-text-color; + } +} + +.status.status-direct { + background: darken($green, 6%); +} + +.button.logo-button { + color: $white; + + svg { + fill: $white; + } +} + +.public-layout { + .activity-stream { + border-color: lighten(#eeeeee, 4%); + } + + .account__section-headline { + background: $green; + border: 1px solid lighten($green, 8%); + + @media screen and (max-width: $no-gap-breakpoint) { + border-top: 0; + } + } + + .header, + .public-account-header, + .public-account-bio { + box-shadow: none; + } + + .hero-widget__text { + background: darken($blue, 4%); + border: 1px solid lighten($blue, 4%); + } + + .public-account-bio { + background: $purple; + border: 1px solid lighten($purple, 4%); + } + + .header { + background: $ui-base-color; + border: 1px solid lighten($ui-base-color, 8%); + + @media screen and (max-width: $no-gap-breakpoint) { + border: 0; + } + + .brand { + &:hover, + &:focus, + &:active { + background: darken($pink, 4%); + } + } + } + + .public-account-header { + &__image { + background: lighten($ui-base-color, 12%); + + &::after { + box-shadow: none; + } + } + + &__bar { + &::before { + background: $account-background-color; + border: 1px solid lighten($ui-base-color, 8%); + border-top: 0; + } + + .avatar img { + border-color: $account-background-color; + } + + @media screen and (max-width: $no-columns-breakpoint) { + background: $account-background-color; + border: 1px solid lighten($ui-base-color, 8%); + border-top: 0; + } + } + + &__tabs { + &__name { + h1, + h1 small { + color: $white; + + @media screen and (max-width: $no-columns-breakpoint) { + color: $primary-text-color; + } + } + } + } + + &__extra { + .public-account-bio { + border: 0; + } + + .public-account-bio .account__header__fields { + border-color: lighten($purple, 8%); + } + } + } +} + +.notification__filter-bar button.active::after, +.account__section-headline a.active::after { + border-color: transparent transparent $white; +} + +.hero-widget, +.box-widget, +.contact-widget, +.landing-page__information.contact-widget, +.moved-account-widget, +.memoriam-widget, +.activity-stream, +.nothing-here, +.directory__tag > a, +.directory__tag > div, +.card > a, +.page-header, +.compose-form .compose-form__warning { + box-shadow: none; +} + +body { + background: $cream; +} + +.public-layout .header, .public-layout .public-account-header__image { + background: $pink; + border: 1px solid lighten($pink, 8%); +} + +.public-layout .header .nav-button { + background: darken($pink, 4%); + + &:hover, &:focus { + background: darken($pink, 6%); + } +} + +.public-layout .public-account-header__bar .avatar img { + border: 4px solid $blue; +} + +.public-layout .public-account-header__bar:before { + background: $blue; + border: 1px solid lighten($blue, 8%); +} + +.public-layout .public-account-header__tabs__tabs .counter { + border-right: 1px solid lighten($blue, 8%); +} + +.public-layout .public-account-header__tabs__tabs .counter::after { + border-bottom: 4px solid lighten($blue, 12%); +} + +.public-layout .public-account-header__image { + background: $pink; +} + +.notification__filter-bar button.active::before, .notification__filter-bar button.active::after, .notification__filter-bar a.active::before, .notification__filter-bar a.active::after, .account__section-headline button.active::before, .account__section-headline button.active::after, .account__section-headline a.active::before, .account__section-headline a.active::after { + border-color: transparent transparent $white; +} + +.public-layout .footer .grid .column-2 h4 a, +.public-layout .footer, +.public-layout .footer h4, +.public-layout .footer ul a { + color: $blueberry; +} + +.public-layout .footer .brand svg { + fill: $blueberry; +} + +.account__header__image { + background: $pink; +} + +.detailed-status__wrapper { + background: $purple; +} + +a.status-card.compact:hover { + background: $purple; + border: 1px solid lighten($purple, 4%); +} + +.column-inline-form { + background: $blue; + border: 1px solid lighten($blue, 4%); +} + +.account { + border-bottom: 1px solid #eeeeee; +} + +.notification-favourite .status.status-direct:not(.read) { + background: transparent; + border-bottom: 1px solid lighten(#eeeeee, 4%); +} + +.loading-indicator__figure { + border: 0 solid lighten($green, 12%); +} + +.account__header__bio .account__header__fields { + border-top: 1px solid lighten($purple, 8%); + border-bottom: 1px solid lighten($purple, 8%); +} + +.public-account-bio .account__header__fields { + border-bottom: 1px solid lighten($purple, 8%); +} + +.account__header__fields dl { + border-bottom: 1px solid lighten($purple, 8%); +} + +@media screen and (max-width: 600px) { + .public-layout .public-account-header__bar { + background: $blue; + } + + .public-layout .public-account-header__extra .public-account-bio .account__header__fields { + border-color: lighten($purple, 8%); + background: $purple; + } + + .admin-wrapper .sidebar ul a, .admin-wrapper .sidebar ul ul a { + border-bottom: 1px solid $blue; + } +} + +.audio-player { + background: $ui-base-color; + border: 1px solid lighten($ui-base-color, 8%); + + &__progress-placeholder { + background-color: rgba(lighten($ui-highlight-color, 8%), 0.5); + } + + &__wave-placeholder { + background-color: lighten($ui-base-color, 16%); + } +} + +.audio-player .video-player__controls button, +.audio-player .video-player__time-sep, +.audio-player .video-player__time-current, +.audio-player .video-player__time-total { + color: $ui-primary-color; +} diff --git a/app/javascript/styles/macaron/variables.scss b/app/javascript/styles/macaron/variables.scss new file mode 100644 index 000000000..c4983cc9a --- /dev/null +++ b/app/javascript/styles/macaron/variables.scss @@ -0,0 +1,48 @@ +// Dependent colors +$black: #000000; +$white: #ffffff; +$purple: #c8c4dd; +$blue: #c8dbee; +$green: #dff6eb; +$pink: #ffcbcb; +$blueberry: #5971ad; +$cream: #fffdef; +$bilberry: #ad599c; + +$classic-base-color: #282c37; +$classic-primary-color: #9baec8; +$classic-secondary-color: $green; +$classic-highlight-color: #2b90d9; + +// Differences +$success-green: #3c754d; + +$base-overlay-background: $white !default; +$valid-value-color: $success-green !default; + +$ui-base-color: $classic-secondary-color !default; +$ui-base-lighter-color: $cream; +$ui-primary-color: #9bcbed; +$ui-secondary-color: $classic-base-color !default; +$ui-highlight-color: $blueberry; + +$primary-text-color: $black !default; +$darker-text-color: $classic-base-color !default; +$dark-text-color: #444b5d; +$action-button-color: #606984; + +$inverted-text-color: $black !default; +$lighter-text-color: $classic-base-color !default; +$light-text-color: #444b5d; + +//Newly added colors +$account-background-color: $white !default; + +//Invert darkened and lightened colors +@function darken($color, $amount) { + @return hsl(hue($color), saturation($color), lightness($color) + $amount); +} + +@function lighten($color, $amount) { + @return hsl(hue($color), saturation($color), lightness($color) - $amount); +} diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss index 55ebd3091..14152718d 100644 --- a/app/javascript/styles/mailer.scss +++ b/app/javascript/styles/mailer.scss @@ -228,6 +228,11 @@ h1 { line-height: 36px; } +.column-cell a h1 { + margin: 0 8px 10px; + line-height: 26px; +} + h2 { font-size: 23px; line-height: 30px; diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index d4290d7e6..7a49bf74a 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -195,7 +195,7 @@ html { } .drawer__inner__mastodon { - background: $white url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: $white; } // Change the colors used in compose-form diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss index d6bd9e3c6..da9bfcbdf 100644 --- a/app/javascript/styles/mastodon/about.scss +++ b/app/javascript/styles/mastodon/about.scss @@ -579,7 +579,7 @@ $small-breakpoint: 960px; bottom: 25px; img { - height: 190px; + height: 155px; width: auto; } } @@ -688,6 +688,8 @@ $small-breakpoint: 960px; justify-content: center; align-items: center; padding: 50px; + font-family: $font-display, sans-serif; + font-weight: bold; svg { fill: $primary-text-color; @@ -864,6 +866,22 @@ $small-breakpoint: 960px; .brand { position: relative; text-decoration: none; + color: $secondary-text-color; +} + +a.brand { + color: $primary-text-color; +} + +h1 a.brand { + color: $secondary-text-color; + font-size: 3.8em; +} + +.originalmascotimg svg { + width: 200px; + fill: $secondary-text-color; + margin-top: -25px; } .brand__tagline { @@ -883,4 +901,3 @@ $small-breakpoint: 960px; color: $dark-text-color; } } - diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 25ebc19b0..30035c10e 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -46,6 +46,12 @@ $content-width: 840px; position: relative; bottom: -2px; } + + h2 { + height: 20px; + position: relative; + bottom: -2px; + } } &__icon { @@ -68,15 +74,32 @@ $content-width: 840px; .logo { display: block; - margin: 40px auto; - width: 100px; + margin: 60px 0 0 20px; height: 100px; + + h2 .brand { + color: $primary-text-color; + display: block; + font-size: 24px; + line-height: 28px; + font-weight: 400; + padding-bottom: 40px; + border-bottom: 1px solid lighten($ui-base-color, 8%); + } + } @media screen and (max-width: $no-columns-breakpoint) { & > a:first-child { display: none; } + + .logo, + .logo h2, + .logo h2 .brand { + display: none; + } + } ul { diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss index 9e63b1d31..45cfe0c47 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -138,6 +138,12 @@ body { height: auto; margin-top: -120px; } + + h1 { + a.brand { + font-size: 36px; + } + } } h1 { diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index d6385f161..df7561dc9 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -406,12 +406,6 @@ color: $lighter-text-color; font-weight: 500; text-decoration: underline; - - &:hover, - &:active, - &:focus { - text-decoration: none; - } } } @@ -821,10 +815,6 @@ &.status__content--with-spoiler { white-space: normal; - - .status__content__text { - white-space: pre-wrap; - } } .emojione { @@ -832,11 +822,82 @@ height: 20px; margin: -3px 0 0; } + .status__content__text { + p, + pre, + blockquote { + margin-bottom: 20px; + white-space: pre-wrap; + unicode-bidi: plaintext; - p { - margin-bottom: 20px; - white-space: pre-wrap; - unicode-bidi: plaintext; + &:last-child { + margin-bottom: 2px; + } + } + + h1, + h2, + h3, + h4, + h5 { + margin-top: 20px; + margin-bottom: 20px; + } + + h1 { + font-weight: 700; + font-size: 22px; + } + + h2 { + font-weight: 700; + font-size: 20px; + } + + h3, + h4, + h5 { + font-weight: 500; + } + + blockquote { + padding-left: 10px; + border-left: 3px solid $darker-text-color; + color: $darker-text-color; + white-space: normal; + + p:last-child { + margin-bottom: 0; + } + } + + b, + strong { + font-weight: 700; + } + + em, + i { + font-style: italic; + } + + ul, + ol { + margin-left: 1em; + margin-bottom: 1em; + + p { + margin: 0; + } + } + + ul { + list-style-type: disc; + } + + ol { + list-style-type: decimal; + } &:last-child { margin-bottom: 0; @@ -845,7 +906,7 @@ a { color: $secondary-text-color; - text-decoration: none; + text-decoration: underline; unicode-bidi: isolate; &:hover { @@ -857,13 +918,9 @@ } &.mention { - &:hover { - text-decoration: none; - span { text-decoration: underline; } - } } .fa { @@ -901,6 +958,10 @@ display: block; } } + + .article-type img { + max-width: 95%; + } } .announcements__item__content { @@ -1177,6 +1238,7 @@ .status__action-bar-dropdown { height: 23.15px; width: 23.15px; + margin-right: 18px; } .detailed-status__action-bar-dropdown { @@ -2027,6 +2089,13 @@ a.account__display-name { width: 285px; pointer-events: auto; height: 100%; + + @media screen and (max-width: 1550px) { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 10px; + } + } } @@ -2467,6 +2536,12 @@ a.account__display-name { height: calc(100% - 10px); overflow-y: hidden; + @media screen and (max-width: 1550px) { + height: auto; + min-height: calc(100% - 10px); + overflow-y: visible; + } + .navigation-bar { padding-top: 20px; padding-bottom: 20px; @@ -2493,6 +2568,11 @@ a.account__display-name { background-color: $white; border-radius: 4px 4px 0 0; flex: 0 1 auto; + + @media screen and (max-width: 1550px) { + overflow-y: visible; + } + } .autosuggest-textarea__textarea { @@ -2558,12 +2638,12 @@ a.account__display-name { } .drawer__inner__mastodon { - background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: lighten($ui-base-color, 13%); flex: 1; min-height: 47px; display: none; - > img { + > img, svg { display: block; object-fit: contain; object-position: bottom left; @@ -2575,7 +2655,7 @@ a.account__display-name { } @media screen and (min-height: 640px) { - display: block; + display: flex; } } @@ -2801,6 +2881,15 @@ a.account__display-name { border-color: $ui-highlight-color; } +label[for="is-exclusive-checkbox"] { + margin-left: 20px; +} + +.is-exclusive-checkbox { + transform: scale(0.7); + transform-origin: bottom; +} + .column-link { background: lighten($ui-base-color, 8%); color: $primary-text-color; @@ -3301,7 +3390,7 @@ a.status-card.compact:hover { } &__label { - margin-top: 30px; + margin-top: 0px; strong { display: block; @@ -7257,3 +7346,21 @@ noscript { text-align: center; } } + +.drawer__inner__mastodon svg#hometownlogo { + box-sizing: border-box; + fill: $secondary-text-color; + margin: 0 0 10px 10px; + align-self: flex-end; +} + +div.status__content, +div.status__content--with-action, +div.status__content--with-spoiler { + p { + span.show_more_button { + display: block; + margin: 0.25rem 0 0 0; + } + } +} diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss index cb0301372..24ec67cbd 100644 --- a/app/javascript/styles/mastodon/containers.scss +++ b/app/javascript/styles/mastodon/containers.scss @@ -257,6 +257,29 @@ } } +.originalhero { + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + align-content: space-between; + + svg { + fill: $secondary-text-color; + height: 200px; + } + + h1 { + flex-grow: 2; + text-align: center; + white-space: nowrap; + font-family: $font-display, sans-serif; + font-size: 0.6rem; + } + } + .public-layout { @media screen and (max-width: $no-gap-breakpoint) { padding-top: 48px; @@ -322,6 +345,7 @@ .brand { display: block; padding: 15px; + white-space: nowrap; svg { display: block; @@ -476,8 +500,42 @@ border-radius: 4px 4px 0 0; } + .originalheader { + width: 100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + align-content: space-between; + + svg { + fill: $secondary-text-color; + height: 300px; + } + + h1 { + flex-grow: 2; + text-align: center; + white-space: nowrap; + font-family: $font-display, sans-serif; + } + } + + + @media screen and (max-width: 600px) { height: 200px; + + .originalheader { + svg { + height: 200px; + } + + h1 { + font-size: 0.5rem; + } + } } } diff --git a/app/javascript/styles/mastodon/modal.scss b/app/javascript/styles/mastodon/modal.scss index 962ed1ef5..2a0d477ac 100644 --- a/app/javascript/styles/mastodon/modal.scss +++ b/app/javascript/styles/mastodon/modal.scss @@ -15,7 +15,6 @@ > * { flex: 1; max-height: 235px; - background: url('../images/elephant_ui_plane.svg') no-repeat left bottom / contain; } } diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index 2b5d3ffc2..ede34ea93 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -4,8 +4,8 @@ class ActivityPub::Activity include JsonLdHelper include Redisable - SUPPORTED_TYPES = %w(Note Question).freeze - CONVERTED_TYPES = %w(Image Audio Video Article Page Event).freeze + SUPPORTED_TYPES = %w(Note Question Article).freeze + CONVERTED_TYPES = %w(Image Audio Video Page Event).freeze def initialize(json, account, **options) @json = json diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 612744676..ed641a950 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -77,6 +77,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity @mentions = [] @params = {} + process_inline_images if @object['content'].present? && @object['type'] == 'Article' process_status_params process_tags process_audience @@ -107,7 +108,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity account: @account, text: text_from_content || '', language: detected_language, - spoiler_text: converted_object_type? ? '' : (text_from_summary || ''), + spoiler_text: converted_object_type? ? '' : (text_from_summary || (@object['type'] == 'Article' && text_from_name) || ''), created_at: @object['published'], override_timestamps: @options[:override_timestamps], reply: @object['inReplyTo'].present?, @@ -117,10 +118,61 @@ class ActivityPub::Activity::Create < ActivityPub::Activity conversation: conversation_from_uri(@object['conversation']), media_attachment_ids: process_attachments.take(4).map(&:id), poll: process_poll, + activity_pub_type: @object['type'] } end end + class Handler < ::Ox::Sax + attr_reader :srcs + attr_reader :alts + def initialize(block) + @stack = [] + @srcs = [] + @alts = {} + end + + def start_element(element_name) + @stack << [element_name, {}] + end + + def end_element(element_name) + self_name, self_attributes = @stack[-1] + if self_name == :img && !self_attributes[:src].nil? + @srcs << self_attributes[:src] + @alts[self_attributes[:src]] = self_attributes[:alt] + end + @stack.pop + end + + def attr(attribute_name, attribute_value) + _name, attributes = @stack.last + attributes[attribute_name] = attribute_value + end + end + + def process_inline_images + proc = Proc.new { |name| puts name } + handler = Handler.new(proc) + Ox.sax_parse(handler, @object['content']) + handler.srcs.each do |src| + if skip_download? + @object['content'].gsub!(src, '') + next + end + + media_attachment = MediaAttachment.create(account: @account, remote_url: src, description: handler.alts[src], focus: nil) + media_attachment.file_remote_url = src + media_attachment.save + if unsupported_media_type?(media_attachment.file.content_type) + @object['content'].gsub!(src, '') + media_attachment.delete + else + @object['content'].gsub!(src, media_attachment.file.url(:small)) + end + end + end + def process_audience (audience_to + audience_cc).uniq.each do |audience| next if audience == ActivityPub::TagManager::COLLECTIONS[:public] @@ -391,6 +443,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def text_from_content return Formatter.instance.linkify([[text_from_name, text_from_summary.presence].compact.join("\n\n"), object_url || object_uri].join(' ')) if converted_object_type? + return Formatter.instance.format_article(@object['content']) if @object['content'].present? && @object['type'] == 'Article' + if @object['content'].present? @object['content'] elsif content_language_map? diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index f0ad3e21f..c9ddaceb6 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -40,9 +40,9 @@ class FeedManager def filter?(timeline_type, status, receiver) case timeline_type when :home - filter_from_home?(status, receiver.id, build_crutches(receiver.id, [status])) + filter_from_home?(status, receiver.id, build_crutches(receiver.id, [status]), :home) when :list - filter_from_list?(status, receiver) || filter_from_home?(status, receiver.account_id, build_crutches(receiver.account_id, [status])) + filter_from_list?(status, receiver) || filter_from_home?(status, receiver.account_id, build_crutches(receiver.account_id, [status]), :list) when :mentions filter_from_mentions?(status, receiver.id) else @@ -315,10 +315,17 @@ class FeedManager # @param [Integer] receiver_id # @param [Hash] crutches # @return [Boolean] - def filter_from_home?(status, receiver_id, crutches) + def filter_from_home?(status, receiver_id, crutches, timeline_type=:home) return false if receiver_id == status.account_id return true if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?) return true if phrase_filtered?(status, receiver_id, :home) + # hometown: exclusive list rules + unless timeline_type == :list + # find all exclusive lists + @list = List.where(account: Account.find(receiver_id), is_exclusive: true) + # is there a list the receiver owns with this account on it? if so, return true + return true if ListAccount.where(list: @list, account_id: status.account_id).exists? + end check_for_blocks = crutches[:active_mentions][status.id] || [] check_for_blocks.concat([status.account_id]) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 7f217ae9f..fbf8b3e5e 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -91,6 +91,12 @@ class Formatter html.html_safe # rubocop:disable Rails/OutputSafety end + def format_article(text) + text = text.gsub(/>\n+<") + text = "#{text}" + text.html_safe # rubocop:disable Rails/OutputSafety + end + def linkify(text) html = encode_and_link_urls(text) html = simple_format(html, {}, sanitize: false) diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb index 8f700197b..d1836e8df 100644 --- a/app/lib/sanitize_config.rb +++ b/app/lib/sanitize_config.rb @@ -71,11 +71,14 @@ class Sanitize end MASTODON_STRICT ||= freeze_config( - elements: %w(p br span a), + elements: %w(p br span a abbr del pre blockquote code b strong i em h1 h2 h3 h4 h5 ul ol li img), attributes: { - 'a' => %w(href rel class), - 'span' => %w(class), + 'a' => %w(href rel class title), + 'span' => %w(class), + 'abbr' => %w(title), + 'blockquote' => %w(cite), + 'img' => %w(src alt), }, add_attributes: { @@ -83,9 +86,15 @@ class Sanitize 'rel' => 'nofollow noopener noreferrer', 'target' => '_blank', }, + 'span' => { + 'class' => 'article-type', + }, }, - protocols: {}, + protocols: { + 'a' => { 'href' => HTTP_PROTOCOLS }, + 'blockquote' => { 'cite' => HTTP_PROTOCOLS }, + }, transformers: [ CLASS_WHITELIST_TRANSFORMER, diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 95996ba3f..4bd36b5fd 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -19,7 +19,7 @@ class UserMailer < Devise::Mailer I18n.with_locale(@resource.locale || I18n.default_locale) do mail to: @resource.unconfirmed_email.presence || @resource.email, - subject: I18n.t(@resource.pending_reconfirmation? ? 'devise.mailer.reconfirmation_instructions.subject' : 'devise.mailer.confirmation_instructions.subject', instance: @instance), + subject: I18n.t(@resource.pending_reconfirmation? ? 'devise.mailer.reconfirmation_instructions.subject' : 'devise.mailer.confirmation_instructions.subject', instance: @instance, title: Setting.site_title), template_name: @resource.pending_reconfirmation? ? 'reconfirmation_instructions' : 'confirmation_instructions' end end @@ -32,7 +32,7 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? I18n.with_locale(@resource.locale || I18n.default_locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject') + mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject', title: Setting.site_title) end end @@ -43,7 +43,7 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? I18n.with_locale(@resource.locale || I18n.default_locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject') + mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject', title: Setting.site_title) end end @@ -54,7 +54,7 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? I18n.with_locale(@resource.locale || I18n.default_locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.email_changed.subject') + mail to: @resource.email, subject: I18n.t('devise.mailer.email_changed.subject', title: Setting.site_title) end end @@ -144,7 +144,7 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? I18n.with_locale(@resource.locale || I18n.default_locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject') + mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject', title: Setting.site_title) end end @@ -156,7 +156,7 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? I18n.with_locale(@resource.locale || I18n.default_locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject') + mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject', title: Setting.site_title) end end diff --git a/app/models/list.rb b/app/models/list.rb index cdc6ebdb3..ca62e934b 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -9,6 +9,7 @@ # created_at :datetime not null # updated_at :datetime not null # replies_policy :integer default("list"), not null +# is_exclusive :boolean default(FALSE) # class List < ApplicationRecord diff --git a/app/models/status.rb b/app/models/status.rb index 21adb6f0f..381052c0c 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -24,6 +24,7 @@ # poll_id :bigint(8) # deleted_at :datetime # local_only :boolean +# activity_pub_type :string # class Status < ApplicationRecord diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 4778c7a28..387a511bb 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -2,10 +2,15 @@ class InitialStateSerializer < ActiveModel::Serializer attributes :meta, :compose, :accounts, - :media_attachments, :settings + :media_attachments, :settings, + :max_toot_chars has_one :push_subscription, serializer: REST::WebPushSubscriptionSerializer + def max_toot_chars + StatusLengthValidator::MAX_CHARS + end + def meta store = { streaming_api_base_url: Rails.configuration.x.streaming_api_base_url, diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index b388e448e..ee67f9df6 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -4,7 +4,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer include RoutingHelper attributes :uri, :title, :short_description, :description, :email, - :version, :urls, :stats, :thumbnail, + :version, :urls, :stats, :thumbnail, :max_toot_chars, :languages, :registrations, :approval_required, :invites_enabled has_one :contact_account, serializer: REST::AccountSerializer @@ -39,6 +39,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('media/images/preview.jpg') end + def max_toot_chars + StatusLengthValidator::MAX_CHARS + end + def stats { user_count: instance_presenter.user_count, diff --git a/app/serializers/rest/list_serializer.rb b/app/serializers/rest/list_serializer.rb index 3e87f7119..7dc2f1487 100644 --- a/app/serializers/rest/list_serializer.rb +++ b/app/serializers/rest/list_serializer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class REST::ListSerializer < ActiveModel::Serializer - attributes :id, :title, :replies_policy + attributes :id, :title, :replies_policy, :is_exclusive def id object.id.to_s diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 495ac5ed2..4761933ea 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -4,7 +4,7 @@ class REST::StatusSerializer < ActiveModel::Serializer attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id, :sensitive, :spoiler_text, :visibility, :language, :uri, :url, :replies_count, :reblogs_count, - :favourites_count, :local_only + :favourites_count, :local_only, :activity_pub_type attribute :favourited, if: :current_user? attribute :reblogged, if: :current_user? @@ -70,6 +70,10 @@ class REST::StatusSerializer < ActiveModel::Serializer ActivityPub::TagManager.instance.uri_for(object) end + def activity_pub_type + object.activity_pub_type.to_s + end + def content Formatter.instance.format(object) end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index fdda25b36..76cc9241b 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -87,9 +87,21 @@ class PostStatusService < BaseService end end - def local_only_option(local_only, in_reply_to, federation_setting) - return in_reply_to&.local_only? if local_only.nil? # XXX temporary, just until clients implement to avoid leaking local_only posts - return federation_setting if local_only.nil? + def local_only_option(local_only, in_reply_to, federation_setting, text) + # This is intended for third party clients. The admin can set a custom :local_only: + # emoji that users can append to force a post to be local only. + if text.include? ":local_only:" + return true + end + if local_only.nil? + if in_reply_to && in_reply_to.local_only + return true + end + if in_reply_to && !in_reply_to.local_only + return false + end + return !federation_setting + end local_only end @@ -172,7 +184,7 @@ class PostStatusService < BaseService language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account), application: @options[:application], rate_limit: @options[:with_rate_limit], - local_only: local_only_option(@options[:local_only], @in_reply_to, @account.user&.setting_default_federation), + local_only: local_only_option(@options[:local_only], @in_reply_to, @account.user&.setting_default_federation, @text), }.compact end diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb index 93bae2fa8..92ee5e643 100644 --- a/app/validators/status_length_validator.rb +++ b/app/validators/status_length_validator.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class StatusLengthValidator < ActiveModel::Validator - MAX_CHARS = 500 + MAX_CHARS = (ENV['MAX_TOOT_CHARS'] || 500).to_i def validate(status) return unless status.local? && !status.reblog? diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml index e4d614d71..7fdff6ace 100644 --- a/app/views/about/_registration.html.haml +++ b/app/views/about/_registration.html.haml @@ -1,6 +1,6 @@ .simple_form__overlay-area{ class: (closed_registrations? && @instance_presenter.closed_registrations_message.present?) ? 'simple_form__overlay-area__blurred' : '' } = simple_form_for(new_user, url: user_registration_path, namespace: 'registration', html: { novalidate: false }) do |f| - %p.lead= t('about.federation_hint_html', instance: content_tag(:strong, site_hostname)) + %p.lead= t('about.federation_hint_html', instance: content_tag(:strong, site_title)) .fields-group = f.simple_fields_for :account do |account_fields| diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml index 109b5fa86..01771e0fc 100644 --- a/app/views/about/more.html.haml +++ b/app/views/about/more.html.haml @@ -9,7 +9,14 @@ .column-0 .public-account-header.public-account-header--no-bar .public-account-header__image - = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title, class: 'parallax' + - if @instance_presenter.hero.present? || @instance_presenter.thumbnail.present? + = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url, alt: @instance_presenter.site_title, class: 'parallax' + - else + %div{:class => ("originalheader")} + = svg_logo + %h1 + = link_to root_url, class: 'brand' do + = site_title .column-1 .landing-page__call-to-action{ dir: 'ltr' } @@ -24,8 +31,13 @@ %strong= number_to_human @instance_presenter.status_count, strip_insignificant_zeros: true %span= t 'about.status_count_after', count: @instance_presenter.status_count .row__mascot - .landing-page__mascot - = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('media/images/elephant_ui_plane.svg'), alt: '' + - if @instance_presenter.mascot&.file&.url + .landing-page__mascot + = image_tag @instance_presenter.mascot&.file&.url + - else + .landing-page__mascot{:class => ("originalmascot")} + %div{:class => ("originalmascotimg")} + = svg_logo .column-2 .contact-widget diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml index 565c4ed59..1f9931c60 100644 --- a/app/views/about/show.html.haml +++ b/app/views/about/show.html.haml @@ -7,9 +7,9 @@ .landing .landing__brand - = link_to root_url, class: 'brand' do - = svg_logo_full - %span.brand__tagline=t 'about.tagline' + %h1 + = link_to root_url, class: 'brand' do + = site_title .landing__grid .landing__grid__column.landing__grid__column-registration @@ -35,22 +35,29 @@ %h4 = fa_icon 'globe fw' = t('about.see_whats_happening') - %small= t('about.browse_public_posts') + %small= t('about.browse_public_posts', title: site_title) .directory__tag = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener noreferrer' do %h4 = fa_icon 'tablet fw' = t('about.get_apps') - %small= t('about.apps_platforms') + %small= t('about.apps_platforms', title: site_title) .landing__grid__column.landing__grid__column-login .box-widget = render 'login' .hero-widget - .hero-widget__img - = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title + - if @instance_presenter.hero.present? || @instance_presenter.thumbnail.present? + .hero-widget__img + = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url, alt: @instance_presenter.site_title + - else + %div{:class => ("originalhero")} + = svg_logo + %h1 + = link_to root_url, class: 'brand' do + = site_title .hero-widget__text %p diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 2849f07aa..abe10dda0 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -77,7 +77,7 @@ %h4= t 'admin.dashboard.software' %ul %li - Mastodon + Hometown %span.pull-right= @version %li Ruby diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml index 7ec91c06a..947e183fe 100644 --- a/app/views/application/_sidebar.html.haml +++ b/app/views/application/_sidebar.html.haml @@ -1,6 +1,7 @@ .hero-widget - .hero-widget__img - = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title + - if @instance_presenter.hero.present? || @instance_presenter.thumbnail.present? + .hero-widget__img + = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url, alt: @instance_presenter.site_title .hero-widget__text %p= @instance_presenter.site_short_description.html_safe.presence || t('about.about_mastodon_html') diff --git a/app/views/auth/registrations/_sessions.html.haml b/app/views/auth/registrations/_sessions.html.haml index d3a04c00e..a0cdd231d 100644 --- a/app/views/auth/registrations/_sessions.html.haml +++ b/app/views/auth/registrations/_sessions.html.haml @@ -1,5 +1,5 @@ %h3= t 'sessions.title' -%p.muted-hint= t 'sessions.explanation' +%p.muted-hint= t('sessions.explanation', title: site_title) %hr.spacer/ diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 94cc782b2..b3fb9c758 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -10,7 +10,7 @@ .app-holder#mastodon{ data: { props: Oj.dump(default_props) } } %noscript - = image_pack_tag 'logo.svg', alt: 'Mastodon' + = image_pack_tag 'logo.svg', alt: site_title %div - = t('errors.noscript_html', apps_path: 'https://joinmastodon.org/apps') + = t('errors.noscript_html', apps_path: 'https://joinmastodon.org/apps', title: site_title) diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 62716ab1e..33da9f250 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -7,13 +7,16 @@ .sidebar-wrapper .sidebar-wrapper__inner .sidebar - = link_to root_path do - = image_pack_tag 'logo.svg', class: 'logo', alt: 'Mastodon' + .logo + %h2 + = link_to root_url, class: 'brand' do + = site_title .sidebar__toggle .sidebar__toggle__logo - = link_to root_path do - = svg_logo_full + %h2 + = link_to root_path, class: 'brand' do + = site_title = link_to '#', class: 'sidebar__toggle__icon' do = fa_icon 'bars' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 9501207e0..e1665c7e8 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -39,5 +39,4 @@ = content_for?(:content) ? yield(:content) : yield .logo-resources - = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg') - = render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg') + = render file: Rails.root.join('app', 'javascript', 'images', 'hometown.svg') diff --git a/app/views/layouts/auth.html.haml b/app/views/layouts/auth.html.haml index 0ea3bbe3b..35d69fbaf 100644 --- a/app/views/layouts/auth.html.haml +++ b/app/views/layouts/auth.html.haml @@ -5,8 +5,8 @@ .container-alt .logo-container %h1 - = link_to root_path do - = svg_logo_full + = link_to root_path, class: 'brand' do + = site_title .form-container = render 'flashes' diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml index 852a0c69b..1bbcfd6b9 100644 --- a/app/views/layouts/error.html.haml +++ b/app/views/layouts/error.html.haml @@ -12,6 +12,8 @@ %body.error .dialog .dialog__illustration - %img{ alt: Setting.default_settings['site_title'], src: '/oops.png' }/ + %h1 + = link_to root_url, class: 'brand' do + = Setting.default_settings['site_title'] .dialog__message %h1= yield :content diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml index 343bcb265..e01272946 100644 --- a/app/views/layouts/mailer.html.haml +++ b/app/views/layouts/mailer.html.haml @@ -24,7 +24,8 @@ %tr %td.column-cell = link_to root_url do - = image_tag full_pack_url('media/images/mailer/logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo' + %h1 + = site_title = yield @@ -49,4 +50,5 @@ %p= link_to t('application_mailer.notification_preferences'), settings_preferences_notifications_url %td.column-cell.text-right = link_to root_url do - = image_tag full_pack_url('media/images/mailer/logo_transparent.png'), alt: 'Mastodon', height: 24 + %h4 + = site_title diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml index e63cf0848..c3d141d78 100644 --- a/app/views/layouts/public.html.haml +++ b/app/views/layouts/public.html.haml @@ -9,7 +9,7 @@ %nav.header .nav-left = link_to root_url, class: 'brand' do - = svg_logo_full + = site_title - unless whitelist_mode? = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory diff --git a/app/views/public_timelines/show.html.haml b/app/views/public_timelines/show.html.haml index 3325be5bf..95a9dc0ec 100644 --- a/app/views/public_timelines/show.html.haml +++ b/app/views/public_timelines/show.html.haml @@ -7,11 +7,10 @@ .page-header %h1= t('about.see_whats_happening') - - if Setting.show_known_fediverse_at_about_page - %p= t('about.browse_public_posts') + %p= t('about.browse_public_posts', title: site_title) - else - %p= t('about.browse_local_posts') + %p= t('about.browse_local_posts', title: site_title) #mastodon-timeline{ data: { props: Oj.dump(default_props.merge(local: !Setting.show_known_fediverse_at_about_page)) }} #modal-container diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 4885878f0..2066630f3 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -48,7 +48,7 @@ .fields-row__column.fields-group.fields-row__column-6 %h6= t('verification.verification') - %p.hint= t('verification.explanation_html') + %p.hint= t('verification.explanation_html', instance: site_hostname) .input-copy .input-copy__wrapper diff --git a/app/views/user_mailer/backup_ready.html.haml b/app/views/user_mailer/backup_ready.html.haml index 85140b08b..6009d584d 100644 --- a/app/views/user_mailer/backup_ready.html.haml +++ b/app/views/user_mailer/backup_ready.html.haml @@ -36,7 +36,7 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.backup_ready.explanation' + %p= t('user_mailer.backup_ready.explanation', title: site_title) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/reconfirmation_instructions.html.haml b/app/views/user_mailer/reconfirmation_instructions.html.haml index 7f10ba94f..c02d44724 100644 --- a/app/views/user_mailer/reconfirmation_instructions.html.haml +++ b/app/views/user_mailer/reconfirmation_instructions.html.haml @@ -57,4 +57,4 @@ %tbody %tr %td.column-cell.text-center.padded - %p= t 'devise.mailer.reconfirmation_instructions.extra' + %p= t 'devise.mailer.reconfirmation_instructions.extra', title: site_title diff --git a/app/views/user_mailer/welcome.html.haml b/app/views/user_mailer/welcome.html.haml index 1f75ff48a..de1d8395b 100644 --- a/app/views/user_mailer/welcome.html.haml +++ b/app/views/user_mailer/welcome.html.haml @@ -135,7 +135,7 @@ %h5= t 'user_mailer.welcome.tips' %ul %li - %span= t 'user_mailer.welcome.tip_mobile_webapp' + %span= t 'user_mailer.welcome.tip_mobile_webapp', instance: @instance %li %span= t 'user_mailer.welcome.tip_following' %li diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index a3f2c5796..13275642a 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -23,28 +23,28 @@ en: 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. 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 login to change your details or delete your account, but you cannot access most of the functions until your account is approved. 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. extra_html: Please also check out the rules of the server and our terms of service. - subject: 'Mastodon: Confirmation instructions for %{instance}' + subject: '%{title}: Confirmation instructions' title: Verify email address email_changed: explanation: 'The email address for your account is being changed to:' 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 server admin if you're locked out of your account. - subject: 'Mastodon: Email changed' + subject: '%{title}: Email changed' title: New email address password_change: explanation: The password for your account has been changed. 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 server admin if you're locked out of your account. - subject: 'Mastodon: Password changed' + subject: '%{title}: Password changed' title: Password changed reconfirmation_instructions: explanation: Confirm the new address to change your email. - 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. - subject: 'Mastodon: Confirm email for %{instance}' + extra: If this change wasn't initiated by you, please ignore this email. The email address for the %{title} account won't change until you access the link above. + subject: '%{title}: Confirm email' title: Verify email address reset_password_instructions: action: Change password explanation: You requested a new password for your account. 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. - subject: 'Mastodon: Reset password instructions' + subject: '%{title}: Reset password instructions' title: Password reset two_factor_disabled: explanation: Two-factor authentication for your account has been disabled. Login is now possible using only e-mail address and password. diff --git a/config/locales/en.yml b/config/locales/en.yml index 7291c4476..6aedbb0ba 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,26 +1,26 @@ --- en: about: - about_hashtag_html: These are public toots tagged with #%{hashtag}. You can interact with them if you have an account anywhere in the fediverse. - about_mastodon_html: 'The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!' + about_hashtag_html: These are public posts tagged with #%{hashtag}. You can interact with them if you have an account anywhere in the fediverse. + about_mastodon_html: 'Hometown is adapted from Mastodon, a decentralized social network with no ads, no corporate surveillance, and ethical design.' about_this: About active_count_after: active active_footnote: Monthly Active Users (MAU) administered_by: 'Administered by:' api: API apps: Mobile apps - apps_platforms: Use Mastodon from iOS, Android and other platforms + apps_platforms: Use %{title} from iOS, Android and other platforms browse_directory: Browse a profile directory and filter by interests browse_local_posts: Browse a live stream of public posts from this server - browse_public_posts: Browse a live stream of public posts on Mastodon + browse_public_posts: Browse a live stream of public posts on %{title} contact: Contact contact_missing: Not set contact_unavailable: N/A discover_users: Discover users documentation: Documentation - federation_hint_html: With an account on %{instance} you'll be able to follow people on any Mastodon server and beyond. + federation_hint_html: With an account on %{instance} you'll be able to follow people on any Hometown or Mastodon server and beyond. get_apps: Try a mobile app - hosted_on: Mastodon hosted on %{domain} + hosted_on: Hometown hosted on %{domain} instance_actor_flash: | This account is a virtual actor used to represent the server itself and not any individual user. It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block. @@ -50,7 +50,7 @@ en: one: user other: users user_count_before: Home to - what_is_mastodon: What is Mastodon? + what_is_mastodon: What is Hometown/Mastodon? accounts: choices_html: "%{name}'s choices:" endorsements_hint: You can endorse people you follow from the web interface, and they will show up here. @@ -74,10 +74,10 @@ en: pin_errors: following: You must be already following the person you want to endorse posts: - one: Toot - other: Toots - posts_tab_heading: Toots - posts_with_replies: Toots and replies + one: Post + other: Posts + posts_tab_heading: Posts + posts_with_replies: Posts and replies reserved_username: The username is reserved roles: admin: Admin @@ -489,11 +489,11 @@ en: relays: add_new: Add new relay delete: Delete - description_html: A federation relay is an intermediary server that exchanges large volumes of public toots between servers that subscribe and publish to it. It can help small and medium servers discover content from the fediverse, which would otherwise require local users manually following other people on remote servers. + description_html: A federation relay is an intermediary server that exchanges large volumes of public posts between servers that subscribe and publish to it. It can help small and medium servers discover content from the fediverse, which would otherwise require local users manually following other people on remote servers. disable: Disable disabled: Disabled enable: Enable - enable_hint: Once enabled, your server will subscribe to all public toots from this relay, and will begin sending this server's public toots to it. + enable_hint: Once enabled, your server will subscribe to all public posts from this relay, and will begin sending this server's public posts to it. enabled: Enabled inbox_url: Relay URL pending: Waiting for relay's approval @@ -609,13 +609,13 @@ en: desc_html: Show a staff badge on a user page title: Show staff badge site_description: - desc_html: Introductory paragraph on the API. Describe what makes this Mastodon server special and anything else important. You can use HTML tags, in particular <a> and <em>. + desc_html: Introductory paragraph on the API. Describe what makes this Hometown server special and anything else important. You can use HTML tags, in particular <a> and <em>. title: Server description site_description_extended: desc_html: A good place for your code of conduct, rules, guidelines and other things that set your server apart. You can use HTML tags title: Custom extended information site_short_description: - desc_html: Displayed in sidebar and meta tags. Describe what Mastodon is and what makes this server special in a single paragraph. + desc_html: Displayed in sidebar and meta tags. Describe what Hometown is and what makes this server special in a single paragraph. title: Short server description site_terms: desc_html: You can write your own privacy policy, terms of service or other legalese. You can use HTML tags @@ -707,7 +707,7 @@ en: guide_link: https://crowdin.com/project/mastodon guide_link_text: Everyone can contribute. sensitive_content: Sensitive content - toot_layout: Toot layout + toot_layout: Post layout application_mailer: notification_preferences: Change e-mail preferences salutation: "%{name}," @@ -842,6 +842,7 @@ en: '500': content: We're sorry, but something went wrong on our end. title: This page is not correct + noscript_html: To use the %{title} web application, please enable JavaScript. Alternatively, try one of the native apps for Hometown/Mastodon for your platform. '503': The page could not be served due to a temporary server failure. noscript_html: To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the native apps for Mastodon for your platform. existing_username_validator: @@ -851,7 +852,7 @@ en: archive_takeout: date: Date download: Download your archive - hint_html: You can request an archive of your toots and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. + hint_html: You can request an archive of your posts and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. in_progress: Compiling your archive... request: Request your archive size: Size @@ -917,7 +918,7 @@ en: i_am_html: I am %{username} on %{service}. identity: Identity inactive: Inactive - publicize_checkbox: 'And toot this:' + publicize_checkbox: 'And post this:' publicize_toot: 'It is proven! I am %{username} on %{service}: %{url}' remove: Remove proof from account removed: Successfully removed proof from account @@ -1117,16 +1118,16 @@ en: remote_interaction: favourite: proceed: Proceed to favourite - prompt: 'You want to favourite this toot:' + prompt: 'You want to favourite this post:' reblog: proceed: Proceed to boost - prompt: 'You want to boost this toot:' + prompt: 'You want to boost this post:' reply: proceed: Proceed to reply - prompt: 'You want to reply to this toot:' + prompt: 'You want to reply to this post:' scheduled_statuses: - over_daily_limit: You have exceeded the limit of %{limit} scheduled toots for that day - over_total_limit: You have exceeded the limit of %{limit} scheduled toots + over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for that day + over_total_limit: You have exceeded the limit of %{limit} scheduled posts too_soon: The scheduled date must be in the future sessions: activity: Last activity @@ -1151,7 +1152,7 @@ en: weibo: Weibo current_session: Current session description: "%{browser} on %{platform}" - explanation: These are the web browsers currently logged in to your Mastodon account. + explanation: These are the web browsers currently logged in to your %{title} account. ip: IP platforms: adobe_air: Adobe Air @@ -1175,7 +1176,7 @@ en: aliases: Account aliases appearance: Appearance authorized_apps: Authorized apps - back: Back to Mastodon + back: Back home delete: Account deletion development: Development edit_profile: Edit profile @@ -1217,9 +1218,9 @@ en: open_in_web: Open in web over_character_limit: character limit of %{max} exceeded pin_errors: - limit: You have already pinned the maximum number of toots - ownership: Someone else's toot cannot be pinned - private: Non-public toot cannot be pinned + limit: You have already pinned the maximum number of posts + ownership: Someone else's post cannot be pinned + private: Non-public post cannot be pinned reblog: A boost cannot be pinned poll: total_people: @@ -1243,7 +1244,7 @@ en: unlisted: Unlisted unlisted_long: Everyone can see, but not listed on public timelines stream_entries: - pinned: Pinned toot + pinned: Pinned post reblogged: boosted sensitive_content: Sensitive content tags: @@ -1256,7 +1257,7 @@ en:
  • Basic account information: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.
  • Posts, following and other public information: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.
  • -
  • Direct and followers-only posts: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. Please keep in mind that the operators of the server and any receiving server may view such messages, and that recipients may screenshot, copy or otherwise re-share them. Do not share any dangerous information over Mastodon.
  • +
  • Direct and followers-only posts: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it's important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. Please keep in mind that the operators of the server and any receiving server may view such messages, and that recipients may screenshot, copy or otherwise re-share them. Do not share any dangerous information over Hometown/Mastodon.
  • IPs and other metadata: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.
@@ -1267,7 +1268,7 @@ en:

Any of the information we collect from you may be used in the following ways:

    -
  • To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.
  • +
  • To provide the core functionality of Hometown/Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.
  • To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.
  • The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.
@@ -1335,6 +1336,8 @@ en: contrast: Mastodon (High contrast) default: Mastodon (Dark) mastodon-light: Mastodon (Light) + macaron: Macaron (Pastel light) + fairy-floss: Fairy Floss (Pastel dark) time: formats: default: "%b %d, %Y, %H:%M" @@ -1356,7 +1359,7 @@ en: webauthn: Security keys user_mailer: backup_ready: - explanation: You requested a full backup of your Mastodon account. It's now ready for download! + explanation: You requested a full backup of your %{title} account. It's now ready for download! subject: Your archive is ready for download title: Archive takeout sign_in_token: @@ -1396,11 +1399,11 @@ en: full_handle_hint: This is what you would tell your friends so they can message or follow you from another server. review_preferences_action: Change preferences review_preferences_step: Make sure to set your preferences, such as which emails you'd like to receive, or what privacy level you’d like your posts to default to. If you don’t have motion sickness, you could choose to enable GIF autoplay. - subject: Welcome to Mastodon - tip_federated_timeline: The federated timeline is a firehose view of the Mastodon network. But it only includes people your neighbours are subscribed to, so it's not complete. + subject: Welcome to %{title} + tip_federated_timeline: The federated timeline is a firehose view of the wider network. But it only includes people your neighbours are subscribed to, so it's not complete. tip_following: You follow your server's admin(s) by default. To find more interesting people, check the local and federated timelines. tip_local_timeline: The local timeline is a firehose view of people on %{instance}. These are your immediate neighbours! - tip_mobile_webapp: If your mobile browser offers you to add Mastodon to your homescreen, you can receive push notifications. It acts like a native app in many ways! + tip_mobile_webapp: If your Android mobile browser prompts you to add %{instance} to your homescreen, you can receive push notifications from the web app. It acts like a native app in many ways! On iOS, you can still pin %{instance} to your homescreen, but you will not receive push notifications. tips: Tips title: Welcome aboard, %{name}! users: @@ -1416,7 +1419,7 @@ en: signed_in_as: 'Signed in as:' suspicious_sign_in_confirmation: You appear to not have logged in from this device before, and you haven't logged in for a while, so we're sending a security code to your e-mail address to confirm that it's you. verification: - explanation_html: 'You can verify yourself as the owner of the links in your profile metadata. For that, the linked website must contain a link back to your Mastodon profile. The link back must have a rel="me" attribute. The text content of the link does not matter. Here is an example:' + explanation_html: 'You can verify yourself as the owner of the links in your profile metadata. For that, the linked website must contain a link back to your %{instance} profile. The link back must have a rel="me" attribute. The text content of the link does not matter. Here is an example:' verification: Verification webauthn_credentials: add: Add new security key diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index d3461474b..d80bffc79 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -1,7 +1,7 @@ --- en_GB: about: - about_hashtag_html: These are public toots tagged with #%{hashtag}. You can interact with them if you have an account anywhere in the fediverse. + about_hashtag_html: These are public posts tagged with #%{hashtag}. You can interact with them if you have an account anywhere in the fediverse. about_mastodon_html: Mastodon is a social network based on open web protocols and free, open-source software. It is decentralized like e-mail. about_this: About active_count_after: active @@ -59,10 +59,10 @@ en_GB: pin_errors: following: You must be already following the person you want to endorse posts: - one: Toot - other: Toots - posts_tab_heading: Toots - posts_with_replies: Toots and replies + one: Post + other: Posts + posts_tab_heading: Posts + posts_with_replies: Posts and replies reserved_username: The username is reserved roles: admin: Admin @@ -181,11 +181,11 @@ en_GB: create_account_warning: "%{name} sent a warning to %{target}" create_custom_emoji: "%{name} uploaded new emoji %{target}" create_domain_block: "%{name} blocked domain %{target}" - create_email_domain_block: "%{name} blacklisted e-mail domain %{target}" + create_email_domain_block: "%{name} blocklisted e-mail domain %{target}" demote_user: "%{name} demoted user %{target}" destroy_custom_emoji: "%{name} destroyed emoji %{target}" destroy_domain_block: "%{name} unblocked domain %{target}" - destroy_email_domain_block: "%{name} whitelisted e-mail domain %{target}" + destroy_email_domain_block: "%{name} allowlisted e-mail domain %{target}" destroy_status: "%{name} removed status by %{target}" disable_2fa_user: "%{name} disabled two factor requirement for user %{target}" disable_custom_emoji: "%{name} disabled emoji %{target}" @@ -289,14 +289,14 @@ en_GB: undo: Undo domain block email_domain_blocks: add_new: Add new - created_msg: Successfully added e-mail domain to blacklist + created_msg: Successfully added e-mail domain to blocklist delete: Delete - destroyed_msg: Successfully deleted e-mail domain from blacklist + destroyed_msg: Successfully deleted e-mail domain from blocklist domain: Domain new: create: Add domain - title: New e-mail blacklist entry - title: E-mail blacklist + title: New e-mail blocklist entry + title: E-mail blocklist followers: back_to_account: Back To Account title: "%{acct}'s Followers" @@ -327,11 +327,11 @@ en_GB: relays: add_new: Add new relay delete: Delete - description_html: A federation relay is an intermediary server that exchanges large volumes of public toots between servers that subscribe and publish to it. It can help small and medium servers discover content from the fediverse, which would otherwise require local users manually following other people on remote servers. + description_html: A federation relay is an intermediary server that exchanges large volumes of public posts between servers that subscribe and publish to it. It can help small and medium servers discover content from the fediverse, which would otherwise require local users manually following other people on remote servers. disable: Disable disabled: Disabled enable: Enable - enable_hint: Once enabled, your server will subscribe to all public toots from this relay, and will begin sending this server's public toots to it. + enable_hint: Once enabled, your server will subscribe to all public posts from this relay, and will begin sending this server's public posts to it. enabled: Enabled inbox_url: Relay URL pending: Waiting for relay's approval @@ -417,7 +417,7 @@ en_GB: open: Anyone can sign up title: Registrations mode show_known_fediverse_at_about_page: - desc_html: When toggled, it will show toots from all the known fediverse on preview. Otherwise it will only show local toots. + desc_html: When toggled, it will show posts from all the known fediverse on preview. Otherwise it will only show local posts. title: Show known fediverse on timeline preview show_staff_badge: desc_html: Show a staff badge on a user page @@ -583,7 +583,7 @@ en_GB: archive_takeout: date: Date download: Download your archive - hint_html: You can request an archive of your toots and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. + hint_html: You can request an archive of your posts and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. in_progress: Compiling your archive... request: Request your archive size: Size @@ -775,20 +775,20 @@ en_GB: remote_interaction: favourite: proceed: Proceed to favourite - prompt: 'You want to favourite this toot:' + prompt: 'You want to favourite this post:' reblog: proceed: Proceed to boost - prompt: 'You want to boost this toot:' + prompt: 'You want to boost this post:' reply: proceed: Proceed to reply - prompt: 'You want to reply to this toot:' + prompt: 'You want to reply to this post:' remote_unfollow: error: Error title: Title unfollowed: Unfollowed scheduled_statuses: - over_daily_limit: You have exceeded the limit of %{limit} scheduled toots for that day - over_total_limit: You have exceeded the limit of %{limit} scheduled toots + over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for that day + over_total_limit: You have exceeded the limit of %{limit} scheduled posts too_soon: The scheduled date must be in the future sessions: activity: Last activity @@ -833,7 +833,7 @@ en_GB: title: Sessions settings: authorized_apps: Authorized apps - back: Back to Mastodon + back: Back home delete: Account deletion development: Development edit_profile: Edit profile @@ -864,9 +864,9 @@ en_GB: open_in_web: Open in web over_character_limit: character limit of %{max} exceeded pin_errors: - limit: You have already pinned the maximum number of toots - ownership: Someone else's toot cannot be pinned - private: Non-public toot cannot be pinned + limit: You have already pinned the maximum number of posts + ownership: Someone else's post cannot be pinned + private: Non-public post cannot be pinned reblog: A boost cannot be pinned poll: total_votes: @@ -884,7 +884,7 @@ en_GB: unlisted: Unlisted unlisted_long: Everyone can see, but not listed on public timelines stream_entries: - pinned: Pinned toot + pinned: Pinned post reblogged: boosted sensitive_content: Sensitive content terms: @@ -1002,8 +1002,8 @@ en_GB: warning: explanation: disable: While your account is frozen, your account data remains intact, but you cannot perform any actions until it is unlocked. - silence: While your account is limited, only people who are already following you will see your toots on this server, and you may be excluded from various public listings. However, others may still manually follow you. - suspend: Your account has been suspended, and all of your toots and your uploaded media files have been irreversibly removed from this server, and servers where you had followers. + silence: While your account is limited, only people who are already following you will see your posts on this server, and you may be excluded from various public listings. However, others may still manually follow you. + suspend: Your account has been suspended, and all of your posts and your uploaded media files have been irreversibly removed from this server, and servers where you had followers. review_server_policies: Review server policies subject: disable: Your account %{acct} has been frozen diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index d15be063e..acfbde0fc 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -7,12 +7,12 @@ en: account_migration: acct: Specify the username@domain of the account you want to move to account_warning_preset: - text: You can use toot syntax, such as URLs, hashtags and mentions + text: You can use post syntax, such as URLs, hashtags and mentions title: Optional. Not visible to the recipient admin_account_action: - include_statuses: The user will see which toots have caused the moderation action or warning + include_statuses: The user will see which posts have caused the moderation action or warning send_email_notification: The user will receive an explanation of what happened with their account - text_html: Optional. You can use toot syntax. You can add warning presets to save time + text_html: Optional. You can use post syntax. You can add warning presets to save time type_html: Choose what to do with %{acct} warning_preset_id: Optional. You can still add custom text to end of the preset announcement: @@ -20,7 +20,7 @@ en: ends_at: Optional. Announcement will be automatically unpublished at this time scheduled_at: Leave blank to publish the announcement immediately starts_at: Optional. In case your announcement is bound to a specific time range - text: You can use toot syntax. Please be mindful of the space the announcement will take up on the user's screen + text: You can use post syntax. Please be mindful of the space the announcement will take up on the user's screen defaults: autofollow: People who sign up through the invite will automatically follow you avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px @@ -34,21 +34,21 @@ en: fields: You can have up to 4 items displayed as a table on your profile header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px inbox_url: Copy the URL from the frontpage of the relay you want to use - irreversible: Filtered toots will disappear irreversibly, even if filter is later removed + irreversible: Filtered posts will disappear irreversibly, even if filter is later removed locale: The language of the user interface, e-mails and push notifications locked: Requires you to manually approve followers password: Use at least 8 characters - phrase: Will be matched regardless of casing in text or content warning of a toot + phrase: Will be matched regardless of casing in text or content warning of a post scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. - setting_aggregate_reblogs: Do not show new boosts for toots that have been recently boosted (only affects newly-received boosts) - setting_default_federation: Toots do not federate to other instances unless manually changed while composing + setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts) + setting_default_federation:
  • If checked, your new posts federate to other instances unless manually changed while composing in the web interface.
  • If unchecked, your new posts stay local unless manually changed while composing in the web interface.
  • Third party apps will make new posts that respect this setting. See here for more info on third-party apps
setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click setting_display_media_default: Hide media marked as sensitive setting_display_media_hide_all: Always hide media setting_display_media_show_all: Always show media setting_hide_network: Who you follow and who follows you will not be shown on your profile setting_noindex: Affects your public profile and status pages - setting_show_application: The application you use to toot will be displayed in the detailed view of your toots + setting_show_application: The application you use to post will be displayed in the detailed view of your posts setting_use_blurhash: Gradients are based on the colors of the hidden visuals but obfuscate any details setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed username: Your username will be unique on %{domain} @@ -80,7 +80,7 @@ en: tag: name: You can only change the casing of the letters, for example, to make it more readable user: - chosen_languages: When checked, only toots in selected languages will be displayed in public timelines + chosen_languages: When checked, only posts in selected languages will be displayed in public timelines labels: account: fields: @@ -94,7 +94,7 @@ en: text: Preset text title: Title admin_account_action: - include_statuses: Include reported toots in the e-mail + include_statuses: Include reported posts in the e-mail send_email_notification: Notify the user per e-mail text: Custom warning type: Action @@ -142,22 +142,22 @@ en: setting_aggregate_reblogs: Group boosts in timelines setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting - setting_crop_images: Crop images in non-expanded toots to 16x9 - setting_default_federation: Allow my toots to reach other instances by default + setting_crop_images: Crop images in non-expanded posts to 16x9 + setting_default_federation: Allow my posts to reach other instances by default setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive - setting_delete_modal: Show confirmation dialog before deleting a toot + setting_delete_modal: Show confirmation dialog before deleting a post setting_disable_swiping: Disable swiping motions setting_display_media: Media display setting_display_media_default: Default setting_display_media_hide_all: Hide all setting_display_media_show_all: Show all - setting_expand_spoilers: Always expand toots marked with content warnings + setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_network: Hide your network setting_noindex: Opt-out of search engine indexing setting_reduce_motion: Reduce motion in animations - setting_show_application: Disclose application used to send toots + setting_show_application: Disclose application used to send posts setting_system_font_ui: Use system's default font setting_theme: Site theme setting_trends: Show today's trends @@ -203,7 +203,7 @@ en: listable: Allow this hashtag to appear in searches and on the profile directory name: Hashtag trendable: Allow this hashtag to appear under trends - usable: Allow toots to use this hashtag + usable: Allow posts to use this hashtag 'no': 'No' recommended: Recommended required: diff --git a/config/settings.yml b/config/settings.yml index c87f0bdb9..24b4b9592 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -2,7 +2,7 @@ # important settings can be changed from the admin interface. defaults: &defaults - site_title: Mastodon + site_title: Hometown site_short_description: '' site_description: '' site_extended_description: '' diff --git a/config/themes.yml b/config/themes.yml index 9c21c9459..620bc7f99 100644 --- a/config/themes.yml +++ b/config/themes.yml @@ -1,3 +1,5 @@ default: styles/application.scss contrast: styles/contrast.scss mastodon-light: styles/mastodon-light.scss +macaron: styles/macaron.scss +fairy-floss: styles/fairy-floss.scss diff --git a/db/migrate/20190712233435_add_activitypub_type_to_statuses.rb b/db/migrate/20190712233435_add_activitypub_type_to_statuses.rb new file mode 100644 index 000000000..8929ae061 --- /dev/null +++ b/db/migrate/20190712233435_add_activitypub_type_to_statuses.rb @@ -0,0 +1,5 @@ +class AddActivityPubTypeToStatuses < ActiveRecord::Migration[5.2] + def change + add_column :statuses, :activity_pub_type, :string + end +end diff --git a/db/migrate/20190726034905_add_is_exclusive_to_lists.rb b/db/migrate/20190726034905_add_is_exclusive_to_lists.rb new file mode 100644 index 000000000..937b236e0 --- /dev/null +++ b/db/migrate/20190726034905_add_is_exclusive_to_lists.rb @@ -0,0 +1,6 @@ +class AddIsExclusiveToLists < ActiveRecord::Migration[5.2] + def change + add_column :lists, :is_exclusive, :boolean + change_column_default :lists, :is_exclusive, false + end +end diff --git a/db/schema.rb b/db/schema.rb index f96a1bc03..819e9103f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -490,6 +490,7 @@ ActiveRecord::Schema.define(version: 2020_12_18_054746) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "replies_policy", default: 0, null: false + t.boolean "is_exclusive", default: false t.index ["account_id"], name: "index_lists_on_account_id" end @@ -806,6 +807,7 @@ ActiveRecord::Schema.define(version: 2020_12_18_054746) do t.bigint "poll_id" t.datetime "deleted_at" t.boolean "local_only" + t.string "activity_pub_type" t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)" t.index ["id", "account_id"], name: "index_statuses_local_20190824", order: { id: :desc }, where: "((local OR (uri IS NULL)) AND (deleted_at IS NULL) AND (visibility = 0) AND (reblog_of_id IS NULL) AND ((NOT reply) OR (in_reply_to_account_id = account_id)))" t.index ["id", "account_id"], name: "index_statuses_public_20200119", order: { id: :desc }, where: "((deleted_at IS NULL) AND (visibility = 0) AND (reblog_of_id IS NULL) AND ((NOT reply) OR (in_reply_to_account_id = account_id)))" diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png index 7a99a1964..677aa9bc7 100644 Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index b12aa55a3..ee9b03cbb 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/avatars/original/missing-mastodon.png b/public/avatars/original/missing-mastodon.png new file mode 100644 index 000000000..34c8e45e6 Binary files /dev/null and b/public/avatars/original/missing-mastodon.png differ diff --git a/public/avatars/original/missing.png b/public/avatars/original/missing.png index 34c8e45e6..29b27183b 100644 Binary files a/public/avatars/original/missing.png and b/public/avatars/original/missing.png differ diff --git a/public/favicon.ico b/public/favicon.ico index 79000c9cc..10d892a88 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png index a4994062d..b27eb3b3a 100644 Binary files a/public/mstile-150x150.png and b/public/mstile-150x150.png differ