Direct messages column (#4514)

* Added a timeline for Direct statuses
* Lists all Direct statuses you've sent and received
* Displayed in Getting Started
* Streaming server support for direct TL

* Changes to match other timelines in 2.0
This commit is contained in:
Kaito Sinclaire 2018-04-18 04:09:06 -07:00 committed by Eugen Rochko
parent aedfea3554
commit 156b916caf
58 changed files with 538 additions and 15 deletions

View File

@ -0,0 +1,60 @@
# frozen_string_literal: true
class Api::V1::Timelines::DirectController < Api::BaseController
before_action -> { doorkeeper_authorize! :read }, only: [:show]
before_action :require_user!, only: [:show]
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
respond_to :json
def show
@statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
end
private
def load_statuses
cached_direct_statuses
end
def cached_direct_statuses
cache_collection direct_statuses, Status
end
def direct_statuses
direct_timeline_statuses.paginate_by_max_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params[:max_id],
params[:since_id]
)
end
def direct_timeline_statuses
Status.as_direct_timeline(current_account)
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def pagination_params(core_params)
params.permit(:local, :limit).merge(core_params)
end
def next_path
api_v1_timelines_direct_url pagination_params(max_id: pagination_max_id)
end
def prev_path
api_v1_timelines_direct_url pagination_params(since_id: pagination_since_id)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
end
end

View File

@ -145,6 +145,8 @@ export function submitCompose() {
if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
insertIfOnline('community');
insertIfOnline('public');
} else if (response.data.visibility === 'direct') {
insertIfOnline('direct');
}
}).catch(function (error) {
dispatch(submitComposeFail(error));

View File

@ -46,4 +46,5 @@ export const connectCommunityStream = () => connectTimelineStream('community', '
export const connectMediaStream = () => connectTimelineStream('community', 'public:local');
export const connectPublicStream = () => connectTimelineStream('public', 'public');
export const connectHashtagStream = (tag) => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
export const connectListStream = (id) => connectTimelineStream(`list:${id}`, `list&list=${id}`);

View File

@ -87,6 +87,7 @@ export function expandTimeline(timelineId, path, params = {}) {
export const expandHomeTimeline = ({ maxId } = {}) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId });
export const expandPublicTimeline = ({ maxId } = {}) => expandTimeline('public', '/api/v1/timelines/public', { max_id: maxId });
export const expandCommunityTimeline = ({ maxId } = {}) => expandTimeline('community', '/api/v1/timelines/public', { local: true, max_id: maxId });
export const expandDirectTimeline = ({ maxId } = {}) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId });
export const expandAccountTimeline = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId });
export const expandAccountFeaturedTimeline = accountId => expandTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true });
export const expandAccountMediaTimeline = (accountId, { maxId } = {}) => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { max_id: maxId, only_media: true });

View File

