mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-01-19 22:22:53 -05:00
Merge commit '8a498f4e65ecf27cc2c992d02b47f890dafef20b' into glitch-soc/merge-upstream
This commit is contained in:
commit
3f61981f5d
@ -1,152 +0,0 @@
|
|||||||
import { List as ImmutableList } from 'immutable';
|
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
|
||||||
|
|
||||||
import api from '../api';
|
|
||||||
import { compareId } from '../compare_id';
|
|
||||||
|
|
||||||
export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST';
|
|
||||||
export const MARKERS_FETCH_SUCCESS = 'MARKERS_FETCH_SUCCESS';
|
|
||||||
export const MARKERS_FETCH_FAIL = 'MARKERS_FETCH_FAIL';
|
|
||||||
export const MARKERS_SUBMIT_SUCCESS = 'MARKERS_SUBMIT_SUCCESS';
|
|
||||||
|
|
||||||
export const synchronouslySubmitMarkers = () => (dispatch, getState) => {
|
|
||||||
const accessToken = getState().getIn(['meta', 'access_token'], '');
|
|
||||||
const params = _buildParams(getState());
|
|
||||||
|
|
||||||
if (Object.keys(params).length === 0 || accessToken === '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Fetch API allows us to perform requests that will be carried out
|
|
||||||
// after the page closes. But that only works if the `keepalive` attribute
|
|
||||||
// is supported.
|
|
||||||
if (window.fetch && 'keepalive' in new Request('')) {
|
|
||||||
fetch('/api/v1/markers', {
|
|
||||||
keepalive: true,
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${accessToken}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify(params),
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else if (navigator && navigator.sendBeacon) {
|
|
||||||
// Failing that, we can use sendBeacon, but we have to encode the data as
|
|
||||||
// FormData for DoorKeeper to recognize the token.
|
|
||||||
const formData = new FormData();
|
|
||||||
|
|
||||||
formData.append('bearer_token', accessToken);
|
|
||||||
|
|
||||||
for (const [id, value] of Object.entries(params)) {
|
|
||||||
formData.append(`${id}[last_read_id]`, value.last_read_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (navigator.sendBeacon('/api/v1/markers', formData)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If neither Fetch nor sendBeacon worked, try to perform a synchronous
|
|
||||||
// request.
|
|
||||||
try {
|
|
||||||
const client = new XMLHttpRequest();
|
|
||||||
|
|
||||||
client.open('POST', '/api/v1/markers', false);
|
|
||||||
client.setRequestHeader('Content-Type', 'application/json');
|
|
||||||
client.setRequestHeader('Authorization', `Bearer ${accessToken}`);
|
|
||||||
client.send(JSON.stringify(params));
|
|
||||||
} catch (e) {
|
|
||||||
// Do not make the BeforeUnload handler error out
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _buildParams = (state) => {
|
|
||||||
const params = {};
|
|
||||||
|
|
||||||
const lastHomeId = state.getIn(['timelines', 'home', 'items'], ImmutableList()).find(item => item !== null);
|
|
||||||
const lastNotificationId = state.getIn(['notifications', 'lastReadId']);
|
|
||||||
|
|
||||||
if (lastHomeId && compareId(lastHomeId, state.getIn(['markers', 'home'])) > 0) {
|
|
||||||
params.home = {
|
|
||||||
last_read_id: lastHomeId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastNotificationId && compareId(lastNotificationId, state.getIn(['markers', 'notifications'])) > 0) {
|
|
||||||
params.notifications = {
|
|
||||||
last_read_id: lastNotificationId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return params;
|
|
||||||
};
|
|
||||||
|
|
||||||
const debouncedSubmitMarkers = debounce((dispatch, getState) => {
|
|
||||||
const accessToken = getState().getIn(['meta', 'access_token'], '');
|
|
||||||
const params = _buildParams(getState());
|
|
||||||
|
|
||||||
if (Object.keys(params).length === 0 || accessToken === '') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
api(getState).post('/api/v1/markers', params).then(() => {
|
|
||||||
dispatch(submitMarkersSuccess(params));
|
|
||||||
}).catch(() => {});
|
|
||||||
}, 300000, { leading: true, trailing: true });
|
|
||||||
|
|
||||||
export function submitMarkersSuccess({ home, notifications }) {
|
|
||||||
return {
|
|
||||||
type: MARKERS_SUBMIT_SUCCESS,
|
|
||||||
home: (home || {}).last_read_id,
|
|
||||||
notifications: (notifications || {}).last_read_id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function submitMarkers(params = {}) {
|
|
||||||
const result = (dispatch, getState) => debouncedSubmitMarkers(dispatch, getState);
|
|
||||||
|
|
||||||
if (params.immediate === true) {
|
|
||||||
debouncedSubmitMarkers.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fetchMarkers = () => (dispatch, getState) => {
|
|
||||||
const params = { timeline: ['notifications'] };
|
|
||||||
|
|
||||||
dispatch(fetchMarkersRequest());
|
|
||||||
|
|
||||||
api(getState).get('/api/v1/markers', { params }).then(response => {
|
|
||||||
dispatch(fetchMarkersSuccess(response.data));
|
|
||||||
}).catch(error => {
|
|
||||||
dispatch(fetchMarkersFail(error));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export function fetchMarkersRequest() {
|
|
||||||
return {
|
|
||||||
type: MARKERS_FETCH_REQUEST,
|
|
||||||
skipLoading: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchMarkersSuccess(markers) {
|
|
||||||
return {
|
|
||||||
type: MARKERS_FETCH_SUCCESS,
|
|
||||||
markers,
|
|
||||||
skipLoading: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchMarkersFail(error) {
|
|
||||||
return {
|
|
||||||
type: MARKERS_FETCH_FAIL,
|
|
||||||
error,
|
|
||||||
skipLoading: true,
|
|
||||||
skipAlert: true,
|
|
||||||
};
|
|
||||||
}
|
|
165
app/javascript/mastodon/actions/markers.ts
Normal file
165
app/javascript/mastodon/actions/markers.ts
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import { List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
import type { MarkerJSON } from 'mastodon/api_types/markers';
|
||||||
|
import type { RootState } from 'mastodon/store';
|
||||||
|
import { createAppAsyncThunk } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
|
import api, { authorizationTokenFromState } from '../api';
|
||||||
|
import { compareId } from '../compare_id';
|
||||||
|
|
||||||
|
export const synchronouslySubmitMarkers = createAppAsyncThunk(
|
||||||
|
'markers/submit',
|
||||||
|
async (_args, { getState }) => {
|
||||||
|
const accessToken = authorizationTokenFromState(getState);
|
||||||
|
const params = buildPostMarkersParams(getState());
|
||||||
|
|
||||||
|
if (Object.keys(params).length === 0 || !accessToken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Fetch API allows us to perform requests that will be carried out
|
||||||
|
// after the page closes. But that only works if the `keepalive` attribute
|
||||||
|
// is supported.
|
||||||
|
if ('fetch' in window && 'keepalive' in new Request('')) {
|
||||||
|
await fetch('/api/v1/markers', {
|
||||||
|
keepalive: true,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
} else if ('navigator' && 'sendBeacon' in navigator) {
|
||||||
|
// Failing that, we can use sendBeacon, but we have to encode the data as
|
||||||
|
// FormData for DoorKeeper to recognize the token.
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('bearer_token', accessToken);
|
||||||
|
|
||||||
|
for (const [id, value] of Object.entries(params)) {
|
||||||
|
if (value.last_read_id)
|
||||||
|
formData.append(`${id}[last_read_id]`, value.last_read_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigator.sendBeacon('/api/v1/markers', formData)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If neither Fetch nor sendBeacon worked, try to perform a synchronous
|
||||||
|
// request.
|
||||||
|
try {
|
||||||
|
const client = new XMLHttpRequest();
|
||||||
|
|
||||||
|
client.open('POST', '/api/v1/markers', false);
|
||||||
|
client.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
client.setRequestHeader('Authorization', `Bearer ${accessToken}`);
|
||||||
|
client.send(JSON.stringify(params));
|
||||||
|
} catch (e) {
|
||||||
|
// Do not make the BeforeUnload handler error out
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
interface MarkerParam {
|
||||||
|
last_read_id?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastHomeId(state: RootState): string | undefined {
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
||||||
|
return (
|
||||||
|
state
|
||||||
|
// @ts-expect-error state.timelines is not yet typed
|
||||||
|
.getIn(['timelines', 'home', 'items'], ImmutableList())
|
||||||
|
// @ts-expect-error state.timelines is not yet typed
|
||||||
|
.find((item) => item !== null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastNotificationId(state: RootState): string | undefined {
|
||||||
|
// @ts-expect-error state.notifications is not yet typed
|
||||||
|
return state.getIn(['notifications', 'lastReadId']);
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildPostMarkersParams = (state: RootState) => {
|
||||||
|
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
|
||||||
|
|
||||||
|
const lastHomeId = getLastHomeId(state);
|
||||||
|
const lastNotificationId = getLastNotificationId(state);
|
||||||
|
|
||||||
|
if (lastHomeId && compareId(lastHomeId, state.markers.home) > 0) {
|
||||||
|
params.home = {
|
||||||
|
last_read_id: lastHomeId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
lastNotificationId &&
|
||||||
|
compareId(lastNotificationId, state.markers.notifications) > 0
|
||||||
|
) {
|
||||||
|
params.notifications = {
|
||||||
|
last_read_id: lastNotificationId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const submitMarkersAction = createAppAsyncThunk<{
|
||||||
|
home: string | undefined;
|
||||||
|
notifications: string | undefined;
|
||||||
|
}>('markers/submitAction', async (_args, { getState }) => {
|
||||||
|
const accessToken = authorizationTokenFromState(getState);
|
||||||
|
const params = buildPostMarkersParams(getState());
|
||||||
|
|
||||||
|
if (Object.keys(params).length === 0 || accessToken === '') {
|
||||||
|
return { home: undefined, notifications: undefined };
|
||||||
|
}
|
||||||
|
|
||||||
|
await api(getState).post<MarkerJSON>('/api/v1/markers', params);
|
||||||
|
|
||||||
|
return {
|
||||||
|
home: params.home?.last_read_id,
|
||||||
|
notifications: params.notifications?.last_read_id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const debouncedSubmitMarkers = debounce(
|
||||||
|
(dispatch) => {
|
||||||
|
dispatch(submitMarkersAction());
|
||||||
|
},
|
||||||
|
300000,
|
||||||
|
{
|
||||||
|
leading: true,
|
||||||
|
trailing: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const submitMarkers = createAppAsyncThunk(
|
||||||
|
'markers/submit',
|
||||||
|
(params: { immediate?: boolean }, { dispatch }) => {
|
||||||
|
debouncedSubmitMarkers(dispatch);
|
||||||
|
|
||||||
|
if (params.immediate) {
|
||||||
|
debouncedSubmitMarkers.flush();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchMarkers = createAppAsyncThunk(
|
||||||
|
'markers/fetch',
|
||||||
|
async (_args, { getState }) => {
|
||||||
|
const response = await api(getState).get<Record<string, MarkerJSON>>(
|
||||||
|
`/api/v1/markers`,
|
||||||
|
{ params: { timeline: ['notifications'] } },
|
||||||
|
);
|
||||||
|
|
||||||
|
return { markers: response.data };
|
||||||
|
},
|
||||||
|
);
|
@ -1,46 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
export const PICTURE_IN_PICTURE_DEPLOY = 'PICTURE_IN_PICTURE_DEPLOY';
|
|
||||||
export const PICTURE_IN_PICTURE_REMOVE = 'PICTURE_IN_PICTURE_REMOVE';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef MediaProps
|
|
||||||
* @property {string} src
|
|
||||||
* @property {boolean} muted
|
|
||||||
* @property {number} volume
|
|
||||||
* @property {number} currentTime
|
|
||||||
* @property {string} poster
|
|
||||||
* @property {string} backgroundColor
|
|
||||||
* @property {string} foregroundColor
|
|
||||||
* @property {string} accentColor
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} statusId
|
|
||||||
* @param {string} accountId
|
|
||||||
* @param {string} playerType
|
|
||||||
* @param {MediaProps} props
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
export const deployPictureInPicture = (statusId, accountId, playerType, props) => {
|
|
||||||
// @ts-expect-error
|
|
||||||
return (dispatch, getState) => {
|
|
||||||
// Do not open a player for a toot that does not exist
|
|
||||||
if (getState().hasIn(['statuses', statusId])) {
|
|
||||||
dispatch({
|
|
||||||
type: PICTURE_IN_PICTURE_DEPLOY,
|
|
||||||
statusId,
|
|
||||||
accountId,
|
|
||||||
playerType,
|
|
||||||
props,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
export const removePictureInPicture = () => ({
|
|
||||||
type: PICTURE_IN_PICTURE_REMOVE,
|
|
||||||
});
|
|
31
app/javascript/mastodon/actions/picture_in_picture.ts
Normal file
31
app/javascript/mastodon/actions/picture_in_picture.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import type { PIPMediaProps } from 'mastodon/reducers/picture_in_picture';
|
||||||
|
import { createAppAsyncThunk } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
|
interface DeployParams {
|
||||||
|
statusId: string;
|
||||||
|
accountId: string;
|
||||||
|
playerType: 'audio' | 'video';
|
||||||
|
props: PIPMediaProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const removePictureInPicture = createAction('pip/remove');
|
||||||
|
|
||||||
|
export const deployPictureInPictureAction =
|
||||||
|
createAction<DeployParams>('pip/deploy');
|
||||||
|
|
||||||
|
export const deployPictureInPicture = createAppAsyncThunk(
|
||||||
|
'pip/deploy',
|
||||||
|
(args: DeployParams, { dispatch, getState }) => {
|
||||||
|
const { statusId } = args;
|
||||||
|
|
||||||
|
// Do not open a player for a toot that does not exist
|
||||||
|
|
||||||
|
// @ts-expect-error state.statuses is not yet typed
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||||
|
if (getState().hasIn(['statuses', statusId])) {
|
||||||
|
dispatch(deployPictureInPictureAction(args));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
@ -29,9 +29,14 @@ const setCSRFHeader = () => {
|
|||||||
|
|
||||||
void ready(setCSRFHeader);
|
void ready(setCSRFHeader);
|
||||||
|
|
||||||
|
export const authorizationTokenFromState = (getState?: GetState) => {
|
||||||
|
return (
|
||||||
|
getState && (getState().meta.get('access_token', '') as string | false)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const authorizationHeaderFromState = (getState?: GetState) => {
|
const authorizationHeaderFromState = (getState?: GetState) => {
|
||||||
const accessToken =
|
const accessToken = authorizationTokenFromState(getState);
|
||||||
getState && (getState().meta.get('access_token', '') as string);
|
|
||||||
|
|
||||||
if (!accessToken) {
|
if (!accessToken) {
|
||||||
return {};
|
return {};
|
||||||
|
7
app/javascript/mastodon/api_types/markers.ts
Normal file
7
app/javascript/mastodon/api_types/markers.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// See app/serializers/rest/account_serializer.rb
|
||||||
|
|
||||||
|
export interface MarkerJSON {
|
||||||
|
last_read_id: string;
|
||||||
|
version: string;
|
||||||
|
updated_at: string;
|
||||||
|
}
|
@ -1,26 +1,26 @@
|
|||||||
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
interface BaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
interface BaseProps
|
||||||
|
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
||||||
block?: boolean;
|
block?: boolean;
|
||||||
secondary?: boolean;
|
secondary?: boolean;
|
||||||
text?: JSX.Element;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PropsWithChildren extends BaseProps {
|
interface PropsChildren extends PropsWithChildren<BaseProps> {
|
||||||
text?: never;
|
text?: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PropsWithText extends BaseProps {
|
interface PropsWithText extends BaseProps {
|
||||||
text: JSX.Element;
|
text: JSX.Element | string;
|
||||||
children: never;
|
children?: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = PropsWithText | PropsWithChildren;
|
type Props = PropsWithText | PropsChildren;
|
||||||
|
|
||||||
export const Button: React.FC<Props> = ({
|
export const Button: React.FC<Props> = ({
|
||||||
text,
|
|
||||||
type = 'button',
|
type = 'button',
|
||||||
onClick,
|
onClick,
|
||||||
disabled,
|
disabled,
|
||||||
@ -28,6 +28,7 @@ export const Button: React.FC<Props> = ({
|
|||||||
secondary,
|
secondary,
|
||||||
className,
|
className,
|
||||||
title,
|
title,
|
||||||
|
text,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -191,7 +191,7 @@ const timeRemainingString = (
|
|||||||
interface Props {
|
interface Props {
|
||||||
intl: IntlShape;
|
intl: IntlShape;
|
||||||
timestamp: string;
|
timestamp: string;
|
||||||
year: number;
|
year?: number;
|
||||||
futureDate?: boolean;
|
futureDate?: boolean;
|
||||||
short?: boolean;
|
short?: boolean;
|
||||||
}
|
}
|
||||||
@ -203,11 +203,6 @@ class RelativeTimestamp extends Component<Props, States> {
|
|||||||
now: Date.now(),
|
now: Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
year: new Date().getFullYear(),
|
|
||||||
short: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
_timer: number | undefined;
|
_timer: number | undefined;
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: Props, nextState: States) {
|
shouldComponentUpdate(nextProps: Props, nextState: States) {
|
||||||
@ -257,7 +252,13 @@ class RelativeTimestamp extends Component<Props, States> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { timestamp, intl, year, futureDate, short } = this.props;
|
const {
|
||||||
|
timestamp,
|
||||||
|
intl,
|
||||||
|
futureDate,
|
||||||
|
year = new Date().getFullYear(),
|
||||||
|
short = true,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const timeGiven = timestamp.includes('T');
|
const timeGiven = timestamp.includes('T');
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
|
@ -81,7 +81,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
relationship: ImmutablePropTypes.map,
|
relationship: ImmutablePropTypes.record,
|
||||||
onReply: PropTypes.func,
|
onReply: PropTypes.func,
|
||||||
onFavourite: PropTypes.func,
|
onFavourite: PropTypes.func,
|
||||||
onReblog: PropTypes.func,
|
onReblog: PropTypes.func,
|
||||||
|
@ -262,7 +262,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
deployPictureInPicture (status, type, mediaProps) {
|
deployPictureInPicture (status, type, mediaProps) {
|
||||||
dispatch(deployPictureInPicture(status.get('id'), status.getIn(['account', 'id']), type, mediaProps));
|
dispatch(deployPictureInPicture({statusId: status.get('id'), accountId: status.getIn(['account', 'id']), playerType: type, props: mediaProps}));
|
||||||
},
|
},
|
||||||
|
|
||||||
onInteractionModal (type, status) {
|
onInteractionModal (type, status) {
|
||||||
|
@ -82,7 +82,7 @@ class GettingStarted extends ImmutablePureComponent {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
myAccount: ImmutablePropTypes.map,
|
myAccount: ImmutablePropTypes.record,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
fetchFollowRequests: PropTypes.func.isRequired,
|
fetchFollowRequests: PropTypes.func.isRequired,
|
||||||
unreadFollowRequests: PropTypes.number,
|
unreadFollowRequests: PropTypes.number,
|
||||||
|
@ -210,4 +210,4 @@ class Footer extends ImmutablePureComponent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRouter(connect(makeMapStateToProps)(injectIntl(Footer)));
|
export default connect(makeMapStateToProps)(withRouter(injectIntl(Footer)));
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { defineMessages, injectIntl } from 'react-intl';
|
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
|
||||||
import { Avatar } from 'mastodon/components/avatar';
|
|
||||||
import { DisplayName } from 'mastodon/components/display_name';
|
|
||||||
import { IconButton } from 'mastodon/components/icon_button';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapStateToProps = (state, { accountId }) => ({
|
|
||||||
account: state.getIn(['accounts', accountId]),
|
|
||||||
});
|
|
||||||
|
|
||||||
class Header extends ImmutablePureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
accountId: PropTypes.string.isRequired,
|
|
||||||
statusId: PropTypes.string.isRequired,
|
|
||||||
account: ImmutablePropTypes.record.isRequired,
|
|
||||||
onClose: PropTypes.func.isRequired,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { account, statusId, onClose, intl } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='picture-in-picture__header'>
|
|
||||||
<Link to={`/@${account.get('acct')}/${statusId}`} className='picture-in-picture__header__account'>
|
|
||||||
<Avatar account={account} size={36} />
|
|
||||||
<DisplayName account={account} />
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<IconButton icon='times' iconComponent={CloseIcon} onClick={onClose} title={intl.formatMessage(messages.close)} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(Header));
|
|
@ -0,0 +1,46 @@
|
|||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
|
import { Avatar } from 'mastodon/components/avatar';
|
||||||
|
import { DisplayName } from 'mastodon/components/display_name';
|
||||||
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
accountId: string;
|
||||||
|
statusId: string;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Header: React.FC<Props> = ({ accountId, statusId, onClose }) => {
|
||||||
|
const account = useAppSelector((state) => state.accounts.get(accountId));
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
if (!account) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='picture-in-picture__header'>
|
||||||
|
<Link
|
||||||
|
to={`/@${account.get('acct')}/${statusId}`}
|
||||||
|
className='picture-in-picture__header__account'
|
||||||
|
>
|
||||||
|
<Avatar account={account} size={36} />
|
||||||
|
<DisplayName account={account} />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
icon='times'
|
||||||
|
iconComponent={CloseIcon}
|
||||||
|
onClick={onClose}
|
||||||
|
title={intl.formatMessage(messages.close)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -1,89 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Component } from 'react';
|
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { removePictureInPicture } from 'mastodon/actions/picture_in_picture';
|
|
||||||
import Audio from 'mastodon/features/audio';
|
|
||||||
import Video from 'mastodon/features/video';
|
|
||||||
|
|
||||||
import Footer from './components/footer';
|
|
||||||
import Header from './components/header';
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
...state.get('picture_in_picture'),
|
|
||||||
});
|
|
||||||
|
|
||||||
class PictureInPicture extends Component {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
statusId: PropTypes.string,
|
|
||||||
accountId: PropTypes.string,
|
|
||||||
type: PropTypes.string,
|
|
||||||
src: PropTypes.string,
|
|
||||||
muted: PropTypes.bool,
|
|
||||||
volume: PropTypes.number,
|
|
||||||
currentTime: PropTypes.number,
|
|
||||||
poster: PropTypes.string,
|
|
||||||
backgroundColor: PropTypes.string,
|
|
||||||
foregroundColor: PropTypes.string,
|
|
||||||
accentColor: PropTypes.string,
|
|
||||||
dispatch: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClose = () => {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch(removePictureInPicture());
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { type, src, currentTime, accountId, statusId } = this.props;
|
|
||||||
|
|
||||||
if (!currentTime) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let player;
|
|
||||||
|
|
||||||
if (type === 'video') {
|
|
||||||
player = (
|
|
||||||
<Video
|
|
||||||
src={src}
|
|
||||||
currentTime={this.props.currentTime}
|
|
||||||
volume={this.props.volume}
|
|
||||||
muted={this.props.muted}
|
|
||||||
autoPlay
|
|
||||||
inline
|
|
||||||
alwaysVisible
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else if (type === 'audio') {
|
|
||||||
player = (
|
|
||||||
<Audio
|
|
||||||
src={src}
|
|
||||||
currentTime={this.props.currentTime}
|
|
||||||
volume={this.props.volume}
|
|
||||||
muted={this.props.muted}
|
|
||||||
poster={this.props.poster}
|
|
||||||
backgroundColor={this.props.backgroundColor}
|
|
||||||
foregroundColor={this.props.foregroundColor}
|
|
||||||
accentColor={this.props.accentColor}
|
|
||||||
autoPlay
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='picture-in-picture'>
|
|
||||||
<Header accountId={accountId} statusId={statusId} onClose={this.handleClose} />
|
|
||||||
|
|
||||||
{player}
|
|
||||||
|
|
||||||
<Footer statusId={statusId} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(PictureInPicture);
|
|
@ -0,0 +1,79 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { removePictureInPicture } from 'mastodon/actions/picture_in_picture';
|
||||||
|
import Audio from 'mastodon/features/audio';
|
||||||
|
import Video from 'mastodon/features/video';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
|
import Footer from './components/footer';
|
||||||
|
import { Header } from './components/header';
|
||||||
|
|
||||||
|
export const PictureInPicture: React.FC = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
dispatch(removePictureInPicture());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const pipState = useAppSelector((s) => s.picture_in_picture);
|
||||||
|
|
||||||
|
if (pipState.type === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
type,
|
||||||
|
src,
|
||||||
|
currentTime,
|
||||||
|
accountId,
|
||||||
|
statusId,
|
||||||
|
volume,
|
||||||
|
muted,
|
||||||
|
poster,
|
||||||
|
backgroundColor,
|
||||||
|
foregroundColor,
|
||||||
|
accentColor,
|
||||||
|
} = pipState;
|
||||||
|
|
||||||
|
let player;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'video':
|
||||||
|
player = (
|
||||||
|
<Video
|
||||||
|
src={src}
|
||||||
|
currentTime={currentTime}
|
||||||
|
volume={volume}
|
||||||
|
muted={muted}
|
||||||
|
autoPlay
|
||||||
|
inline
|
||||||
|
alwaysVisible
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'audio':
|
||||||
|
player = (
|
||||||
|
<Audio
|
||||||
|
src={src}
|
||||||
|
currentTime={currentTime}
|
||||||
|
volume={volume}
|
||||||
|
muted={muted}
|
||||||
|
poster={poster}
|
||||||
|
backgroundColor={backgroundColor}
|
||||||
|
foregroundColor={foregroundColor}
|
||||||
|
accentColor={accentColor}
|
||||||
|
autoPlay
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='picture-in-picture'>
|
||||||
|
<Header accountId={accountId} statusId={statusId} onClose={handleClose} />
|
||||||
|
|
||||||
|
{player}
|
||||||
|
|
||||||
|
<Footer statusId={statusId} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -74,7 +74,7 @@ class ActionBar extends PureComponent {
|
|||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
relationship: ImmutablePropTypes.map,
|
relationship: ImmutablePropTypes.record,
|
||||||
onReply: PropTypes.func.isRequired,
|
onReply: PropTypes.func.isRequired,
|
||||||
onReblog: PropTypes.func.isRequired,
|
onReblog: PropTypes.func.isRequired,
|
||||||
onFavourite: PropTypes.func.isRequired,
|
onFavourite: PropTypes.func.isRequired,
|
||||||
|
@ -14,7 +14,7 @@ import { HotKeys } from 'react-hotkeys';
|
|||||||
import { focusApp, unfocusApp, changeLayout } from 'mastodon/actions/app';
|
import { focusApp, unfocusApp, changeLayout } from 'mastodon/actions/app';
|
||||||
import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'mastodon/actions/markers';
|
import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'mastodon/actions/markers';
|
||||||
import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
|
import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
|
||||||
import PictureInPicture from 'mastodon/features/picture_in_picture';
|
import { PictureInPicture } from 'mastodon/features/picture_in_picture';
|
||||||
import { layoutFromWindow } from 'mastodon/is_mobile';
|
import { layoutFromWindow } from 'mastodon/is_mobile';
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
|
@ -471,6 +471,8 @@
|
|||||||
"notification.own_poll": "Анкетата ви приключи",
|
"notification.own_poll": "Анкетата ви приключи",
|
||||||
"notification.poll": "Анкета, в която гласувахте, приключи",
|
"notification.poll": "Анкета, в която гласувахте, приключи",
|
||||||
"notification.reblog": "{name} подсили ваша публикация",
|
"notification.reblog": "{name} подсили ваша публикация",
|
||||||
|
"notification.relationships_severance_event": "Изгуби се връзката с {name}",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Научете повече",
|
||||||
"notification.status": "{name} току-що публикува",
|
"notification.status": "{name} току-що публикува",
|
||||||
"notification.update": "{name} промени публикация",
|
"notification.update": "{name} промени публикация",
|
||||||
"notification_requests.accept": "Приемам",
|
"notification_requests.accept": "Приемам",
|
||||||
|
@ -472,7 +472,7 @@
|
|||||||
"notification.own_poll": "La teva enquesta ha finalitzat",
|
"notification.own_poll": "La teva enquesta ha finalitzat",
|
||||||
"notification.poll": "Ha finalitzat una enquesta en què has votat",
|
"notification.poll": "Ha finalitzat una enquesta en què has votat",
|
||||||
"notification.reblog": "{name} t'ha impulsat",
|
"notification.reblog": "{name} t'ha impulsat",
|
||||||
"notification.relationships_severance_event": "Connexions perdudes amb {name}",
|
"notification.relationships_severance_event": "S'han perdut les connexions amb {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspès {target}; això vol dir que ja no en podreu rebre actualitzacions o interactuar-hi.",
|
"notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspès {target}; això vol dir que ja no en podreu rebre actualitzacions o interactuar-hi.",
|
||||||
"notification.relationships_severance_event.domain_block": "Un administrador de {from} ha blocat {target}, incloent-hi {followersCount} dels vostres seguidors i {followingCount, plural, one {# compte} other {# comptes}} que seguiu.",
|
"notification.relationships_severance_event.domain_block": "Un administrador de {from} ha blocat {target}, incloent-hi {followersCount} dels vostres seguidors i {followingCount, plural, one {# compte} other {# comptes}} que seguiu.",
|
||||||
"notification.relationships_severance_event.learn_more": "Per a saber-ne més",
|
"notification.relationships_severance_event.learn_more": "Per a saber-ne més",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||||
"filter_modal.title.status": "Filtrar una publicación",
|
"filter_modal.title.status": "Filtrar una publicación",
|
||||||
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
|
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, one {mención privada} other {menciones privadas}}",
|
||||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||||
"firehose.all": "Todas",
|
"firehose.all": "Todas",
|
||||||
"firehose.local": "Este servidor",
|
"firehose.local": "Este servidor",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||||
"filter_modal.title.status": "Filtrar una publicación",
|
"filter_modal.title.status": "Filtrar una publicación",
|
||||||
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
|
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, one {mención privada} other {menciones privadas}}",
|
||||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||||
"firehose.all": "Todas",
|
"firehose.all": "Todas",
|
||||||
"firehose.local": "Este servidor",
|
"firehose.local": "Este servidor",
|
||||||
|
@ -472,7 +472,11 @@
|
|||||||
"notification.own_poll": "Äänestyksesi on päättynyt",
|
"notification.own_poll": "Äänestyksesi on päättynyt",
|
||||||
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
|
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
|
||||||
"notification.reblog": "{name} tehosti julkaisuasi",
|
"notification.reblog": "{name} tehosti julkaisuasi",
|
||||||
|
"notification.relationships_severance_event": "Menetettiin yhteydet palvelimeen {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Palvelimen {from} ylläpitäjä on jäädyttänyt verkkotunnuksen {target}, minkä takia et voi enää vastaanottaa heidän päivityksiään tai olla vuorovaikutuksessa heidän kanssaan.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Palvelimen {from} ylläpitäjä on estänyt verkkotunnuksen {target}, mukaan lukien {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
|
||||||
"notification.relationships_severance_event.learn_more": "Lue lisää",
|
"notification.relationships_severance_event.learn_more": "Lue lisää",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Olet estänyt verkkotunnuksen {target}, mikä poisti {followersCount} seuraajistasi ja {followingCount, plural, one {# seuratuistasi} other {# seuratuistasi}}.",
|
||||||
"notification.status": "{name} julkaisi juuri",
|
"notification.status": "{name} julkaisi juuri",
|
||||||
"notification.update": "{name} muokkasi julkaisua",
|
"notification.update": "{name} muokkasi julkaisua",
|
||||||
"notification_requests.accept": "Hyväksy",
|
"notification_requests.accept": "Hyväksy",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||||
"filter_modal.title.status": "Filtrar unha publicación",
|
"filter_modal.title.status": "Filtrar unha publicación",
|
||||||
"filtered_notifications_banner.pending_requests": "Notificacións de {count, plural, =0 {ninguén} one {unha persoa} other {# persoas}} que poderías coñecer",
|
"filtered_notifications_banner.pending_requests": "Notificacións de {count, plural, =0 {ninguén} one {unha persoa} other {# persoas}} que poderías coñecer",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, one {mención privada} other {mencións privadas}}",
|
||||||
"filtered_notifications_banner.title": "Notificacións filtradas",
|
"filtered_notifications_banner.title": "Notificacións filtradas",
|
||||||
"firehose.all": "Todo",
|
"firehose.all": "Todo",
|
||||||
"firehose.local": "Este servidor",
|
"firehose.local": "Este servidor",
|
||||||
@ -471,6 +472,11 @@
|
|||||||
"notification.own_poll": "A túa enquisa rematou",
|
"notification.own_poll": "A túa enquisa rematou",
|
||||||
"notification.poll": "Rematou a enquisa na que votaches",
|
"notification.poll": "Rematou a enquisa na que votaches",
|
||||||
"notification.reblog": "{name} compartiu a túa publicación",
|
"notification.reblog": "{name} compartiu a túa publicación",
|
||||||
|
"notification.relationships_severance_event": "Perdeuse a conexión con {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "A administración de {from} suspendeu a {target}, o que significa que xa non vas recibir actualizacións de esa conta ou interactuar con ela.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "A administración de {from} bloqueou a {target}, que inclúe a {followersCount} das túas seguidoras e a {followingCount, plural, one {# conta} other {# contas}} que sigues.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Saber máis",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Bloqueaches a {target}, eliminando a {followersCount} das túas seguidoras e a {followingCount, plural, one {# conta} other {# contas}} que sigues.",
|
||||||
"notification.status": "{name} publicou",
|
"notification.status": "{name} publicou",
|
||||||
"notification.update": "{name} editou unha publicación",
|
"notification.update": "{name} editou unha publicación",
|
||||||
"notification_requests.accept": "Aceptar",
|
"notification_requests.accept": "Aceptar",
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"column.domain_blocks": "Letiltott domainek",
|
"column.domain_blocks": "Letiltott domainek",
|
||||||
"column.favourites": "Kedvencek",
|
"column.favourites": "Kedvencek",
|
||||||
"column.firehose": "Hírfolyamok",
|
"column.firehose": "Hírfolyamok",
|
||||||
"column.follow_requests": "Követési kérelmek",
|
"column.follow_requests": "Követési kérések",
|
||||||
"column.home": "Kezdőlap",
|
"column.home": "Kezdőlap",
|
||||||
"column.lists": "Listák",
|
"column.lists": "Listák",
|
||||||
"column.mutes": "Némított felhasználók",
|
"column.mutes": "Némított felhasználók",
|
||||||
@ -133,8 +133,8 @@
|
|||||||
"column.public": "Föderációs idővonal",
|
"column.public": "Föderációs idővonal",
|
||||||
"column_back_button.label": "Vissza",
|
"column_back_button.label": "Vissza",
|
||||||
"column_header.hide_settings": "Beállítások elrejtése",
|
"column_header.hide_settings": "Beállítások elrejtése",
|
||||||
"column_header.moveLeft_settings": "Oszlop elmozdítása balra",
|
"column_header.moveLeft_settings": "Oszlop áthelyezése balra",
|
||||||
"column_header.moveRight_settings": "Oszlop elmozdítása jobbra",
|
"column_header.moveRight_settings": "Oszlop áthelyezése jobbra",
|
||||||
"column_header.pin": "Kitűzés",
|
"column_header.pin": "Kitűzés",
|
||||||
"column_header.show_settings": "Beállítások megjelenítése",
|
"column_header.show_settings": "Beállítások megjelenítése",
|
||||||
"column_header.unpin": "Kitűzés eltávolítása",
|
"column_header.unpin": "Kitűzés eltávolítása",
|
||||||
@ -143,7 +143,7 @@
|
|||||||
"community.column_settings.media_only": "Csak média",
|
"community.column_settings.media_only": "Csak média",
|
||||||
"community.column_settings.remote_only": "Csak távoli",
|
"community.column_settings.remote_only": "Csak távoli",
|
||||||
"compose.language.change": "Nyelv megváltoztatása",
|
"compose.language.change": "Nyelv megváltoztatása",
|
||||||
"compose.language.search": "Nyelv keresése...",
|
"compose.language.search": "Nyelvek keresése…",
|
||||||
"compose.published.body": "A bejegyzés publikálásra került.",
|
"compose.published.body": "A bejegyzés publikálásra került.",
|
||||||
"compose.published.open": "Megnyitás",
|
"compose.published.open": "Megnyitás",
|
||||||
"compose.saved.body": "A bejegyzés mentve.",
|
"compose.saved.body": "A bejegyzés mentve.",
|
||||||
@ -473,8 +473,8 @@
|
|||||||
"notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
|
"notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
|
||||||
"notification.reblog": "{name} megtolta a bejegyzésedet",
|
"notification.reblog": "{name} megtolta a bejegyzésedet",
|
||||||
"notification.relationships_severance_event": "Elvesztek a kapcsolatok vele: {name}",
|
"notification.relationships_severance_event": "Elvesztek a kapcsolatok vele: {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "Egy admin a {from} kiszolgálóról felfüggesztette {target} fiókot, ami azt jelenti, hogy mostantól nem tudsz vele interaktálni vagy tőle értesítéseket kapni.",
|
"notification.relationships_severance_event.account_suspension": "Egy admin a(z) {from} kiszolgálóról felfüggesztette {target} fiókját, ami azt jelenti, hogy mostantól nem fogsz róla értesítést kapni, és nem fogsz tudni vele kapcsolatba lépni.",
|
||||||
"notification.relationships_severance_event.domain_block": "Egy admin a {from} kiszolgálón letiltotta {target} domaint, beleértve {followersCount} követődet és {followingCount, plural, one {#} other {#}} általad követett személyt.",
|
"notification.relationships_severance_event.domain_block": "Egy admin a(z) {from} kiszolgálón letiltotta {target} domaint, beleértve {followersCount} követőt és {followingCount, plural, one {#} other {#}} követett fiókot.",
|
||||||
"notification.relationships_severance_event.learn_more": "További információk",
|
"notification.relationships_severance_event.learn_more": "További információk",
|
||||||
"notification.relationships_severance_event.user_domain_block": "Letiltottad a(z) {target} domaint, ezzel eltávolítva {followersCount} követőt és {followingCount, plural, one {#} other {#}} követett fiókot.",
|
"notification.relationships_severance_event.user_domain_block": "Letiltottad a(z) {target} domaint, ezzel eltávolítva {followersCount} követőt és {followingCount, plural, one {#} other {#}} követett fiókot.",
|
||||||
"notification.status": "{name} bejegyzést tett közzé",
|
"notification.status": "{name} bejegyzést tett közzé",
|
||||||
@ -492,7 +492,7 @@
|
|||||||
"notifications.column_settings.filter_bar.advanced": "Minden kategória megjelenítése",
|
"notifications.column_settings.filter_bar.advanced": "Minden kategória megjelenítése",
|
||||||
"notifications.column_settings.filter_bar.category": "Gyorsszűrő sáv",
|
"notifications.column_settings.filter_bar.category": "Gyorsszűrő sáv",
|
||||||
"notifications.column_settings.follow": "Új követők:",
|
"notifications.column_settings.follow": "Új követők:",
|
||||||
"notifications.column_settings.follow_request": "Új követési kérelmek:",
|
"notifications.column_settings.follow_request": "Új követési kérések:",
|
||||||
"notifications.column_settings.mention": "Megemlítések:",
|
"notifications.column_settings.mention": "Megemlítések:",
|
||||||
"notifications.column_settings.poll": "Szavazási eredmények:",
|
"notifications.column_settings.poll": "Szavazási eredmények:",
|
||||||
"notifications.column_settings.push": "Leküldéses értesítések",
|
"notifications.column_settings.push": "Leküldéses értesítések",
|
||||||
@ -552,14 +552,14 @@
|
|||||||
"onboarding.share.next_steps": "Lehetséges következő lépések:",
|
"onboarding.share.next_steps": "Lehetséges következő lépések:",
|
||||||
"onboarding.share.title": "Profil megosztása",
|
"onboarding.share.title": "Profil megosztása",
|
||||||
"onboarding.start.lead": "Az új Mastodon-fiók használatra kész. Így hozhatod ki belőle a legtöbbet:",
|
"onboarding.start.lead": "Az új Mastodon-fiók használatra kész. Így hozhatod ki belőle a legtöbbet:",
|
||||||
"onboarding.start.skip": "Szeretnél előreugrani?",
|
"onboarding.start.skip": "Nincs szükséged segítségre a kezdéshez?",
|
||||||
"onboarding.start.title": "Ez sikerült!",
|
"onboarding.start.title": "Ez sikerült!",
|
||||||
"onboarding.steps.follow_people.body": "A Mastodon az érdekes emberek követéséről szól.",
|
"onboarding.steps.follow_people.body": "A Mastodon az érdekes emberek követéséről szól.",
|
||||||
"onboarding.steps.follow_people.title": "{count, plural, one {egy ember} other {# ember}} követése",
|
"onboarding.steps.follow_people.title": "Szabd személyre a kezdőlapodat",
|
||||||
"onboarding.steps.publish_status.body": "Üdvözöljük a világot.",
|
"onboarding.steps.publish_status.body": "Köszöntsd a világot szöveggel, fotókkal, videókkal vagy szavazásokkal {emoji}",
|
||||||
"onboarding.steps.publish_status.title": "Az első bejegyzés létrehozása",
|
"onboarding.steps.publish_status.title": "Az első bejegyzés létrehozása",
|
||||||
"onboarding.steps.setup_profile.body": "Mások nagyobb valószínűséggel lépnek kapcsolatba veled egy kitöltött profil esetén.",
|
"onboarding.steps.setup_profile.body": "Növeld az interakciók számát a profilod részletesebb kitöltésével.",
|
||||||
"onboarding.steps.setup_profile.title": "Profilod testreszabása",
|
"onboarding.steps.setup_profile.title": "Szabd személyre a profilodat",
|
||||||
"onboarding.steps.share_profile.body": "Tudasd az ismerőseiddel, hogyan találhatnak meg a Mastodonon",
|
"onboarding.steps.share_profile.body": "Tudasd az ismerőseiddel, hogyan találhatnak meg a Mastodonon",
|
||||||
"onboarding.steps.share_profile.title": "Oszd meg a Mastodon profilodat",
|
"onboarding.steps.share_profile.title": "Oszd meg a Mastodon profilodat",
|
||||||
"onboarding.tips.2fa": "<strong>Tudtad?</strong> A fiókod biztonságossá teheted, ha a fiók beállításaiban beállítod a kétlépcsős hitelesítést. Bármilyen választott TOTP alkalmazással működik, nincs szükség telefonszámra!",
|
"onboarding.tips.2fa": "<strong>Tudtad?</strong> A fiókod biztonságossá teheted, ha a fiók beállításaiban beállítod a kétlépcsős hitelesítést. Bármilyen választott TOTP alkalmazással működik, nincs szükség telefonszámra!",
|
||||||
@ -787,9 +787,9 @@
|
|||||||
"upload_modal.hint": "Kattints vagy húzd a kört az előnézetben arra a fókuszpontra, mely minden bélyegképen látható kell, hogy legyen.",
|
"upload_modal.hint": "Kattints vagy húzd a kört az előnézetben arra a fókuszpontra, mely minden bélyegképen látható kell, hogy legyen.",
|
||||||
"upload_modal.preparing_ocr": "OCR előkészítése…",
|
"upload_modal.preparing_ocr": "OCR előkészítése…",
|
||||||
"upload_modal.preview_label": "Előnézet ({ratio})",
|
"upload_modal.preview_label": "Előnézet ({ratio})",
|
||||||
"upload_progress.label": "Feltöltés...",
|
"upload_progress.label": "Feltöltés…",
|
||||||
"upload_progress.processing": "Feldolgozás…",
|
"upload_progress.processing": "Feldolgozás…",
|
||||||
"username.taken": "Ez a felhasználónév foglalt. Válassz másikat",
|
"username.taken": "Ez a felhasználónév foglalt. Válassz másikat.",
|
||||||
"video.close": "Videó bezárása",
|
"video.close": "Videó bezárása",
|
||||||
"video.download": "Fájl letöltése",
|
"video.download": "Fájl letöltése",
|
||||||
"video.exit_fullscreen": "Kilépés teljes képernyőből",
|
"video.exit_fullscreen": "Kilépés teljes képernyőből",
|
||||||
@ -799,5 +799,5 @@
|
|||||||
"video.mute": "Hang némítása",
|
"video.mute": "Hang némítása",
|
||||||
"video.pause": "Szünet",
|
"video.pause": "Szünet",
|
||||||
"video.play": "Lejátszás",
|
"video.play": "Lejátszás",
|
||||||
"video.unmute": "Hang némításának vége"
|
"video.unmute": "Hang némításának feloldása"
|
||||||
}
|
}
|
||||||
|
@ -473,7 +473,10 @@
|
|||||||
"notification.poll": "Könnun sem þú tókst þátt í er lokið",
|
"notification.poll": "Könnun sem þú tókst þátt í er lokið",
|
||||||
"notification.reblog": "{name} endurbirti færsluna þína",
|
"notification.reblog": "{name} endurbirti færsluna þína",
|
||||||
"notification.relationships_severance_event": "Missti tengingar við {name}",
|
"notification.relationships_severance_event": "Missti tengingar við {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Stjórnandi á {from} hefur fryst {target}, sem þýðir að þú færð ekki lengur skilaboð frá viðkomandi né átt í samskiptum við viðkomandi.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Stjórnandi á {from} hefur lokað á {target} og þar með {followersCount} fylgjendur þína auk {followingCount, plural, one {# aðgangs} other {# aðganga}} sem þú fylgist með.",
|
||||||
"notification.relationships_severance_event.learn_more": "Kanna nánar",
|
"notification.relationships_severance_event.learn_more": "Kanna nánar",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Þú hefur lokað á {target} og þar með fjarlægt {followersCount} fylgjendur þína auk {followingCount, plural, one {# aðgangs} other {# aðganga}} sem þú fylgist með.",
|
||||||
"notification.status": "{name} sendi inn rétt í þessu",
|
"notification.status": "{name} sendi inn rétt í þessu",
|
||||||
"notification.update": "{name} breytti færslu",
|
"notification.update": "{name} breytti færslu",
|
||||||
"notification_requests.accept": "Samþykkja",
|
"notification_requests.accept": "Samþykkja",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtra questo post",
|
"filter_modal.select_filter.title": "Filtra questo post",
|
||||||
"filter_modal.title.status": "Filtra un post",
|
"filter_modal.title.status": "Filtra un post",
|
||||||
"filtered_notifications_banner.pending_requests": "Notifiche da {count, plural, =0 {nessuno} one {una persona} other {# persone}} che potresti conoscere",
|
"filtered_notifications_banner.pending_requests": "Notifiche da {count, plural, =0 {nessuno} one {una persona} other {# persone}} che potresti conoscere",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural,one {menzione privata} other {menzioni private}}",
|
||||||
"filtered_notifications_banner.title": "Notifiche filtrate",
|
"filtered_notifications_banner.title": "Notifiche filtrate",
|
||||||
"firehose.all": "Tutto",
|
"firehose.all": "Tutto",
|
||||||
"firehose.local": "Questo server",
|
"firehose.local": "Questo server",
|
||||||
@ -473,7 +474,9 @@
|
|||||||
"notification.reblog": "{name} ha rebloggato il tuo post",
|
"notification.reblog": "{name} ha rebloggato il tuo post",
|
||||||
"notification.relationships_severance_event": "Connessioni perse con {name}",
|
"notification.relationships_severance_event": "Connessioni perse con {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "Un amministratore da {from} ha sospeso {target}, il che significa che non puoi più ricevere aggiornamenti da loro o interagire con loro.",
|
"notification.relationships_severance_event.account_suspension": "Un amministratore da {from} ha sospeso {target}, il che significa che non puoi più ricevere aggiornamenti da loro o interagire con loro.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Un amministratore da {from} ha bloccato {target}, inclusi {followersCount} dei tuoi seguaci e {followingCount, plural, one {# account} other {# account}} che segui.",
|
||||||
"notification.relationships_severance_event.learn_more": "Scopri di più",
|
"notification.relationships_severance_event.learn_more": "Scopri di più",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Tu hai bloccato {target}, rimuovendo {followersCount} dei tuoi seguaci e {followingCount, plural, one {# account} other {# account}} che segui.",
|
||||||
"notification.status": "{name} ha appena pubblicato un post",
|
"notification.status": "{name} ha appena pubblicato un post",
|
||||||
"notification.update": "{name} ha modificato un post",
|
"notification.update": "{name} ha modificato un post",
|
||||||
"notification_requests.accept": "Accetta",
|
"notification_requests.accept": "Accetta",
|
||||||
|
@ -177,6 +177,7 @@
|
|||||||
"confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?",
|
"confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?",
|
||||||
"confirmations.discard_edit_media.confirm": "破棄",
|
"confirmations.discard_edit_media.confirm": "破棄",
|
||||||
"confirmations.discard_edit_media.message": "メディアの説明またはプレビューに保存されていない変更があります。それでも破棄しますか?",
|
"confirmations.discard_edit_media.message": "メディアの説明またはプレビューに保存されていない変更があります。それでも破棄しますか?",
|
||||||
|
"confirmations.domain_block.confirm": "サーバーをブロック",
|
||||||
"confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。",
|
"confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。",
|
||||||
"confirmations.edit.confirm": "編集",
|
"confirmations.edit.confirm": "編集",
|
||||||
"confirmations.edit.message": "今編集すると現在作成中のメッセージが上書きされます。本当に実行しますか?",
|
"confirmations.edit.message": "今編集すると現在作成中のメッセージが上書きされます。本当に実行しますか?",
|
||||||
|
@ -221,6 +221,7 @@
|
|||||||
"filter_modal.select_filter.prompt_new": "Taggayt tamaynutt : {name}",
|
"filter_modal.select_filter.prompt_new": "Taggayt tamaynutt : {name}",
|
||||||
"filter_modal.select_filter.search": "Nadi neɣ snulfu-d",
|
"filter_modal.select_filter.search": "Nadi neɣ snulfu-d",
|
||||||
"filter_modal.select_filter.title": "Sizdeg tassufeɣt-a",
|
"filter_modal.select_filter.title": "Sizdeg tassufeɣt-a",
|
||||||
|
"filter_modal.title.status": "Sizdeg tassufeɣt",
|
||||||
"firehose.all": "Akk",
|
"firehose.all": "Akk",
|
||||||
"firehose.local": "Deg uqeddac-ayi",
|
"firehose.local": "Deg uqeddac-ayi",
|
||||||
"firehose.remote": "Iqeddacen nniḍen",
|
"firehose.remote": "Iqeddacen nniḍen",
|
||||||
@ -335,6 +336,7 @@
|
|||||||
"mute_modal.show_options": "Sken-d tinefrunin",
|
"mute_modal.show_options": "Sken-d tinefrunin",
|
||||||
"mute_modal.title": "Sgugem aseqdac?",
|
"mute_modal.title": "Sgugem aseqdac?",
|
||||||
"navigation_bar.about": "Ɣef",
|
"navigation_bar.about": "Ɣef",
|
||||||
|
"navigation_bar.advanced_interface": "Ldi deg ugrudem n web leqqayen",
|
||||||
"navigation_bar.blocks": "Iseqdacen yettusḥebsen",
|
"navigation_bar.blocks": "Iseqdacen yettusḥebsen",
|
||||||
"navigation_bar.bookmarks": "Ticraḍ",
|
"navigation_bar.bookmarks": "Ticraḍ",
|
||||||
"navigation_bar.community_timeline": "Tasuddemt tadigant",
|
"navigation_bar.community_timeline": "Tasuddemt tadigant",
|
||||||
@ -364,6 +366,7 @@
|
|||||||
"notification.own_poll": "Tafrant-ik·im tfuk",
|
"notification.own_poll": "Tafrant-ik·im tfuk",
|
||||||
"notification.poll": "Tfukk tefrant ideg tettekkaḍ",
|
"notification.poll": "Tfukk tefrant ideg tettekkaḍ",
|
||||||
"notification.reblog": "{name} yebḍa tajewwiqt-ik i tikelt-nniḍen",
|
"notification.reblog": "{name} yebḍa tajewwiqt-ik i tikelt-nniḍen",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Issin ugar",
|
||||||
"notification.status": "{name} akken i d-yessufeɣ",
|
"notification.status": "{name} akken i d-yessufeɣ",
|
||||||
"notification_requests.accept": "Qbel",
|
"notification_requests.accept": "Qbel",
|
||||||
"notification_requests.dismiss": "Agi",
|
"notification_requests.dismiss": "Agi",
|
||||||
@ -372,6 +375,8 @@
|
|||||||
"notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk tilɣa-inek·em i lebda?",
|
"notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk tilɣa-inek·em i lebda?",
|
||||||
"notifications.column_settings.alert": "Tilɣa n tnarit",
|
"notifications.column_settings.alert": "Tilɣa n tnarit",
|
||||||
"notifications.column_settings.favourite": "Imenyafen:",
|
"notifications.column_settings.favourite": "Imenyafen:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Sken-d akk taggayin",
|
||||||
|
"notifications.column_settings.filter_bar.category": "Iri n usizdeg uzrib",
|
||||||
"notifications.column_settings.follow": "Imeḍfaṛen imaynuten:",
|
"notifications.column_settings.follow": "Imeḍfaṛen imaynuten:",
|
||||||
"notifications.column_settings.follow_request": "Isuturen imaynuten n teḍfeṛt:",
|
"notifications.column_settings.follow_request": "Isuturen imaynuten n teḍfeṛt:",
|
||||||
"notifications.column_settings.mention": "Abdar:",
|
"notifications.column_settings.mention": "Abdar:",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "이 게시물을 필터",
|
"filter_modal.select_filter.title": "이 게시물을 필터",
|
||||||
"filter_modal.title.status": "게시물 필터",
|
"filter_modal.title.status": "게시물 필터",
|
||||||
"filtered_notifications_banner.pending_requests": "알 수도 있는 {count, plural, =0 {0 명} one {한 명} other {# 명}}의 사람들로부터의 알림",
|
"filtered_notifications_banner.pending_requests": "알 수도 있는 {count, plural, =0 {0 명} one {한 명} other {# 명}}의 사람들로부터의 알림",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, other {개인적인 멘션}}",
|
||||||
"filtered_notifications_banner.title": "걸러진 알림",
|
"filtered_notifications_banner.title": "걸러진 알림",
|
||||||
"firehose.all": "모두",
|
"firehose.all": "모두",
|
||||||
"firehose.local": "이 서버",
|
"firehose.local": "이 서버",
|
||||||
@ -471,6 +472,11 @@
|
|||||||
"notification.own_poll": "설문을 마침",
|
"notification.own_poll": "설문을 마침",
|
||||||
"notification.poll": "참여한 설문이 종료됨",
|
"notification.poll": "참여한 설문이 종료됨",
|
||||||
"notification.reblog": "{name} 님이 부스트했습니다",
|
"notification.reblog": "{name} 님이 부스트했습니다",
|
||||||
|
"notification.relationships_severance_event": "{name} 님과의 연결이 끊어졌습니다",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "{from}의 관리자가 {target}를 정지시켰기 때문에 그들과 더이상 상호작용 할 수 없고 정보를 받아볼 수 없습니다.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "{from}의 관리자가 {target}를 차단하였고 여기에는 나의 {followersCount} 명의 팔로워와 {followingCount, plural, other {#}} 명의 팔로우가 포함되었습니다.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "더 알아보기",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "내가 {target}를 차단하여 {followersCount} 명의 팔로워와 {followingCount, plural, other {#}} 명의 팔로우가 제거되었습니다.",
|
||||||
"notification.status": "{name} 님이 방금 게시물을 올렸습니다",
|
"notification.status": "{name} 님이 방금 게시물을 올렸습니다",
|
||||||
"notification.update": "{name} 님이 게시물을 수정했습니다",
|
"notification.update": "{name} 님이 게시물을 수정했습니다",
|
||||||
"notification_requests.accept": "수락",
|
"notification_requests.accept": "수락",
|
||||||
@ -484,6 +490,7 @@
|
|||||||
"notifications.column_settings.alert": "데스크탑 알림",
|
"notifications.column_settings.alert": "데스크탑 알림",
|
||||||
"notifications.column_settings.favourite": "좋아요:",
|
"notifications.column_settings.favourite": "좋아요:",
|
||||||
"notifications.column_settings.filter_bar.advanced": "모든 범주 표시",
|
"notifications.column_settings.filter_bar.advanced": "모든 범주 표시",
|
||||||
|
"notifications.column_settings.filter_bar.category": "빠른 필터 막대",
|
||||||
"notifications.column_settings.follow": "새 팔로워:",
|
"notifications.column_settings.follow": "새 팔로워:",
|
||||||
"notifications.column_settings.follow_request": "새 팔로우 요청:",
|
"notifications.column_settings.follow_request": "새 팔로우 요청:",
|
||||||
"notifications.column_settings.mention": "멘션:",
|
"notifications.column_settings.mention": "멘션:",
|
||||||
|
@ -89,8 +89,12 @@
|
|||||||
"announcement.announcement": "Comunicados",
|
"announcement.announcement": "Comunicados",
|
||||||
"attachments_list.unprocessed": "(não processado)",
|
"attachments_list.unprocessed": "(não processado)",
|
||||||
"audio.hide": "Ocultar áudio",
|
"audio.hide": "Ocultar áudio",
|
||||||
|
"block_modal.remote_users_caveat": "Pediremos ao servidor {domínio} que respeite sua decisão. No entanto, a conformidade não é garantida pois alguns servidores podem lidar com os blocos de maneira diferente. As postagens públicas ainda podem estar visíveis para usuários não logados.",
|
||||||
"block_modal.show_less": "Mostrar menos",
|
"block_modal.show_less": "Mostrar menos",
|
||||||
"block_modal.show_more": "Mostrar mais",
|
"block_modal.show_more": "Mostrar mais",
|
||||||
|
"block_modal.they_cant_mention": "Eles não podem mencionar ou seguir você.",
|
||||||
|
"block_modal.they_cant_see_posts": "Eles não podem ver suas postagens e você não verá as deles.",
|
||||||
|
"block_modal.they_will_know": "Eles podem ver que estão bloqueados.",
|
||||||
"block_modal.title": "Bloquear usuário?",
|
"block_modal.title": "Bloquear usuário?",
|
||||||
"block_modal.you_wont_see_mentions": "Você não verá publicações que os mencionem.",
|
"block_modal.you_wont_see_mentions": "Você não verá publicações que os mencionem.",
|
||||||
"boost_modal.combo": "Pressione {combo} para pular isso na próxima vez",
|
"boost_modal.combo": "Pressione {combo} para pular isso na próxima vez",
|
||||||
@ -173,6 +177,7 @@
|
|||||||
"confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?",
|
"confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?",
|
||||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||||
"confirmations.discard_edit_media.message": "Há mudanças não salvas na descrição ou pré-visualização da mídia. Descartar assim mesmo?",
|
"confirmations.discard_edit_media.message": "Há mudanças não salvas na descrição ou pré-visualização da mídia. Descartar assim mesmo?",
|
||||||
|
"confirmations.domain_block.confirm": "Servidor de blocos",
|
||||||
"confirmations.domain_block.message": "Você tem certeza de que deseja bloquear tudo de {domain}? Você não verá mais o conteúdo desta instância em nenhuma linha do tempo pública ou nas suas notificações. Seus seguidores desta instância serão removidos.",
|
"confirmations.domain_block.message": "Você tem certeza de que deseja bloquear tudo de {domain}? Você não verá mais o conteúdo desta instância em nenhuma linha do tempo pública ou nas suas notificações. Seus seguidores desta instância serão removidos.",
|
||||||
"confirmations.edit.confirm": "Editar",
|
"confirmations.edit.confirm": "Editar",
|
||||||
"confirmations.edit.message": "Editar agora irá substituir a mensagem que está sendo criando. Tem certeza de que deseja continuar?",
|
"confirmations.edit.message": "Editar agora irá substituir a mensagem que está sendo criando. Tem certeza de que deseja continuar?",
|
||||||
@ -204,8 +209,27 @@
|
|||||||
"dismissable_banner.explore_statuses": "Estas são postagens de toda a rede social que estão ganhando tração hoje. Postagens mais recentes com mais impulsos e favoritos têm classificações mais altas.",
|
"dismissable_banner.explore_statuses": "Estas são postagens de toda a rede social que estão ganhando tração hoje. Postagens mais recentes com mais impulsos e favoritos têm classificações mais altas.",
|
||||||
"dismissable_banner.explore_tags": "Estas hashtags estão ganhando popularidade no momento entre as pessoas deste e de outros servidores da rede descentralizada.",
|
"dismissable_banner.explore_tags": "Estas hashtags estão ganhando popularidade no momento entre as pessoas deste e de outros servidores da rede descentralizada.",
|
||||||
"dismissable_banner.public_timeline": "Estas são as publicações públicas mais recentes de pessoas na rede social que pessoas em {domain} seguem.",
|
"dismissable_banner.public_timeline": "Estas são as publicações públicas mais recentes de pessoas na rede social que pessoas em {domain} seguem.",
|
||||||
|
"domain_block_modal.block": "Servidor de blocos.",
|
||||||
|
"domain_block_modal.block_account_instead": "Bloco @(nome)",
|
||||||
"domain_block_modal.they_can_interact_with_old_posts": "Pessoas deste servidor podem interagir com suas publicações antigas.",
|
"domain_block_modal.they_can_interact_with_old_posts": "Pessoas deste servidor podem interagir com suas publicações antigas.",
|
||||||
"domain_block_modal.they_cant_follow": "Ninguém deste servidor pode lhe seguir.",
|
"domain_block_modal.they_cant_follow": "Ninguém deste servidor pode lhe seguir.",
|
||||||
|
"domain_block_modal.they_wont_know": "Eles não saberão que foram bloqueados.",
|
||||||
|
"domain_block_modal.title": "Dominio do bloco",
|
||||||
|
"domain_block_modal.you_will_lose_followers": "Todos os seus seguidores deste servidor serão removidos.",
|
||||||
|
"domain_block_modal.you_wont_see_posts": "Você não verá postagens ou notificações de usuários neste servidor.",
|
||||||
|
"domain_pill.activitypub_lets_connect": "Ele permite que você se conecte e interaja com pessoas não apenas no Mastodon, mas também em diferentes aplicativos sociais.",
|
||||||
|
"domain_pill.activitypub_like_language": "ActivityPub é como a linguagem que o Mastodon fala com outras redes sociais.",
|
||||||
|
"domain_pill.server": "Servidor",
|
||||||
|
"domain_pill.their_handle": "Seu identificador:",
|
||||||
|
"domain_pill.their_server": "Sua casa digital, onde ficam todas as suas postagens.",
|
||||||
|
"domain_pill.their_username": "Seu identificador exclusivo em seu servidor. É possível encontrar usuários com o mesmo nome de usuário em servidores diferentes.",
|
||||||
|
"domain_pill.username": "Nome de usuário",
|
||||||
|
"domain_pill.whats_in_a_handle": "O que há em uma alça?",
|
||||||
|
"domain_pill.who_they_are": "Como os identificadores indicam quem alguém é e onde está, você pode interagir com pessoas na web social de <button>plataformas alimentadas pelo ActivityPub</button>.",
|
||||||
|
"domain_pill.who_you_are": "Como seu identificador indica quem você é e onde está, as pessoas podem interagir com você nas redes sociais das <button>plataformas alimentadas pelo ActivityPub</button>.",
|
||||||
|
"domain_pill.your_handle": "Seu identificador:",
|
||||||
|
"domain_pill.your_server": "Sua casa digital, onde ficam todas as suas postagens. Não gosta deste? Transfira servidores a qualquer momento e traga seus seguidores também.",
|
||||||
|
"domain_pill.your_username": "Seu identificador exclusivo neste servidor. É possível encontrar usuários com o mesmo nome de usuário em servidores diferentes.",
|
||||||
"embed.instructions": "Incorpore este toot no seu site ao copiar o código abaixo.",
|
"embed.instructions": "Incorpore este toot no seu site ao copiar o código abaixo.",
|
||||||
"embed.preview": "Aqui está como vai ficar:",
|
"embed.preview": "Aqui está como vai ficar:",
|
||||||
"emoji_button.activity": "Atividade",
|
"emoji_button.activity": "Atividade",
|
||||||
@ -273,6 +297,8 @@
|
|||||||
"filter_modal.select_filter.subtitle": "Use uma categoria existente ou crie uma nova",
|
"filter_modal.select_filter.subtitle": "Use uma categoria existente ou crie uma nova",
|
||||||
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
||||||
"filter_modal.title.status": "Filtrar uma publicação",
|
"filter_modal.title.status": "Filtrar uma publicação",
|
||||||
|
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {no one} one {one person} other {# people}} que você talvez conheça",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, one {private mention} other {private mentions}}",
|
||||||
"filtered_notifications_banner.title": "Notificações filtradas",
|
"filtered_notifications_banner.title": "Notificações filtradas",
|
||||||
"firehose.all": "Tudo",
|
"firehose.all": "Tudo",
|
||||||
"firehose.local": "Este servidor",
|
"firehose.local": "Este servidor",
|
||||||
@ -402,7 +428,9 @@
|
|||||||
"loading_indicator.label": "Carregando…",
|
"loading_indicator.label": "Carregando…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Ocultar mídia} other {Ocultar mídias}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Ocultar mídia} other {Ocultar mídias}}",
|
||||||
"moved_to_account_banner.text": "Sua conta {disabledAccount} está desativada porque você a moveu para {movedToAccount}.",
|
"moved_to_account_banner.text": "Sua conta {disabledAccount} está desativada porque você a moveu para {movedToAccount}.",
|
||||||
|
"mute_modal.hide_from_notifications": "Ocultar das notificações",
|
||||||
"mute_modal.hide_options": "Ocultar opções",
|
"mute_modal.hide_options": "Ocultar opções",
|
||||||
|
"mute_modal.indefinite": "Até que eu os ative",
|
||||||
"mute_modal.show_options": "Mostrar opções",
|
"mute_modal.show_options": "Mostrar opções",
|
||||||
"mute_modal.they_can_mention_and_follow": "Eles podem mencionar e seguir você, mas você não os verá.",
|
"mute_modal.they_can_mention_and_follow": "Eles podem mencionar e seguir você, mas você não os verá.",
|
||||||
"mute_modal.they_wont_know": "Eles não saberão que foram silenciados.",
|
"mute_modal.they_wont_know": "Eles não saberão que foram silenciados.",
|
||||||
@ -444,6 +472,11 @@
|
|||||||
"notification.own_poll": "Sua enquete terminou",
|
"notification.own_poll": "Sua enquete terminou",
|
||||||
"notification.poll": "Uma enquete que você votou terminou",
|
"notification.poll": "Uma enquete que você votou terminou",
|
||||||
"notification.reblog": "{name} deu boost no teu toot",
|
"notification.reblog": "{name} deu boost no teu toot",
|
||||||
|
"notification.relationships_severance_event": "Conexões perdidas com {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Um administrador de {from} suspendeu {target}, o que significa que você não pode mais receber atualizações deles ou interagir com eles.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Saber mais",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
|
||||||
"notification.status": "{name} acabou de tootar",
|
"notification.status": "{name} acabou de tootar",
|
||||||
"notification.update": "{name} editou uma publicação",
|
"notification.update": "{name} editou uma publicação",
|
||||||
"notification_requests.accept": "Aceitar",
|
"notification_requests.accept": "Aceitar",
|
||||||
@ -456,6 +489,8 @@
|
|||||||
"notifications.column_settings.admin.sign_up": "Novas inscrições:",
|
"notifications.column_settings.admin.sign_up": "Novas inscrições:",
|
||||||
"notifications.column_settings.alert": "Notificações no computador",
|
"notifications.column_settings.alert": "Notificações no computador",
|
||||||
"notifications.column_settings.favourite": "Favoritos:",
|
"notifications.column_settings.favourite": "Favoritos:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Exibir todas as categorias",
|
||||||
|
"notifications.column_settings.filter_bar.category": "Barra de filtro rápido",
|
||||||
"notifications.column_settings.follow": "Seguidores:",
|
"notifications.column_settings.follow": "Seguidores:",
|
||||||
"notifications.column_settings.follow_request": "Seguidores pendentes:",
|
"notifications.column_settings.follow_request": "Seguidores pendentes:",
|
||||||
"notifications.column_settings.mention": "Menções:",
|
"notifications.column_settings.mention": "Menções:",
|
||||||
@ -481,7 +516,9 @@
|
|||||||
"notifications.permission_denied": "Navegador não tem permissão para ativar notificações no computador.",
|
"notifications.permission_denied": "Navegador não tem permissão para ativar notificações no computador.",
|
||||||
"notifications.permission_denied_alert": "Verifique a permissão do navegador para ativar notificações no computador.",
|
"notifications.permission_denied_alert": "Verifique a permissão do navegador para ativar notificações no computador.",
|
||||||
"notifications.permission_required": "Ativar notificações no computador exige permissão do navegador.",
|
"notifications.permission_required": "Ativar notificações no computador exige permissão do navegador.",
|
||||||
|
"notifications.policy.filter_new_accounts.hint": "Created within the past {days, plural, one {one day} other {# days}}",
|
||||||
"notifications.policy.filter_new_accounts_title": "Novas contas",
|
"notifications.policy.filter_new_accounts_title": "Novas contas",
|
||||||
|
"notifications.policy.filter_not_followers_hint": "Including people who have been following you fewer than {days, plural, one {one day} other {# days}}",
|
||||||
"notifications.policy.filter_not_followers_title": "Pessoas que não estão te seguindo",
|
"notifications.policy.filter_not_followers_title": "Pessoas que não estão te seguindo",
|
||||||
"notifications.policy.filter_not_following_hint": "Até que você os aprove manualmente",
|
"notifications.policy.filter_not_following_hint": "Até que você os aprove manualmente",
|
||||||
"notifications.policy.filter_not_following_title": "Pessoas que você não segue",
|
"notifications.policy.filter_not_following_title": "Pessoas que você não segue",
|
||||||
@ -569,6 +606,7 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "hoje",
|
"relative_time.today": "hoje",
|
||||||
|
"reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"reply_indicator.poll": "Enquete",
|
"reply_indicator.poll": "Enquete",
|
||||||
"report.block": "Bloquear",
|
"report.block": "Bloquear",
|
||||||
@ -667,6 +705,7 @@
|
|||||||
"status.edited_x_times": "Editado {count, plural, one {{count} hora} other {{count} vezes}}",
|
"status.edited_x_times": "Editado {count, plural, one {{count} hora} other {{count} vezes}}",
|
||||||
"status.embed": "Incorporar",
|
"status.embed": "Incorporar",
|
||||||
"status.favourite": "Favorita",
|
"status.favourite": "Favorita",
|
||||||
|
"status.favourites": "{count, plural, one {favorite} other {favorites}}",
|
||||||
"status.filter": "Filtrar esta publicação",
|
"status.filter": "Filtrar esta publicação",
|
||||||
"status.filtered": "Filtrado",
|
"status.filtered": "Filtrado",
|
||||||
"status.hide": "Ocultar publicação",
|
"status.hide": "Ocultar publicação",
|
||||||
@ -687,6 +726,7 @@
|
|||||||
"status.reblog": "Dar boost",
|
"status.reblog": "Dar boost",
|
||||||
"status.reblog_private": "Dar boost para o mesmo público",
|
"status.reblog_private": "Dar boost para o mesmo público",
|
||||||
"status.reblogged_by": "{name} deu boost",
|
"status.reblogged_by": "{name} deu boost",
|
||||||
|
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
|
||||||
"status.reblogs.empty": "Nada aqui. Quando alguém der boost, o usuário aparecerá aqui.",
|
"status.reblogs.empty": "Nada aqui. Quando alguém der boost, o usuário aparecerá aqui.",
|
||||||
"status.redraft": "Excluir e rascunhar",
|
"status.redraft": "Excluir e rascunhar",
|
||||||
"status.remove_bookmark": "Remover do Salvos",
|
"status.remove_bookmark": "Remover do Salvos",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
||||||
"filter_modal.title.status": "Filtrar uma publicação",
|
"filter_modal.title.status": "Filtrar uma publicação",
|
||||||
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {ninguém} one {uma pessoa} other {# pessoas}} que talvez conheça",
|
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {ninguém} one {uma pessoa} other {# pessoas}} que talvez conheça",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural,one {menção privada} other {menções privadas}}",
|
||||||
"filtered_notifications_banner.title": "Notificações filtradas",
|
"filtered_notifications_banner.title": "Notificações filtradas",
|
||||||
"firehose.all": "Todas",
|
"firehose.all": "Todas",
|
||||||
"firehose.local": "Este servidor",
|
"firehose.local": "Este servidor",
|
||||||
@ -471,6 +472,11 @@
|
|||||||
"notification.own_poll": "A sua votação terminou",
|
"notification.own_poll": "A sua votação terminou",
|
||||||
"notification.poll": "Uma votação em que participaste chegou ao fim",
|
"notification.poll": "Uma votação em que participaste chegou ao fim",
|
||||||
"notification.reblog": "{name} reforçou a tua publicação",
|
"notification.reblog": "{name} reforçou a tua publicação",
|
||||||
|
"notification.relationships_severance_event": "Perdeu as ligações com {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Um administrador de {from} suspendeu {target}, o que significa que já não pode receber atualizações dele ou interagir com ele.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Um administrador de {from} bloqueou {target}, incluindo {followersCount} dos seus seguidores e {followingCount, plural, one {# conta} other {# contas}} que segue.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Saber mais",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Bloqueou {target}, removendo {followersCount} dos seus seguidores e {followingCount, plural, one {# conta} other {# contas}} que segue.",
|
||||||
"notification.status": "{name} acabou de publicar",
|
"notification.status": "{name} acabou de publicar",
|
||||||
"notification.update": "{name} editou uma publicação",
|
"notification.update": "{name} editou uma publicação",
|
||||||
"notification_requests.accept": "Aceitar",
|
"notification_requests.accept": "Aceitar",
|
||||||
|
@ -298,6 +298,7 @@
|
|||||||
"filter_modal.select_filter.title": "Filtriraj to objavo",
|
"filter_modal.select_filter.title": "Filtriraj to objavo",
|
||||||
"filter_modal.title.status": "Filtrirajte objavo",
|
"filter_modal.title.status": "Filtrirajte objavo",
|
||||||
"filtered_notifications_banner.pending_requests": "Obvestila od {count, plural, =0 {nikogar, ki bi ga} one {# človeka, ki bi ga} two {# ljudi, ki bi ju} few {# ljudi, ki bi jih} other {# ljudi, ki bi jih}} lahko poznali",
|
"filtered_notifications_banner.pending_requests": "Obvestila od {count, plural, =0 {nikogar, ki bi ga} one {# človeka, ki bi ga} two {# ljudi, ki bi ju} few {# ljudi, ki bi jih} other {# ljudi, ki bi jih}} lahko poznali",
|
||||||
|
"filtered_notifications_banner.private_mentions": "{count, plural, one {zasebna omemba} two {zasebni omembi} few {zasebne omembe} other {zasebnih omemb}}",
|
||||||
"filtered_notifications_banner.title": "Filtrirana obvestila",
|
"filtered_notifications_banner.title": "Filtrirana obvestila",
|
||||||
"firehose.all": "Vse",
|
"firehose.all": "Vse",
|
||||||
"firehose.local": "Ta strežnik",
|
"firehose.local": "Ta strežnik",
|
||||||
@ -471,6 +472,11 @@
|
|||||||
"notification.own_poll": "Vaša anketa je zaključena",
|
"notification.own_poll": "Vaša anketa je zaključena",
|
||||||
"notification.poll": "Anketa, v kateri ste sodelovali, je zaključena",
|
"notification.poll": "Anketa, v kateri ste sodelovali, je zaključena",
|
||||||
"notification.reblog": "{name} je izpostavila/a vašo objavo",
|
"notification.reblog": "{name} je izpostavila/a vašo objavo",
|
||||||
|
"notification.relationships_severance_event": "Povezave z {name} prekinjene",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Skrbnik na {from} je suspendiral račun {target}, kar pomeni, da od računa ne morete več prejemati posodobitev ali imeti z njim interakcij.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Skrbnik na {from} je blokiral domeno {target}, vključno z vašimi sledilci ({followersCount}) in {followingCount, plural, one {# računom, ki mu sledite} two {# računoma, ki jima sledite} few {# računi, ki jim sledite} other {# računi, ki jim sledite}}.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Več o tem",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Blokirali ste domeno {target}, vključno z vašimi sledilci ({followersCount}) in {followingCount, plural, one {# računom, ki mu sledite} two {# računoma, ki jima sledite} few {# računi, ki jim sledite} other {# računi, ki jim sledite}}.",
|
||||||
"notification.status": "{name} je pravkar objavil/a",
|
"notification.status": "{name} je pravkar objavil/a",
|
||||||
"notification.update": "{name} je uredil(a) objavo",
|
"notification.update": "{name} je uredil(a) objavo",
|
||||||
"notification_requests.accept": "Sprejmi",
|
"notification_requests.accept": "Sprejmi",
|
||||||
|
@ -462,6 +462,7 @@
|
|||||||
"notification.own_poll": "Ваша анкета је завршена",
|
"notification.own_poll": "Ваша анкета је завршена",
|
||||||
"notification.poll": "Завршена је анкета у којој сте гласали",
|
"notification.poll": "Завршена је анкета у којој сте гласали",
|
||||||
"notification.reblog": "{name} је подржао вашу објаву",
|
"notification.reblog": "{name} је подржао вашу објаву",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Сазнајте више",
|
||||||
"notification.status": "{name} је управо објавио",
|
"notification.status": "{name} је управо објавио",
|
||||||
"notification.update": "{name} је уредио објаву",
|
"notification.update": "{name} је уредио објаву",
|
||||||
"notification_requests.accept": "Прихвати",
|
"notification_requests.accept": "Прихвати",
|
||||||
@ -474,6 +475,7 @@
|
|||||||
"notifications.column_settings.admin.sign_up": "Нове рагистрације:",
|
"notifications.column_settings.admin.sign_up": "Нове рагистрације:",
|
||||||
"notifications.column_settings.alert": "Обавештења на радној површини",
|
"notifications.column_settings.alert": "Обавештења на радној површини",
|
||||||
"notifications.column_settings.favourite": "Омиљено:",
|
"notifications.column_settings.favourite": "Омиљено:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Прикажи све категорије",
|
||||||
"notifications.column_settings.follow": "Нови пратиоци:",
|
"notifications.column_settings.follow": "Нови пратиоци:",
|
||||||
"notifications.column_settings.follow_request": "Нови захтеви за праћење:",
|
"notifications.column_settings.follow_request": "Нови захтеви за праћење:",
|
||||||
"notifications.column_settings.mention": "Помињања:",
|
"notifications.column_settings.mention": "Помињања:",
|
||||||
|
@ -21,14 +21,14 @@ import history from './history';
|
|||||||
import listAdder from './list_adder';
|
import listAdder from './list_adder';
|
||||||
import listEditor from './list_editor';
|
import listEditor from './list_editor';
|
||||||
import lists from './lists';
|
import lists from './lists';
|
||||||
import markers from './markers';
|
import { markersReducer } from './markers';
|
||||||
import media_attachments from './media_attachments';
|
import media_attachments from './media_attachments';
|
||||||
import meta from './meta';
|
import meta from './meta';
|
||||||
import { modalReducer } from './modal';
|
import { modalReducer } from './modal';
|
||||||
import { notificationPolicyReducer } from './notification_policy';
|
import { notificationPolicyReducer } from './notification_policy';
|
||||||
import { notificationRequestsReducer } from './notification_requests';
|
import { notificationRequestsReducer } from './notification_requests';
|
||||||
import notifications from './notifications';
|
import notifications from './notifications';
|
||||||
import picture_in_picture from './picture_in_picture';
|
import { pictureInPictureReducer } from './picture_in_picture';
|
||||||
import polls from './polls';
|
import polls from './polls';
|
||||||
import push_notifications from './push_notifications';
|
import push_notifications from './push_notifications';
|
||||||
import { relationshipsReducer } from './relationships';
|
import { relationshipsReducer } from './relationships';
|
||||||
@ -77,8 +77,8 @@ const reducers = {
|
|||||||
suggestions,
|
suggestions,
|
||||||
polls,
|
polls,
|
||||||
trends,
|
trends,
|
||||||
markers,
|
markers: markersReducer,
|
||||||
picture_in_picture,
|
picture_in_picture: pictureInPictureReducer,
|
||||||
history,
|
history,
|
||||||
tags,
|
tags,
|
||||||
followed_tags,
|
followed_tags,
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import { Map as ImmutableMap } from 'immutable';
|
|
||||||
|
|
||||||
import {
|
|
||||||
MARKERS_SUBMIT_SUCCESS,
|
|
||||||
} from '../actions/markers';
|
|
||||||
|
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
|
||||||
home: '0',
|
|
||||||
notifications: '0',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function markers(state = initialState, action) {
|
|
||||||
switch(action.type) {
|
|
||||||
case MARKERS_SUBMIT_SUCCESS:
|
|
||||||
if (action.home) {
|
|
||||||
state = state.set('home', action.home);
|
|
||||||
}
|
|
||||||
if (action.notifications) {
|
|
||||||
state = state.set('notifications', action.notifications);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
18
app/javascript/mastodon/reducers/markers.ts
Normal file
18
app/javascript/mastodon/reducers/markers.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { submitMarkersAction } from 'mastodon/actions/markers';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
home: '0',
|
||||||
|
notifications: '0',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const markersReducer = createReducer(initialState, (builder) => {
|
||||||
|
builder.addCase(
|
||||||
|
submitMarkersAction.fulfilled,
|
||||||
|
(state, { payload: { home, notifications } }) => {
|
||||||
|
if (home) state.home = home;
|
||||||
|
if (notifications) state.notifications = notifications;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
@ -13,7 +13,7 @@ import {
|
|||||||
unfocusApp,
|
unfocusApp,
|
||||||
} from '../actions/app';
|
} from '../actions/app';
|
||||||
import {
|
import {
|
||||||
MARKERS_FETCH_SUCCESS,
|
fetchMarkers,
|
||||||
} from '../actions/markers';
|
} from '../actions/markers';
|
||||||
import {
|
import {
|
||||||
notificationsUpdate,
|
notificationsUpdate,
|
||||||
@ -255,8 +255,8 @@ const recountUnread = (state, last_read_id) => {
|
|||||||
|
|
||||||
export default function notifications(state = initialState, action) {
|
export default function notifications(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case MARKERS_FETCH_SUCCESS:
|
case fetchMarkers.fulfilled.type:
|
||||||
return action.markers.notifications ? recountUnread(state, action.markers.notifications.last_read_id) : state;
|
return action.payload.markers.notifications ? recountUnread(state, action.payload.markers.notifications.last_read_id) : state;
|
||||||
case NOTIFICATIONS_MOUNT:
|
case NOTIFICATIONS_MOUNT:
|
||||||
return updateMounted(state);
|
return updateMounted(state);
|
||||||
case NOTIFICATIONS_UNMOUNT:
|
case NOTIFICATIONS_UNMOUNT:
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import { PICTURE_IN_PICTURE_DEPLOY, PICTURE_IN_PICTURE_REMOVE } from 'mastodon/actions/picture_in_picture';
|
|
||||||
|
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
statusId: null,
|
|
||||||
accountId: null,
|
|
||||||
type: null,
|
|
||||||
src: null,
|
|
||||||
muted: false,
|
|
||||||
volume: 0,
|
|
||||||
currentTime: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function pictureInPicture(state = initialState, action) {
|
|
||||||
switch(action.type) {
|
|
||||||
case PICTURE_IN_PICTURE_DEPLOY:
|
|
||||||
return { statusId: action.statusId, accountId: action.accountId, type: action.playerType, ...action.props };
|
|
||||||
case PICTURE_IN_PICTURE_REMOVE:
|
|
||||||
return { ...initialState };
|
|
||||||
case TIMELINE_DELETE:
|
|
||||||
return (state.statusId === action.id) ? { ...initialState } : state;
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
56
app/javascript/mastodon/reducers/picture_in_picture.ts
Normal file
56
app/javascript/mastodon/reducers/picture_in_picture.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import type { Reducer } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import {
|
||||||
|
deployPictureInPictureAction,
|
||||||
|
removePictureInPicture,
|
||||||
|
} from 'mastodon/actions/picture_in_picture';
|
||||||
|
|
||||||
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
|
|
||||||
|
export interface PIPMediaProps {
|
||||||
|
src: string;
|
||||||
|
muted: boolean;
|
||||||
|
volume: number;
|
||||||
|
currentTime: number;
|
||||||
|
poster: string;
|
||||||
|
backgroundColor: string;
|
||||||
|
foregroundColor: string;
|
||||||
|
accentColor: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PIPStateWithValue extends Partial<PIPMediaProps> {
|
||||||
|
statusId: string;
|
||||||
|
accountId: string;
|
||||||
|
type: 'audio' | 'video';
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PIPStateEmpty extends Partial<PIPMediaProps> {
|
||||||
|
type: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PIPState = PIPStateWithValue | PIPStateEmpty;
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
type: null,
|
||||||
|
muted: false,
|
||||||
|
volume: 0,
|
||||||
|
currentTime: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pictureInPictureReducer: Reducer<PIPState> = (
|
||||||
|
state = initialState,
|
||||||
|
action,
|
||||||
|
) => {
|
||||||
|
if (deployPictureInPictureAction.match(action))
|
||||||
|
return {
|
||||||
|
statusId: action.payload.statusId,
|
||||||
|
accountId: action.payload.accountId,
|
||||||
|
type: action.payload.playerType,
|
||||||
|
...action.payload.props,
|
||||||
|
};
|
||||||
|
else if (removePictureInPicture.match(action)) return initialState;
|
||||||
|
else if (action.type === TIMELINE_DELETE)
|
||||||
|
if (state.type && state.statusId === action.id) return initialState;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
@ -60,7 +60,7 @@ export const makeGetStatus = () => {
|
|||||||
|
|
||||||
export const makeGetPictureInPicture = () => {
|
export const makeGetPictureInPicture = () => {
|
||||||
return createSelector([
|
return createSelector([
|
||||||
(state, { id }) => state.get('picture_in_picture').statusId === id,
|
(state, { id }) => state.picture_in_picture.statusId === id,
|
||||||
(state) => state.getIn(['meta', 'layout']) !== 'mobile',
|
(state) => state.getIn(['meta', 'layout']) !== 'mobile',
|
||||||
], (inUse, available) => ImmutableMap({
|
], (inUse, available) => ImmutableMap({
|
||||||
inUse: inUse && available,
|
inUse: inUse && available,
|
||||||
|
@ -2612,6 +2612,7 @@ a.account__display-name {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$ui-header-height: 55px;
|
$ui-header-height: 55px;
|
||||||
|
$ui-header-logo-wordmark-width: 99px;
|
||||||
|
|
||||||
.ui__header {
|
.ui__header {
|
||||||
display: none;
|
display: none;
|
||||||
@ -2627,6 +2628,10 @@ $ui-header-height: 55px;
|
|||||||
&__logo {
|
&__logo {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
container: header-logo / inline-size;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: $ui-header-height - 30px;
|
height: $ui-header-height - 30px;
|
||||||
@ -2637,7 +2642,7 @@ $ui-header-height: 55px;
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (width >= 320px) {
|
@container header-logo (min-width: #{$ui-header-logo-wordmark-width}) {
|
||||||
.logo--wordmark {
|
.logo--wordmark {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -2654,6 +2659,7 @@ $ui-header-height: 55px;
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
@ -5084,6 +5090,7 @@ a.status-card {
|
|||||||
.language-dropdown__dropdown {
|
.language-dropdown__dropdown {
|
||||||
box-shadow: var(--dropdown-shadow);
|
box-shadow: var(--dropdown-shadow);
|
||||||
background: var(--dropdown-background-color);
|
background: var(--dropdown-background-color);
|
||||||
|
backdrop-filter: var(--background-filter);
|
||||||
border: 1px solid var(--dropdown-border-color);
|
border: 1px solid var(--dropdown-border-color);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
@ -27,6 +27,8 @@ class AccountWarning < ApplicationRecord
|
|||||||
suspend: 4_000,
|
suspend: 4_000,
|
||||||
}, suffix: :action
|
}, suffix: :action
|
||||||
|
|
||||||
|
RECENT_PERIOD = 3.months.freeze
|
||||||
|
|
||||||
normalizes :text, with: ->(text) { text.to_s }, apply_to_nil: true
|
normalizes :text, with: ->(text) { text.to_s }, apply_to_nil: true
|
||||||
|
|
||||||
belongs_to :account, inverse_of: :account_warnings
|
belongs_to :account, inverse_of: :account_warnings
|
||||||
@ -37,7 +39,7 @@ class AccountWarning < ApplicationRecord
|
|||||||
|
|
||||||
scope :latest, -> { order(id: :desc) }
|
scope :latest, -> { order(id: :desc) }
|
||||||
scope :custom, -> { where.not(text: '') }
|
scope :custom, -> { where.not(text: '') }
|
||||||
scope :recent, -> { where('account_warnings.created_at >= ?', 3.months.ago) }
|
scope :recent, -> { where(created_at: RECENT_PERIOD.ago..) }
|
||||||
|
|
||||||
def statuses
|
def statuses
|
||||||
Status.with_discarded.where(id: status_ids || [])
|
Status.with_discarded.where(id: status_ids || [])
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::MarkerSerializer < ActiveModel::Serializer
|
class REST::MarkerSerializer < ActiveModel::Serializer
|
||||||
|
# Please update `app/javascript/mastodon/api_types/markers.ts` when making changes to the attributes
|
||||||
|
|
||||||
attributes :last_read_id, :version, :updated_at
|
attributes :last_read_id, :version, :updated_at
|
||||||
|
|
||||||
def last_read_id
|
def last_read_id
|
||||||
|
@ -16,16 +16,14 @@
|
|||||||
= image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20
|
= image_tag frontend_asset_url('images/mailer-new/welcome/checkbox-off.png'), alt: '', width: 20, height: 20
|
||||||
%td.email-checklist-icons-step-td
|
%td.email-checklist-icons-step-td
|
||||||
- if defined?(key)
|
- if defined?(key)
|
||||||
= image_tag frontend_asset_url("images/mailer-new/welcome-icons/#{key}-#{checked ? 'on' : 'off'}.png"), alt: '', width: 40, height: 40
|
= image_tag frontend_asset_url("images/mailer-new/welcome-icons/#{key}_step-#{checked ? 'on' : 'off'}.png"), alt: '', width: 40, height: 40
|
||||||
%td.email-checklist-text-td
|
%td.email-checklist-text-td
|
||||||
.email-desktop-flex
|
.email-desktop-flex
|
||||||
/[if mso]
|
/[if mso]
|
||||||
<table border="0" cellpadding="0" cellspacing="0" align="center" style="width:100%;" role="presentation"><tr><td vertical-align:top;">
|
<table border="0" cellpadding="0" cellspacing="0" align="center" style="width:100%;" role="presentation"><tr><td vertical-align:top;">
|
||||||
%div
|
%div
|
||||||
- if defined?(title)
|
%h3= t("user_mailer.welcome.#{key}_title")
|
||||||
%h3= title
|
%p= t("user_mailer.welcome.#{key}_step")
|
||||||
- if defined?(text)
|
|
||||||
%p= text
|
|
||||||
/[if mso]
|
/[if mso]
|
||||||
</td><td style="vertical-align:top;">
|
</td><td style="vertical-align:top;">
|
||||||
%div
|
%div
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
%td.email-body-huge-padding-td
|
%td.email-body-huge-padding-td
|
||||||
%h2.email-h2= t('user_mailer.welcome.checklist_title')
|
%h2.email-h2= t('user_mailer.welcome.checklist_title')
|
||||||
%p.email-h-sub= t('user_mailer.welcome.checklist_subtitle')
|
%p.email-h-sub= t('user_mailer.welcome.checklist_subtitle')
|
||||||
= render 'application/mailer/checklist', key: 'edit_profile_step', title: t('user_mailer.welcome.edit_profile_title'), text: t('user_mailer.welcome.edit_profile_step'), checked: @has_account_fields, button_text: t('user_mailer.welcome.edit_profile_action'), button_url: web_url('start/profile')
|
= render 'application/mailer/checklist', key: 'edit_profile', checked: @has_account_fields, button_text: t('user_mailer.welcome.edit_profile_action'), button_url: web_url('start/profile')
|
||||||
= render 'application/mailer/checklist', key: 'follow_step', title: t('user_mailer.welcome.follow_title'), text: t('user_mailer.welcome.follow_step'), checked: @has_active_relationships, button_text: t('user_mailer.welcome.follow_action'), button_url: web_url('start/follows')
|
= render 'application/mailer/checklist', key: 'follow', checked: @has_active_relationships, button_text: t('user_mailer.welcome.follow_action'), button_url: web_url('start/follows')
|
||||||
= render 'application/mailer/checklist', key: 'post_step', title: t('user_mailer.welcome.post_title'), text: t('user_mailer.welcome.post_step'), checked: @has_statuses, button_text: t('user_mailer.welcome.post_action'), button_url: web_url
|
= render 'application/mailer/checklist', key: 'post', checked: @has_statuses, button_text: t('user_mailer.welcome.post_action'), button_url: web_url
|
||||||
= render 'application/mailer/checklist', key: 'share_step', title: t('user_mailer.welcome.share_title'), text: t('user_mailer.welcome.share_step'), checked: false, button_text: t('user_mailer.welcome.share_action'), button_url: web_url('start/share')
|
= render 'application/mailer/checklist', key: 'share', checked: false, button_text: t('user_mailer.welcome.share_action'), button_url: web_url('start/share')
|
||||||
= render 'application/mailer/checklist', key: 'apps_step', title: t('user_mailer.welcome.apps_title'), text: t('user_mailer.welcome.apps_step'), checked: false, show_apps_buttons: true
|
= render 'application/mailer/checklist', key: 'apps', checked: false, show_apps_buttons: true
|
||||||
%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
|
%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
|
||||||
%tr
|
%tr
|
||||||
%td.email-body-columns-td
|
%td.email-body-columns-td
|
||||||
|
@ -1768,6 +1768,7 @@ bg:
|
|||||||
contrast: Mastodon (висок контраст)
|
contrast: Mastodon (висок контраст)
|
||||||
default: Mastodon (тъмно)
|
default: Mastodon (тъмно)
|
||||||
mastodon-light: Mastodon (светло)
|
mastodon-light: Mastodon (светло)
|
||||||
|
system: Самодейно (употреба на системната тема)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b, %Y, %H:%M"
|
default: "%d %b, %Y, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ ca:
|
|||||||
contrast: Mastodon (alt contrast)
|
contrast: Mastodon (alt contrast)
|
||||||
default: Mastodon (fosc)
|
default: Mastodon (fosc)
|
||||||
mastodon-light: Mastodon (clar)
|
mastodon-light: Mastodon (clar)
|
||||||
|
system: Automàtic (utilitza el tema del sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%b %d, %Y, %H:%M"
|
default: "%b %d, %Y, %H:%M"
|
||||||
|
@ -1767,6 +1767,7 @@ da:
|
|||||||
contrast: Mastodon (høj kontrast)
|
contrast: Mastodon (høj kontrast)
|
||||||
default: Mastodont (mørkt)
|
default: Mastodont (mørkt)
|
||||||
mastodon-light: Mastodon (lyst)
|
mastodon-light: Mastodon (lyst)
|
||||||
|
system: Automatisk (benyt systemtema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d. %b %Y, %H:%M"
|
default: "%d. %b %Y, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ de:
|
|||||||
contrast: Mastodon (Hoher Kontrast)
|
contrast: Mastodon (Hoher Kontrast)
|
||||||
default: Mastodon (Dunkel)
|
default: Mastodon (Dunkel)
|
||||||
mastodon-light: Mastodon (Hell)
|
mastodon-light: Mastodon (Hell)
|
||||||
|
system: Automatisch (mit System synchronisieren)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d. %b %Y, %H:%M Uhr"
|
default: "%d. %b %Y, %H:%M Uhr"
|
||||||
|
@ -1768,6 +1768,7 @@ es-AR:
|
|||||||
contrast: Alto contraste
|
contrast: Alto contraste
|
||||||
default: Oscuro
|
default: Oscuro
|
||||||
mastodon-light: Claro
|
mastodon-light: Claro
|
||||||
|
system: Automático (usar tema del sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y.%b.%d, %H:%M"
|
default: "%Y.%b.%d, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ es-MX:
|
|||||||
contrast: Alto contraste
|
contrast: Alto contraste
|
||||||
default: Mastodon
|
default: Mastodon
|
||||||
mastodon-light: Mastodon (claro)
|
mastodon-light: Mastodon (claro)
|
||||||
|
system: Automático (usar tema del sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d de %b del %Y, %H:%M"
|
default: "%d de %b del %Y, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ es:
|
|||||||
contrast: Alto contraste
|
contrast: Alto contraste
|
||||||
default: Mastodon
|
default: Mastodon
|
||||||
mastodon-light: Mastodon (claro)
|
mastodon-light: Mastodon (claro)
|
||||||
|
system: Automático (usar tema del sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d de %b del %Y, %H:%M"
|
default: "%d de %b del %Y, %H:%M"
|
||||||
|
@ -1772,6 +1772,7 @@ eu:
|
|||||||
contrast: Mastodon (Kontraste altua)
|
contrast: Mastodon (Kontraste altua)
|
||||||
default: Mastodon (Iluna)
|
default: Mastodon (Iluna)
|
||||||
mastodon-light: Mastodon (Argia)
|
mastodon-light: Mastodon (Argia)
|
||||||
|
system: Automatikoa (erabili sistemaren gaia)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y(e)ko %b %d, %H:%M"
|
default: "%Y(e)ko %b %d, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ fi:
|
|||||||
contrast: Mastodon (Korkea kontrasti)
|
contrast: Mastodon (Korkea kontrasti)
|
||||||
default: Mastodon (Tumma)
|
default: Mastodon (Tumma)
|
||||||
mastodon-light: Mastodon (Vaalea)
|
mastodon-light: Mastodon (Vaalea)
|
||||||
|
system: Automaattinen (käytä järjestelmän teemaa)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d.%m.%Y klo %H.%M"
|
default: "%d.%m.%Y klo %H.%M"
|
||||||
|
@ -1768,6 +1768,7 @@ fo:
|
|||||||
contrast: Mastodon (høgur kontrastur)
|
contrast: Mastodon (høgur kontrastur)
|
||||||
default: Mastodon (myrkt)
|
default: Mastodon (myrkt)
|
||||||
mastodon-light: Mastodon (ljóst)
|
mastodon-light: Mastodon (ljóst)
|
||||||
|
system: Sjálvvirkandi (brúka vanligt uppsetingareyðkenni)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%b %d, %Y, %H:%M"
|
default: "%b %d, %Y, %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ gl:
|
|||||||
contrast: Mastodon (Alto contraste)
|
contrast: Mastodon (Alto contraste)
|
||||||
default: Mastodon (Escuro)
|
default: Mastodon (Escuro)
|
||||||
mastodon-light: Mastodon (Claro)
|
mastodon-light: Mastodon (Claro)
|
||||||
|
system: Automático (seguir ao sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b, %Y, %H:%M"
|
default: "%d %b, %Y, %H:%M"
|
||||||
|
@ -1832,6 +1832,7 @@ he:
|
|||||||
contrast: מסטודון (ניגודיות גבוהה)
|
contrast: מסטודון (ניגודיות גבוהה)
|
||||||
default: מסטודון (כהה)
|
default: מסטודון (כהה)
|
||||||
mastodon-light: מסטודון (בהיר)
|
mastodon-light: מסטודון (בהיר)
|
||||||
|
system: אוטומטי (לפי המערכת)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b %Y, %H:%M"
|
default: "%d %b %Y, %H:%M"
|
||||||
|
@ -57,27 +57,27 @@ hu:
|
|||||||
deleted: Törölve
|
deleted: Törölve
|
||||||
demote: Lefokozás
|
demote: Lefokozás
|
||||||
destroyed_msg: A %{username} fiók adatai bekerültek a végleges törlése váró sorba
|
destroyed_msg: A %{username} fiók adatai bekerültek a végleges törlése váró sorba
|
||||||
disable: Kikapcsolás
|
disable: Befagyasztás
|
||||||
disable_sign_in_token_auth: Tokenes e-mail hitelesítés letiltása
|
disable_sign_in_token_auth: Tokenes e-mail-hitelesítés letiltása
|
||||||
disable_two_factor_authentication: Kétlépcsős hitelesítés kikapcsolása
|
disable_two_factor_authentication: Kétlépcsős hitelesítés kikapcsolása
|
||||||
disabled: Kikapcsolva
|
disabled: Befagyasztva
|
||||||
display_name: Megjelenített név
|
display_name: Megjelenítendő név
|
||||||
domain: Domain
|
domain: Domain
|
||||||
edit: Szerkesztés
|
edit: Szerkesztés
|
||||||
email: E-mail
|
email: E-mail-cím
|
||||||
email_status: E-mail állapot
|
email_status: E-mail állapot
|
||||||
enable: Bekapcsolás
|
enable: Kiolvasztás
|
||||||
enable_sign_in_token_auth: Tokenes e-mail hitelesítés engedélyezése
|
enable_sign_in_token_auth: Tokenes e-mail-hitelesítés engedélyezése
|
||||||
enabled: Bekapcsolva
|
enabled: Bekapcsolva
|
||||||
enabled_msg: A %{username} fiók fagyasztását sikeresen visszavontuk
|
enabled_msg: "%{username} fiókja befagyasztása sikeresen visszavonva"
|
||||||
followers: Követő
|
followers: Követő
|
||||||
follows: Követett
|
follows: Követett
|
||||||
header: Fejléc
|
header: Fejléc
|
||||||
inbox_url: Beérkezett üzenetek URL-je
|
inbox_url: Beérkezett üzenetek webcíme
|
||||||
invite_request_text: Csatlakozás oka
|
invite_request_text: Csatlakozás oka
|
||||||
invited_by: Meghívta
|
invited_by: Meghívta
|
||||||
ip: IP
|
ip: IP-cím
|
||||||
joined: Csatlakozott
|
joined: Csatlakozva
|
||||||
location:
|
location:
|
||||||
all: Összes
|
all: Összes
|
||||||
local: Helyi
|
local: Helyi
|
||||||
@ -1768,6 +1768,7 @@ hu:
|
|||||||
contrast: Mastodon (nagy kontrasztú)
|
contrast: Mastodon (nagy kontrasztú)
|
||||||
default: Mastodon (sötét)
|
default: Mastodon (sötét)
|
||||||
mastodon-light: Mastodon (világos)
|
mastodon-light: Mastodon (világos)
|
||||||
|
system: Automatikus (rendszertéma használata)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y. %b %d., %H:%M"
|
default: "%Y. %b %d., %H:%M"
|
||||||
|
@ -1772,6 +1772,7 @@ is:
|
|||||||
contrast: Mastodon (mikil birtuskil)
|
contrast: Mastodon (mikil birtuskil)
|
||||||
default: Mastodon (dökkt)
|
default: Mastodon (dökkt)
|
||||||
mastodon-light: Mastodon (ljóst)
|
mastodon-light: Mastodon (ljóst)
|
||||||
|
system: Sjálfvirkt (nota þema kerfis)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d. %b, %Y, %H:%M"
|
default: "%d. %b, %Y, %H:%M"
|
||||||
|
@ -1770,6 +1770,7 @@ it:
|
|||||||
contrast: Mastodon (contrasto elevato)
|
contrast: Mastodon (contrasto elevato)
|
||||||
default: Mastodon (scuro)
|
default: Mastodon (scuro)
|
||||||
mastodon-light: Mastodon (chiaro)
|
mastodon-light: Mastodon (chiaro)
|
||||||
|
system: Automatico (usa il tema di sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b %Y, %H:%M"
|
default: "%d %b %Y, %H:%M"
|
||||||
|
@ -391,6 +391,7 @@ kab:
|
|||||||
invites: Iɛeṛṛuḍen
|
invites: Iɛeṛṛuḍen
|
||||||
moderation: Aseɣyed
|
moderation: Aseɣyed
|
||||||
delete: Kkes
|
delete: Kkes
|
||||||
|
everyone: Tisirag timezwura
|
||||||
privileges:
|
privileges:
|
||||||
administrator: Anedbal
|
administrator: Anedbal
|
||||||
rules:
|
rules:
|
||||||
@ -441,6 +442,10 @@ kab:
|
|||||||
system_checks:
|
system_checks:
|
||||||
rules_check:
|
rules_check:
|
||||||
action: Sefrek ilugan n uqeddac
|
action: Sefrek ilugan n uqeddac
|
||||||
|
software_version_critical_check:
|
||||||
|
action: Wali ileqqman yellan
|
||||||
|
software_version_patch_check:
|
||||||
|
action: Wali ileqqman yellan
|
||||||
title: Tadbelt
|
title: Tadbelt
|
||||||
trends:
|
trends:
|
||||||
allow: Sireg
|
allow: Sireg
|
||||||
@ -602,6 +607,8 @@ kab:
|
|||||||
notifications: Ilɣa
|
notifications: Ilɣa
|
||||||
thread: Idiwenniyen
|
thread: Idiwenniyen
|
||||||
edit:
|
edit:
|
||||||
|
add_keyword: Rnu awal tasarut
|
||||||
|
keywords: Awalen n tsarut
|
||||||
title: Ẓreg amzizdig
|
title: Ẓreg amzizdig
|
||||||
index:
|
index:
|
||||||
delete: Kkes
|
delete: Kkes
|
||||||
@ -640,6 +647,7 @@ kab:
|
|||||||
blocking: Tabdart n yimiḍanen iweḥlen
|
blocking: Tabdart n yimiḍanen iweḥlen
|
||||||
bookmarks: Ticraḍ
|
bookmarks: Ticraḍ
|
||||||
following: Tabdert n wid teṭṭafareḍ
|
following: Tabdert n wid teṭṭafareḍ
|
||||||
|
lists: Tibdarin
|
||||||
muting: Tabdert n wid tesgugmeḍ
|
muting: Tabdert n wid tesgugmeḍ
|
||||||
upload: Sali
|
upload: Sali
|
||||||
invites:
|
invites:
|
||||||
@ -750,6 +758,7 @@ kab:
|
|||||||
phantom_js: PhantomJS
|
phantom_js: PhantomJS
|
||||||
qq: Iminig QQ
|
qq: Iminig QQ
|
||||||
safari: Safari
|
safari: Safari
|
||||||
|
unknown_browser: Iminig arussin
|
||||||
weibo: Weibo
|
weibo: Weibo
|
||||||
current_session: Tiɣimit tamirant
|
current_session: Tiɣimit tamirant
|
||||||
date: Azemz
|
date: Azemz
|
||||||
|
@ -1738,6 +1738,7 @@ ko:
|
|||||||
contrast: 마스토돈 (고대비)
|
contrast: 마스토돈 (고대비)
|
||||||
default: 마스토돈 (어두움)
|
default: 마스토돈 (어두움)
|
||||||
mastodon-light: 마스토돈 (밝음)
|
mastodon-light: 마스토돈 (밝음)
|
||||||
|
system: 자동 선택 (시스템 테마 이용)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y-%m-%d %H:%M"
|
default: "%Y-%m-%d %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ nl:
|
|||||||
contrast: Mastodon (hoog contrast)
|
contrast: Mastodon (hoog contrast)
|
||||||
default: Mastodon (donker)
|
default: Mastodon (donker)
|
||||||
mastodon-light: Mastodon (licht)
|
mastodon-light: Mastodon (licht)
|
||||||
|
system: Automatisch (systeemthema gebruiken)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %B %Y om %H:%M"
|
default: "%d %B %Y om %H:%M"
|
||||||
|
@ -1768,6 +1768,7 @@ nn:
|
|||||||
contrast: Mastodon (Høg kontrast)
|
contrast: Mastodon (Høg kontrast)
|
||||||
default: Mastodon (Mørkt)
|
default: Mastodon (Mørkt)
|
||||||
mastodon-light: Mastodon (Lyst)
|
mastodon-light: Mastodon (Lyst)
|
||||||
|
system: Automatisk (bruk systemdrakta)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d.%b %Y, %H:%M"
|
default: "%d.%b %Y, %H:%M"
|
||||||
|
@ -1832,6 +1832,7 @@ pl:
|
|||||||
contrast: Mastodon (Wysoki kontrast)
|
contrast: Mastodon (Wysoki kontrast)
|
||||||
default: Mastodon (Ciemny)
|
default: Mastodon (Ciemny)
|
||||||
mastodon-light: Mastodon (Jasny)
|
mastodon-light: Mastodon (Jasny)
|
||||||
|
system: Automatyczny (odpowiadający motywowi systemu)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d. %b %Y, %H:%M"
|
default: "%d. %b %Y, %H:%M"
|
||||||
|
@ -597,6 +597,9 @@ pt-BR:
|
|||||||
actions_description_html: Decida que medidas tomar para resolver esta denúncia. Se você decidir punir a conta denunciada, ela receberá uma notificação por e-mail, exceto quando for selecionada a categoria <strong>spam</strong> for selecionada.
|
actions_description_html: Decida que medidas tomar para resolver esta denúncia. Se você decidir punir a conta denunciada, ela receberá uma notificação por e-mail, exceto quando for selecionada a categoria <strong>spam</strong> for selecionada.
|
||||||
actions_description_remote_html: Decida quais medidas tomará para resolver esta denúncia. Isso só afetará como <strong>seu servidor</strong> se comunica com esta conta remota e manipula seu conteúdo.
|
actions_description_remote_html: Decida quais medidas tomará para resolver esta denúncia. Isso só afetará como <strong>seu servidor</strong> se comunica com esta conta remota e manipula seu conteúdo.
|
||||||
add_to_report: Adicionar mais à denúncia
|
add_to_report: Adicionar mais à denúncia
|
||||||
|
already_suspended_badges:
|
||||||
|
local: Já suspenso neste servidor
|
||||||
|
remote: Já suspenso em seu servidor
|
||||||
are_you_sure: Você tem certeza?
|
are_you_sure: Você tem certeza?
|
||||||
assign_to_self: Atribuir para si
|
assign_to_self: Atribuir para si
|
||||||
assigned: Moderador responsável
|
assigned: Moderador responsável
|
||||||
@ -1652,13 +1655,20 @@ pt-BR:
|
|||||||
import: Importar
|
import: Importar
|
||||||
import_and_export: Importar e exportar
|
import_and_export: Importar e exportar
|
||||||
migrate: Migração de conta
|
migrate: Migração de conta
|
||||||
|
notifications: Notificações por e-mail
|
||||||
preferences: Preferências
|
preferences: Preferências
|
||||||
profile: Perfil
|
profile: Perfil
|
||||||
relationships: Seguindo e seguidores
|
relationships: Seguindo e seguidores
|
||||||
|
severed_relationships: Relacionamentos rompidos
|
||||||
statuses_cleanup: Exclusão automatizada de publicações
|
statuses_cleanup: Exclusão automatizada de publicações
|
||||||
strikes: Avisos de moderação
|
strikes: Avisos de moderação
|
||||||
two_factor_authentication: Autenticação de dois fatores
|
two_factor_authentication: Autenticação de dois fatores
|
||||||
webauthn_authentication: Chaves de segurança
|
webauthn_authentication: Chaves de segurança
|
||||||
|
severed_relationships:
|
||||||
|
download: Download %{count}
|
||||||
|
event_type:
|
||||||
|
account_suspension: Suspensão da conta (%{target_name})
|
||||||
|
domain_block: Suspensão do servidor (%{target_name})
|
||||||
statuses:
|
statuses:
|
||||||
attached:
|
attached:
|
||||||
audio:
|
audio:
|
||||||
|
@ -1768,6 +1768,7 @@ pt-PT:
|
|||||||
contrast: Mastodon (Elevado contraste)
|
contrast: Mastodon (Elevado contraste)
|
||||||
default: Mastodon (Escuro)
|
default: Mastodon (Escuro)
|
||||||
mastodon-light: Mastodon (Claro)
|
mastodon-light: Mastodon (Claro)
|
||||||
|
system: Automático (usar tema do sistema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%H:%M em %d de %b de %Y"
|
default: "%H:%M em %d de %b de %Y"
|
||||||
|
@ -1899,6 +1899,7 @@ ru:
|
|||||||
suspend: Учётная запись заблокирована
|
suspend: Учётная запись заблокирована
|
||||||
welcome:
|
welcome:
|
||||||
explanation: Вот несколько советов для новичков
|
explanation: Вот несколько советов для новичков
|
||||||
|
feature_action: Подробнее
|
||||||
subject: Добро пожаловать в Mastodon
|
subject: Добро пожаловать в Mastodon
|
||||||
title: Добро пожаловать на борт, %{name}!
|
title: Добро пожаловать на борт, %{name}!
|
||||||
users:
|
users:
|
||||||
|
@ -74,8 +74,8 @@ kab:
|
|||||||
setting_default_language: Tutlayt n tira
|
setting_default_language: Tutlayt n tira
|
||||||
setting_default_privacy: Tabaḍnit n tira
|
setting_default_privacy: Tabaḍnit n tira
|
||||||
setting_display_media_default: Akk-a kan
|
setting_display_media_default: Akk-a kan
|
||||||
setting_display_media_hide_all: Ffer kullec
|
setting_display_media_hide_all: Ffer-iten akk
|
||||||
setting_display_media_show_all: Ssken kullec
|
setting_display_media_show_all: Sken-iten-id akk
|
||||||
setting_hide_network: Ffer azetta-k·m
|
setting_hide_network: Ffer azetta-k·m
|
||||||
setting_theme: Asental n wesmel
|
setting_theme: Asental n wesmel
|
||||||
setting_use_pending_items: Askar aleɣwayan
|
setting_use_pending_items: Askar aleɣwayan
|
||||||
@ -115,6 +115,8 @@ kab:
|
|||||||
text: Alugen
|
text: Alugen
|
||||||
tag:
|
tag:
|
||||||
name: Ahacṭag
|
name: Ahacṭag
|
||||||
|
user:
|
||||||
|
time_zone: Tamnaḍt tasragant
|
||||||
user_role:
|
user_role:
|
||||||
name: Isem
|
name: Isem
|
||||||
permissions_as_keys: Tisirag
|
permissions_as_keys: Tisirag
|
||||||
|
@ -1832,6 +1832,7 @@ sl:
|
|||||||
contrast: Mastodon (Visok kontrast)
|
contrast: Mastodon (Visok kontrast)
|
||||||
default: Mastodon (Temna)
|
default: Mastodon (Temna)
|
||||||
mastodon-light: Mastodon (Svetla)
|
mastodon-light: Mastodon (Svetla)
|
||||||
|
system: Samodejno (uporabi sistemsko temo)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%b %d %Y, %H:%M"
|
default: "%b %d %Y, %H:%M"
|
||||||
|
@ -1762,6 +1762,7 @@ sq:
|
|||||||
contrast: Mastodon (Me shumë kontrast)
|
contrast: Mastodon (Me shumë kontrast)
|
||||||
default: Mastodon (I errët)
|
default: Mastodon (I errët)
|
||||||
mastodon-light: Mastodon (I çelët)
|
mastodon-light: Mastodon (I çelët)
|
||||||
|
system: E automatizuar (përdor temë sistemi)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b, %Y, %H:%M"
|
default: "%d %b, %Y, %H:%M"
|
||||||
|
@ -1756,6 +1756,7 @@ sv:
|
|||||||
contrast: Hög kontrast
|
contrast: Hög kontrast
|
||||||
default: Mastodon
|
default: Mastodon
|
||||||
mastodon-light: Mastodon (ljust)
|
mastodon-light: Mastodon (ljust)
|
||||||
|
system: Automatisk (använd systemtema)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b %Y, %H:%M"
|
default: "%d %b %Y, %H:%M"
|
||||||
|
@ -1646,6 +1646,7 @@ th:
|
|||||||
user_domain_block: คุณได้ปิดกั้น %{target_name}
|
user_domain_block: คุณได้ปิดกั้น %{target_name}
|
||||||
lost_followers: ผู้ติดตามที่หายไป
|
lost_followers: ผู้ติดตามที่หายไป
|
||||||
lost_follows: การติดตามที่หายไป
|
lost_follows: การติดตามที่หายไป
|
||||||
|
preamble: คุณอาจสูญเสียการติดตามและผู้ติดตามเมื่อคุณปิดกั้นโดเมนหรือเมื่อผู้กลั่นกรองของคุณตัดสินใจที่จะระงับเซิร์ฟเวอร์ระยะไกล เมื่อสิ่งนั้นเกิดขึ้น คุณจะสามารถดาวน์โหลดรายการความสัมพันธ์ที่ตัดขาด เพื่อตรวจสอบและอาจนำเข้าในเซิร์ฟเวอร์อื่น
|
||||||
purged: มีการล้างข้อมูลเกี่ยวกับเซิร์ฟเวอร์นี้โดยผู้ดูแลของเซิร์ฟเวอร์ของคุณ
|
purged: มีการล้างข้อมูลเกี่ยวกับเซิร์ฟเวอร์นี้โดยผู้ดูแลของเซิร์ฟเวอร์ของคุณ
|
||||||
type: เหตุการณ์
|
type: เหตุการณ์
|
||||||
statuses:
|
statuses:
|
||||||
@ -1735,6 +1736,7 @@ th:
|
|||||||
contrast: Mastodon (ความคมชัดสูง)
|
contrast: Mastodon (ความคมชัดสูง)
|
||||||
default: Mastodon (มืด)
|
default: Mastodon (มืด)
|
||||||
mastodon-light: Mastodon (สว่าง)
|
mastodon-light: Mastodon (สว่าง)
|
||||||
|
system: อัตโนมัติ (ใช้ชุดรูปแบบของระบบ)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b %Y %H:%M น."
|
default: "%d %b %Y %H:%M น."
|
||||||
|
@ -1768,6 +1768,7 @@ tr:
|
|||||||
contrast: Mastodon (Yüksek karşıtlık)
|
contrast: Mastodon (Yüksek karşıtlık)
|
||||||
default: Mastodon (Karanlık)
|
default: Mastodon (Karanlık)
|
||||||
mastodon-light: Mastodon (Açık)
|
mastodon-light: Mastodon (Açık)
|
||||||
|
system: Otomatik (sistem temasını kullan)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%d %b %Y %H:%M"
|
default: "%d %b %Y %H:%M"
|
||||||
|
@ -1832,6 +1832,7 @@ uk:
|
|||||||
contrast: Mastodon (Висока контрастність)
|
contrast: Mastodon (Висока контрастність)
|
||||||
default: Mastodon (Темна)
|
default: Mastodon (Темна)
|
||||||
mastodon-light: Mastodon (світла)
|
mastodon-light: Mastodon (світла)
|
||||||
|
system: Автоматично (використовувати системну тему)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%b %d, %Y, %H:%M"
|
default: "%b %d, %Y, %H:%M"
|
||||||
|
@ -1736,6 +1736,7 @@ vi:
|
|||||||
contrast: Mastodon (Tương phản)
|
contrast: Mastodon (Tương phản)
|
||||||
default: Mastodon (Tối)
|
default: Mastodon (Tối)
|
||||||
mastodon-light: Mastodon (Sáng)
|
mastodon-light: Mastodon (Sáng)
|
||||||
|
system: Tự động (chủ đề hệ thống)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%-d.%m.%Y %H:%M"
|
default: "%-d.%m.%Y %H:%M"
|
||||||
|
@ -1736,6 +1736,7 @@ zh-CN:
|
|||||||
contrast: Mastodon(高对比度)
|
contrast: Mastodon(高对比度)
|
||||||
default: Mastodon(暗色主题)
|
default: Mastodon(暗色主题)
|
||||||
mastodon-light: Mastodon(亮色主题)
|
mastodon-light: Mastodon(亮色主题)
|
||||||
|
system: 自动切换(使用系统主题)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y年%m月%d日 %H:%M"
|
default: "%Y年%m月%d日 %H:%M"
|
||||||
|
@ -1738,6 +1738,7 @@ zh-TW:
|
|||||||
contrast: Mastodon(高對比)
|
contrast: Mastodon(高對比)
|
||||||
default: Mastodon(深色)
|
default: Mastodon(深色)
|
||||||
mastodon-light: Mastodon(亮色)
|
mastodon-light: Mastodon(亮色)
|
||||||
|
system: 自動(使用系統佈景主題)
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%Y 年 %b 月 %d 日 %H:%M"
|
default: "%Y 年 %b 月 %d 日 %H:%M"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user