@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import ColumnSettings from '../../community_timeline/components/column_settings';
import { changeSetting } from '../../../actions/settings';
const mapStateToProps = state => ({
settings: state.getIn(['settings', 'direct']),
});
const mapDispatchToProps = dispatch => ({
onChange (key, checked) {
dispatch(changeSetting(['direct', ...key], checked));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(ColumnSettings);

View File

@ -0,0 +1,104 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../../components/column';
import ColumnHeader from '../../components/column_header';
import { expandDirectTimeline } from '../../actions/timelines';
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ColumnSettingsContainer from './containers/column_settings_container';
import { connectDirectStream } from '../../actions/streaming';
const messages = defineMessages({
title: { id: 'column.direct', defaultMessage: 'Direct messages' },
});
const mapStateToProps = state => ({
hasUnread: state.getIn(['timelines', 'direct', 'unread']) > 0,
});
@connect(mapStateToProps)
@injectIntl
export default class DirectTimeline extends React.PureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
columnId: PropTypes.string,
intl: PropTypes.object.isRequired,
hasUnread: PropTypes.bool,
multiColumn: PropTypes.bool,
};
handlePin = () => {
const { columnId, dispatch } = this.props;
if (columnId) {
dispatch(removeColumn(columnId));
} else {
dispatch(addColumn('DIRECT', {}));
}
}
handleMove = (dir) => {
const { columnId, dispatch } = this.props;
dispatch(moveColumn(columnId, dir));
}
handleHeaderClick = () => {
this.column.scrollTop();
}
componentDidMount () {
const { dispatch } = this.props;
dispatch(expandDirectTimeline());
this.disconnect = dispatch(connectDirectStream());
}
componentWillUnmount () {
if (this.disconnect) {
this.disconnect();
this.disconnect = null;
}
}
setRef = c => {
this.column = c;
}
handleLoadMore = maxId => {
this.props.dispatch(expandDirectTimeline({ maxId }));
}
render () {
const { intl, hasUnread, columnId, multiColumn } = this.props;
const pinned = !!columnId;
return (
<Column ref={this.setRef}>
<ColumnHeader
icon='envelope'
active={hasUnread}
title={intl.formatMessage(messages.title)}
onPin={this.handlePin}
onMove={this.handleMove}
onClick={this.handleHeaderClick}
pinned={pinned}
multiColumn={multiColumn}
>
<ColumnSettingsContainer />
</ColumnHeader>
<StatusListContainer
trackScroll={!pinned}
scrollKey={`direct_timeline-${columnId}`}
timelineId='direct'
onLoadMore={this.handleLoadMore}
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any direct messages yet. When you send or receive one, it will show up here." />}
/>
</Column>
);
}
}

View File

@ -19,6 +19,7 @@ const messages = defineMessages({
navigation_subheading: { id: 'column_subheading.navigation', defaultMessage: 'Navigation' },
settings_subheading: { id: 'column_subheading.settings', defaultMessage: 'Settings' },
community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
direct: { id: 'navigation_bar.direct', defaultMessage: 'Direct messages' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
@ -98,20 +99,24 @@ export default class GettingStarted extends ImmutablePureComponent {
}
}
if (!multiColumn || !columns.find(item => item.get('id') === 'DIRECT')) {
navItems.push(<ColumnLink key='4' icon='envelope' text={intl.formatMessage(messages.direct)} to='/timelines/direct' />);
}
navItems.push(
<ColumnLink key='4' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
<ColumnLink key='5' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
<ColumnLink key='5' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
<ColumnLink key='6' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
);
if (myAccount.get('locked')) {
navItems.push(<ColumnLink key='6' icon='users' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
navItems.push(<ColumnLink key='7' icon='users' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
}
if (multiColumn) {
navItems.push(<ColumnLink key='7' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' />);
navItems.push(<ColumnLink key='8' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' />);
}
navItems.push(<ColumnLink key='8' icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />);
navItems.push(<ColumnLink key='9' icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />);
return (
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile>

View File

@ -12,7 +12,7 @@ import BundleContainer from '../containers/bundle_container';
import ColumnLoading from './column_loading';
import DrawerLoading from './drawer_loading';
import BundleColumnError from './bundle_column_error';
import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, FavouritedStatuses, ListTimeline } from '../../ui/util/async-components';
import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, ListTimeline } from '../../ui/util/async-components';
import detectPassiveEvents from 'detect-passive-events';
import { scrollRight } from '../../../scroll';
@ -24,6 +24,7 @@ const componentMap = {
'PUBLIC': PublicTimeline,
'COMMUNITY': CommunityTimeline,
'HASHTAG': HashtagTimeline,
'DIRECT': DirectTimeline,
'FAVOURITES': FavouritedStatuses,
'LIST': ListTimeline,
};

View File

@ -30,6 +30,7 @@ import {
Following,
Reblogs,
Favourites,
DirectTimeline,
HashtagTimeline,
Notifications,
FollowRequests,
@ -79,6 +80,7 @@ const keyMap = {
goToNotifications: 'g n',
goToLocal: 'g l',
goToFederated: 'g t',
goToDirect: 'g d',
goToStart: 'g s',
goToFavourites: 'g f',
goToPinned: 'g p',
@ -140,6 +142,7 @@ class SwitchingColumnsArea extends React.PureComponent {
<WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} />
<WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} />
<WrappedRoute path='/timelines/public/local' component={CommunityTimeline} content={children} />
<WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} />
<WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} />
<WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} />
@ -386,6 +389,10 @@ export default class UI extends React.PureComponent {
this.context.router.history.push('/timelines/public');
}
handleHotkeyGoToDirect = () => {
this.context.router.history.push('/timelines/direct');
}
handleHotkeyGoToStart = () => {
this.context.router.history.push('/getting-started');
}
@ -425,6 +432,7 @@ export default class UI extends React.PureComponent {
goToNotifications: this.handleHotkeyGoToNotifications,
goToLocal: this.handleHotkeyGoToLocal,
goToFederated: this.handleHotkeyGoToFederated,
goToDirect: this.handleHotkeyGoToDirect,
goToStart: this.handleHotkeyGoToStart,
goToFavourites: this.handleHotkeyGoToFavourites,
goToPinned: this.handleHotkeyGoToPinned,

View File

@ -26,6 +26,10 @@ export function HashtagTimeline () {
return import(/* webpackChunkName: "features/hashtag_timeline" */'../../hashtag_timeline');
}
export function DirectTimeline() {
return import(/* webpackChunkName: "features/direct_timeline" */'../../direct_timeline');
}
export function ListTimeline () {
return import(/* webpackChunkName: "features/list_timeline" */'../../list_timeline');
}

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "إعادة المحاولة",
"column.blocks": "الحسابات المحجوبة",
"column.community": "الخيط العام المحلي",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "المفضلة",
"column.follow_requests": "طلبات المتابعة",
@ -100,6 +101,7 @@
"emoji_button.symbols": "رموز",
"emoji_button.travel": "أماكن و أسفار",
"empty_column.community": "الخط الزمني المحلي فارغ. أكتب شيئا ما للعامة كبداية !",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "ليس هناك بعدُ أي محتوى ذو علاقة بهذا الوسم.",
"empty_column.home": "إنك لا تتبع بعد أي شخص إلى حد الآن. زر {public} أو استخدام حقل البحث لكي تبدأ على التعرف على مستخدمين آخرين.",
"empty_column.home.public_timeline": "الخيط العام",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "هل تود إخفاء الإخطارات القادمة من هذا المستخدم ؟",
"navigation_bar.blocks": "الحسابات المحجوبة",
"navigation_bar.community_timeline": "الخيط العام المحلي",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "تعديل الملف الشخصي",
"navigation_bar.favourites": "المفضلة",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} و {results}}",
"standalone.public_title": "نظرة على ...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "تعذرت ترقية هذا المنشور",
"status.delete": "إحذف",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "تدبيس على الملف الشخصي",
"status.pinned": "تبويق مثبَّت",
"status.reblog": "رَقِّي",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} رقى",
"status.reply": "ردّ",
"status.replyAll": "رُد على الخيط",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Symbols",
"emoji_button.travel": "Travel & Places",
"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.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",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Редактирай профил",
"navigation_bar.favourites": "Favourites",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Изтриване",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.reblog": "Споделяне",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} сподели",
"status.reply": "Отговор",
"status.replyAll": "Reply to thread",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Torna-ho a provar",
"column.blocks": "Usuaris blocats",
"column.community": "Línia de temps local",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorits",
"column.follow_requests": "Peticions per seguir-te",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Símbols",
"emoji_button.travel": "Viatges i Llocs",
"empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per fer rodar la pilota!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Encara no hi ha res amb aquesta etiqueta.",
"empty_column.home": "Encara no segueixes ningú. Visita {public} o fes cerca per començar i conèixer altres usuaris.",
"empty_column.home.public_timeline": "la línia de temps pública",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Amagar notificacions d'aquest usuari?",
"navigation_bar.blocks": "Usuaris bloquejats",
"navigation_bar.community_timeline": "Línia de temps Local",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favorits",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
"standalone.public_title": "Una mirada a l'interior ...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
"status.delete": "Esborrar",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Fixat en el perfil",
"status.pinned": "Toot fixat",
"status.reblog": "Impuls",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} ha retootejat",
"status.reply": "Respondre",
"status.replyAll": "Respondre al tema",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Erneut versuchen",
"column.blocks": "Blockierte Profile",
"column.community": "Lokale Zeitleiste",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriten",
"column.follow_requests": "Folgeanfragen",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Symbole",
"emoji_button.travel": "Reisen und Orte",
"empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe einen öffentlichen Beitrag, um den Ball ins Rollen zu bringen!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Unter diesem Hashtag gibt es noch nichts.",
"empty_column.home": "Deine Startseite ist leer! Besuche {public} oder nutze die Suche, um loszulegen und andere Leute zu finden.",
"empty_column.home.public_timeline": "die öffentliche Zeitleiste",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Benachrichtigungen von diesem Account verbergen?",
"navigation_bar.blocks": "Blockierte Profile",
"navigation_bar.community_timeline": "Lokale Zeitleiste",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profil bearbeiten",
"navigation_bar.favourites": "Favoriten",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
"standalone.public_title": "Ein kleiner Einblick …",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
"status.delete": "Löschen",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Im Profil anheften",
"status.pinned": "Pinned toot",
"status.reblog": "Teilen",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} teilte",
"status.reply": "Antworten",
"status.replyAll": "Auf Thread antworten",

View File

@ -242,6 +242,14 @@
"defaultMessage": "Boost",
"id": "status.reblog"
},
{
"defaultMessage": "Boost to original audience",
"id": "status.reblog_private"
},
{
"defaultMessage": "Unboost",
"id": "status.cancel_reblog_private"
},
{
"defaultMessage": "This post cannot be boosted",
"id": "status.cannot_reblog"
@ -897,6 +905,19 @@
],
"path": "app/javascript/mastodon/features/compose/index.json"
},
{
"descriptors": [
{
"defaultMessage": "Direct messages",
"id": "column.direct"
},
{
"defaultMessage": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"id": "empty_column.direct"
}
],
"path": "app/javascript/mastodon/features/direct_timeline/index.json"
},
{
"descriptors": [
{
@ -971,6 +992,10 @@
"defaultMessage": "Local timeline",
"id": "navigation_bar.community_timeline"
},
{
"defaultMessage": "Direct messages",
"id": "navigation_bar.direct"
},
{
"defaultMessage": "Preferences",
"id": "navigation_bar.preferences"
@ -1399,6 +1424,14 @@
"defaultMessage": "Boost",
"id": "status.reblog"
},
{
"defaultMessage": "Boost to original audience",
"id": "status.reblog_private"
},
{
"defaultMessage": "Unboost",
"id": "status.cancel_reblog_private"
},
{
"defaultMessage": "This post cannot be boosted",
"id": "status.cannot_reblog"

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Symbols",
"emoji_button.travel": "Travel & Places",
"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.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",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.reblog": "Boost",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} boosted",
"status.reply": "Reply",
"status.replyAll": "Reply to thread",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Bonvolu reprovi",
"column.blocks": "Blokitaj uzantoj",
"column.community": "Loka tempolinio",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Stelumoj",
"column.follow_requests": "Petoj de sekvado",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Simboloj",
"emoji_button.travel": "Vojaĝoj kaj lokoj",
"empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
"empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.",
"empty_column.home.public_timeline": "la publikan tempolinion",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn el ĉi tiu uzanto?",
"navigation_bar.blocks": "Blokitaj uzantoj",
"navigation_bar.community_timeline": "Loka tempolinio",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Redakti profilon",
"navigation_bar.favourites": "Stelumoj",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}",
"standalone.public_title": "Enrigardo…",
"status.block": "Bloki @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
"status.delete": "Forigi",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Alpingli profile",
"status.pinned": "Alpinglita mesaĝo",
"status.reblog": "Diskonigi",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} diskonigis",
"status.reply": "Respondi",
"status.replyAll": "Respondi al la fadeno",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Inténtalo de nuevo",
"column.blocks": "Usuarios bloqueados",
"column.community": "Línea de tiempo local",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritos",
"column.follow_requests": "Solicitudes de seguimiento",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viajes y lugares",
"empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "No hay nada en este hashtag aún.",
"empty_column.home": "No estás siguiendo a nadie aún. Visita {public} o haz búsquedas para empezar y conocer gente nueva.",
"empty_column.home.public_timeline": "la línea de tiempo pública",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Ocultar notificaciones de este usuario?",
"navigation_bar.blocks": "Usuarios bloqueados",
"navigation_bar.community_timeline": "Historia local",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritos",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
"standalone.public_title": "Un pequeño vistazo...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Este toot no puede retootearse",
"status.delete": "Borrar",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Fijar",
"status.pinned": "Toot fijado",
"status.reblog": "Retootear",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "Retooteado por {name}",
"status.reply": "Responder",
"status.replyAll": "Responder al hilo",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "تلاش دوباره",
"column.blocks": "کاربران مسدودشده",
"column.community": "نوشته‌های محلی",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "پسندیده‌ها",
"column.follow_requests": "درخواست‌های پیگیری",
@ -100,6 +101,7 @@
"emoji_button.symbols": "نمادها",
"emoji_button.travel": "سفر و مکان",
"empty_column.community": "فهرست نوشته‌های محلی خالی است. چیزی بنویسید تا چرخش بچرخد!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "هنوز هیچ چیزی با این هشتگ نیست.",
"empty_column.home": "شما هنوز پیگیر کسی نیستید. {public} را ببینید یا چیزی را جستجو کنید تا کاربران دیگر را ببینید.",
"empty_column.home.public_timeline": "فهرست نوشته‌های همه‌جا",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "اعلان‌های این کاربر پنهان شود؟",
"navigation_bar.blocks": "کاربران مسدودشده",
"navigation_bar.community_timeline": "نوشته‌های محلی",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "ویرایش نمایه",
"navigation_bar.favourites": "پسندیده‌ها",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}",
"standalone.public_title": "نگاهی به کاربران این سرور...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",
"status.delete": "پاک‌کردن",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "نوشتهٔ ثابت نمایه",
"status.pinned": "Pinned toot",
"status.reblog": "بازبوقیدن",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} بازبوقید",
"status.reply": "پاسخ",
"status.replyAll": "به نوشته پاسخ دهید",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Yritä uudestaan",
"column.blocks": "Estetyt käyttäjät",
"column.community": "Paikallinen aikajana",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Suosikit",
"column.follow_requests": "Seuraamispyynnöt",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Symbolit",
"emoji_button.travel": "Matkailu",
"empty_column.community": "Paikallinen aikajana on tyhjä. Homma lähtee käyntiin, kun kirjoitat jotain julkista!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Tällä hashtagilla ei ole vielä mitään.",
"empty_column.home": "Kotiaikajanasi on tyhjä! {public} ja hakutoiminto auttavat alkuun ja kohtaamaan muita käyttäjiä.",
"empty_column.home.public_timeline": "yleinen aikajana",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Piilota tältä käyttäjältä tulevat ilmoitukset?",
"navigation_bar.blocks": "Estetyt käyttäjät",
"navigation_bar.community_timeline": "Paikallinen aikajana",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Muokkaa profiilia",
"navigation_bar.favourites": "Suosikit",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "Kurkistus sisälle...",
"status.block": "Estä @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Tätä julkaisua ei voi buustata",
"status.delete": "Poista",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Kiinnitä profiiliin",
"status.pinned": "Kiinnitetty tuuttaus",
"status.reblog": "Buustaa",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} buustasi",
"status.reply": "Vastaa",
"status.replyAll": "Vastaa ketjuun",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Réessayer",
"column.blocks": "Comptes bloqués",
"column.community": "Fil public local",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoris",
"column.follow_requests": "Demandes de suivi",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Symboles",
"emoji_button.travel": "Lieux & Voyages",
"empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Il ny a encore aucun contenu associé à ce hashtag.",
"empty_column.home": "Vous ne suivez encore personne. Visitez {public} ou bien utilisez la recherche pour vous connecter à dautres personnes.",
"empty_column.home.public_timeline": "le fil public",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Masquer les notifications de cette personne ?",
"navigation_bar.blocks": "Comptes bloqués",
"navigation_bar.community_timeline": "Fil public local",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Modifier le profil",
"navigation_bar.favourites": "Favoris",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
"standalone.public_title": "Un aperçu …",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Cette publication ne peut être boostée",
"status.delete": "Effacer",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Épingler sur le profil",
"status.pinned": "Pouet épinglé",
"status.reblog": "Partager",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} a partagé:",
"status.reply": "Répondre",
"status.replyAll": "Répondre au fil",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Inténteo de novo",
"column.blocks": "Usuarias bloqueadas",
"column.community": "Liña temporal local",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoritas",
"column.follow_requests": "Peticións de seguimento",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viaxes e Lugares",
"empty_column.community": "A liña temporal local está baldeira. Escriba algo de xeito público para que rule!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Aínda non hai nada con esta etiqueta.",
"empty_column.home": "A súa liña temporal de inicio está baldeira! Visite {public} ou utilice a busca para atopar outras usuarias.",
"empty_column.home.public_timeline": "a liña temporal pública",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Esconder notificacións deste usuario?",
"navigation_bar.blocks": "Usuarias bloqueadas",
"navigation_bar.community_timeline": "Liña temporal local",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritas",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count,plural,one {result} outros {results}}",
"standalone.public_title": "Ollada dentro...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Esta mensaxe non pode ser promocionada",
"status.delete": "Eliminar",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Fixar no perfil",
"status.pinned": "Pinned toot",
"status.reblog": "Promover",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} promoveu",
"status.reply": "Resposta",
"status.replyAll": "Resposta a conversa",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "לנסות שוב",
"column.blocks": "חסימות",
"column.community": "ציר זמן מקומי",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "חיבובים",
"column.follow_requests": "בקשות מעקב",
@ -100,6 +101,7 @@
"emoji_button.symbols": "סמלים",
"emoji_button.travel": "טיולים ואתרים",
"empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "אין כלום בהאשתג הזה עדיין.",
"empty_column.home": "אף אחד לא במעקב עדיין. אפשר לבקר ב{public} או להשתמש בחיפוש כדי להתחיל ולהכיר חצוצרנים אחרים.",
"empty_column.home.public_timeline": "ציר זמן בין-קהילתי",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "להסתיר הודעות מחשבון זה?",
"navigation_bar.blocks": "חסימות",
"navigation_bar.community_timeline": "ציר זמן מקומי",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "עריכת פרופיל",
"navigation_bar.favourites": "חיבובים",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}",
"standalone.public_title": "הצצה פנימה...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "לא ניתן להדהד הודעה זו",
"status.delete": "מחיקה",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "לקבע באודות",
"status.pinned": "Pinned toot",
"status.reblog": "הדהוד",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "הודהד על ידי {name}",
"status.reply": "תגובה",
"status.replyAll": "תגובה לכולם",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blokirani korisnici",
"column.community": "Lokalni timeline",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favoriti",
"column.follow_requests": "Zahtjevi za slijeđenje",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Simboli",
"emoji_button.travel": "Putovanja & Mjesta",
"empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Još ne postoji ništa s ovim hashtagom.",
"empty_column.home": "Još ne slijediš nikoga. Posjeti {public} ili koristi tražilicu kako bi počeo i upoznao druge korisnike.",
"empty_column.home.public_timeline": "javni timeline",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Blokirani korisnici",
"navigation_bar.community_timeline": "Lokalni timeline",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Uredi profil",
"navigation_bar.favourites": "Favoriti",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ovaj post ne može biti boostan",
"status.delete": "Obriši",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.reblog": "Podigni",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} je podigao",
"status.reply": "Odgovori",
"status.replyAll": "Odgovori na temu",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Próbálja újra",
"column.blocks": "Letiltott felhasználók",
"column.community": "Helyi idővonal",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Kedvencek",
"column.follow_requests": "Követési kérések",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Szimbólumok",
"emoji_button.travel": "Utazás és Helyek",
"empty_column.community": "A helyi idővonal üres. Írj egy publikus stástuszt, hogy elindítsd a labdát!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Jelenleg nem található semmi ezen hashtaggel.",
"empty_column.home": "A hazai idővonala üres! Látogasd meg a {public} vagy használd a keresőt, hogy ismerj meg más felhasználókat.",
"empty_column.home.public_timeline": "publikus idővonal",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Értesítések elrejtése ezen felhasználótól?",
"navigation_bar.blocks": "Tiltott felhasználók",
"navigation_bar.community_timeline": "Helyi idővonal",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Profil szerkesztése",
"navigation_bar.favourites": "Kedvencek",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "Betekintés...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ezen státusz nem rebloggolható",
"status.delete": "Törlés",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Kitűzés a profilra",
"status.pinned": "Pinned toot",
"status.reblog": "Reblog",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} reblogolta",
"status.reply": "Válasz",
"status.replyAll": "Válaszolj a beszélgetésre",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Կրկին փորձել",
"column.blocks": "Արգելափակված օգտատերեր",
"column.community": "Տեղական հոսք",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Հավանածներ",
"column.follow_requests": "Հետեւելու հայցեր",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Նշաններ",
"emoji_button.travel": "Ուղեւորություն եւ տեղանքներ",
"empty_column.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Այս պիտակով դեռ ոչինչ չկա։",
"empty_column.home": "Քո հիմնական հոսքը դատա՛րկ է։ Այցելի՛ր {public}ը կամ օգտվիր որոնումից՝ այլ մարդկանց հանդիպելու համար։",
"empty_column.home.public_timeline": "հրապարակային հոսք",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Թաքցնե՞լ ցանուցումներն այս օգտատիրոջից։",
"navigation_bar.blocks": "Արգելափակված օգտատերեր",
"navigation_bar.community_timeline": "Տեղական հոսք",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Խմբագրել անձնական էջը",
"navigation_bar.favourites": "Հավանածներ",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "Այս պահին…",
"status.block": "Արգելափակել @{name}֊ին",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Այս թութը չի կարող տարածվել",
"status.delete": "Ջնջել",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Ամրացնել անձնական էջում",
"status.pinned": "Pinned toot",
"status.reblog": "Տարածել",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} տարածել է",
"status.reply": "Պատասխանել",
"status.replyAll": "Պատասխանել թելին",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Coba lagi",
"column.blocks": "Pengguna diblokir",
"column.community": "Linimasa Lokal",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorit",
"column.follow_requests": "Permintaan mengikuti",
@ -100,6 +101,7 @@
"emoji_button.symbols": "Simbol",
"emoji_button.travel": "Tempat Wisata",
"empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.hashtag": "Tidak ada apapun dalam hashtag ini.",
"empty_column.home": "Linimasa anda kosong! Kunjungi {public} atau gunakan pencarian untuk memulai dan bertemu pengguna lain.",
"empty_column.home.public_timeline": "linimasa publik",
@ -154,6 +156,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.blocks": "Pengguna diblokir",
"navigation_bar.community_timeline": "Linimasa lokal",
"navigation_bar.direct": "Direct messages",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Ubah profil",
"navigation_bar.favourites": "Favorit",
@ -238,6 +241,7 @@
"search_results.total": "{count, number} {count, plural, one {hasil} other {hasil}}",
"standalone.public_title": "A look inside...",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Hapus",
"status.direct": "Direct message @{name}",
@ -253,6 +257,7 @@
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.reblog": "Boost",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "di-boost {name}",
"status.reply": "Balas",
"status.replyAll": "Balas ke semua",

View File

@ -40,6 +40,7 @@
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blokusita uzeri",
"column.community": "Lokala tempolineo",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favorati",
"column.follow_requests": "Demandi di sequado",