Merge branch 'glitch-soc' into develop

This commit is contained in:
Jeremy Kescher 2024-02-28 23:01:31 +01:00
commit de1e89f42c
No known key found for this signature in database
GPG key ID: 80A419A7A613DFA4
196 changed files with 1314 additions and 1454 deletions

View file

@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": { "features": {
"ghcr.io/devcontainers/features/sshd:1": {}, "ghcr.io/devcontainers/features/sshd:1": {}
}, },
"runServices": ["app", "db", "redis"], "runServices": ["app", "db", "redis"],
@ -15,16 +15,16 @@
"portsAttributes": { "portsAttributes": {
"3000": { "3000": {
"label": "web", "label": "web",
"onAutoForward": "notify", "onAutoForward": "notify"
}, },
"4000": { "4000": {
"label": "stream", "label": "stream",
"onAutoForward": "silent", "onAutoForward": "silent"
}, }
}, },
"otherPortsAttributes": { "otherPortsAttributes": {
"onAutoForward": "silent", "onAutoForward": "silent"
}, },
"remoteEnv": { "remoteEnv": {
@ -33,7 +33,7 @@
"STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev", "STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev",
"DISABLE_FORGERY_REQUEST_PROTECTION": "true", "DISABLE_FORGERY_REQUEST_PROTECTION": "true",
"ES_ENABLED": "", "ES_ENABLED": "",
"LIBRE_TRANSLATE_ENDPOINT": "", "LIBRE_TRANSLATE_ENDPOINT": ""
}, },
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@ -43,7 +43,7 @@
"customizations": { "customizations": {
"vscode": { "vscode": {
"settings": {}, "settings": {},
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"], "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}, }
}, }
} }

View file

@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": { "features": {
"ghcr.io/devcontainers/features/sshd:1": {}, "ghcr.io/devcontainers/features/sshd:1": {}
}, },
"forwardPorts": [3000, 4000], "forwardPorts": [3000, 4000],
@ -14,17 +14,17 @@
"3000": { "3000": {
"label": "web", "label": "web",
"onAutoForward": "notify", "onAutoForward": "notify",
"requireLocalPort": true, "requireLocalPort": true
}, },
"4000": { "4000": {
"label": "stream", "label": "stream",
"onAutoForward": "silent", "onAutoForward": "silent",
"requireLocalPort": true, "requireLocalPort": true
}, }
}, },
"otherPortsAttributes": { "otherPortsAttributes": {
"onAutoForward": "silent", "onAutoForward": "silent"
}, },
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@ -34,7 +34,7 @@
"customizations": { "customizations": {
"vscode": { "vscode": {
"settings": {}, "settings": {},
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"], "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}, }
}, }
} }

View file

@ -355,7 +355,6 @@ module.exports = defineConfig({
'plugin:import/typescript', 'plugin:import/typescript',
'plugin:promise/recommended', 'plugin:promise/recommended',
'plugin:jsdoc/recommended-typescript', 'plugin:jsdoc/recommended-typescript',
'plugin:prettier/recommended',
], ],
parserOptions: { parserOptions: {
@ -364,6 +363,9 @@ module.exports = defineConfig({
}, },
rules: { rules: {
// Disable formatting rules that have been enabled in the base config
'indent': 'off',
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],

18
.github/workflows/format-check.yml vendored Normal file
View file

@ -0,0 +1,18 @@
name: Check formatting
on:
push:
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Check formatting with Prettier
run: yarn format:check

View file

@ -43,4 +43,4 @@ jobs:
- run: echo "::add-matcher::.github/stylelint-matcher.json" - run: echo "::add-matcher::.github/stylelint-matcher.json"
- name: Stylelint - name: Stylelint
run: yarn lint:sass run: yarn lint:css

View file

@ -36,4 +36,4 @@ jobs:
- name: Run haml-lint - name: Run haml-lint
run: | run: |
echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json" echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json"
bundle exec haml-lint bundle exec haml-lint --reporter github

View file

@ -1,38 +0,0 @@
name: JSON Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.json'
- '.github/workflows/lint-json.yml'
- '!app/javascript/mastodon/locales/*.json'
pull_request:
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.json'
- '.github/workflows/lint-json.yml'
- '!app/javascript/mastodon/locales/*.json'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:json

View file

@ -1,38 +0,0 @@
name: Markdown Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- '.github/workflows/lint-md.yml'
- '.nvmrc'
- '.prettier*'
- '**/*.md'
- '!AUTHORS.md'
- 'package.json'
- 'yarn.lock'
pull_request:
paths:
- '.github/workflows/lint-md.yml'
- '.nvmrc'
- '.prettier*'
- '**/*.md'
- '!AUTHORS.md'
- 'package.json'
- 'yarn.lock'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:md

View file

@ -1,40 +0,0 @@
name: YML Linting
on:
push:
branches-ignore:
- 'dependabot/**'
- 'renovate/**'
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.yaml'
- '**/*.yml'
- '.github/workflows/lint-yml.yml'
- '!config/locales/*.yml'
pull_request:
paths:
- 'package.json'
- 'yarn.lock'
- '.nvmrc'
- '.prettier*'
- '**/*.yaml'
- '**/*.yml'
- '.github/workflows/lint-yml.yml'
- '!config/locales/*.yml'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:yml

View file

@ -54,6 +54,13 @@
# Ignore Docker option files # Ignore Docker option files
docker-compose.override.yml docker-compose.override.yml
# Ignore public
/public/assets
/public/emoji
/public/packs
/public/packs-test
/public/system
# Ignore emoji map file # Ignore emoji map file
/app/javascript/mastodon/features/emoji/emoji_map.json /app/javascript/mastodon/features/emoji/emoji_map.json
@ -74,6 +81,7 @@ app/javascript/styles/mastodon/reset.scss
# Ignore the generated AUTHORS.md # Ignore the generated AUTHORS.md
AUTHORS.md AUTHORS.md
# Process a few selected JS files
!lint-staged.config.js !lint-staged.config.js
# Ignore glitch-soc emoji map file # Ignore glitch-soc emoji map file

View file

@ -333,7 +333,7 @@ GEM
http-form_data (2.3.0) http-form_data (2.3.0)
http_accept_language (2.1.1) http_accept_language (2.1.1)
httpclient (2.8.3) httpclient (2.8.3)
httplog (1.6.2) httplog (1.6.3)
rack (>= 2.0) rack (>= 2.0)
rainbow (>= 2.0.0) rainbow (>= 2.0.0)
i18n (1.14.1) i18n (1.14.1)
@ -744,7 +744,7 @@ GEM
terrapin (1.0.1) terrapin (1.0.1)
climate_control climate_control
test-prof (1.3.1) test-prof (1.3.1)
thor (1.3.0) thor (1.3.1)
tilt (2.3.0) tilt (2.3.0)
timeout (0.4.1) timeout (0.4.1)
tpm-key_attestation (0.12.0) tpm-key_attestation (0.12.0)

View file

@ -180,7 +180,7 @@ class ApplicationController < ActionController::Base
use_pack 'error' use_pack 'error'
render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html] render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html]
end end
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: code } format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 }
end end
end end

View file

@ -45,7 +45,7 @@ const hideSelectAll = () => {
Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => { Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => {
const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
[].forEach.call(document.querySelectorAll(batchCheckboxClassName), (content) => { document.querySelectorAll(batchCheckboxClassName).forEach((content) => {
content.checked = target.checked; content.checked = target.checked;
}); });
@ -80,8 +80,11 @@ Rails.delegate(document, batchCheckboxClassName, 'change', () => {
const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
if (checkAllElement) { if (checkAllElement) {
checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); const allCheckboxes = Array.from(
checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); document.querySelectorAll(batchCheckboxClassName)
);
checkAllElement.checked = allCheckboxes.every((content) => content.checked);
checkAllElement.indeterminate = !checkAllElement.checked && allCheckboxes.some((content) => content.checked);
if (selectAllMatchingElement) { if (selectAllMatchingElement) {
if (checkAllElement.checked) { if (checkAllElement.checked) {
@ -93,18 +96,6 @@ Rails.delegate(document, batchCheckboxClassName, 'change', () => {
} }
}); });
Rails.delegate(document, '.media-spoiler-show-button', 'click', () => {
[].forEach.call(document.querySelectorAll('button.media-spoiler'), (element) => {
element.click();
});
});
Rails.delegate(document, '.media-spoiler-hide-button', 'click', () => {
[].forEach.call(document.querySelectorAll('.spoiler-button.spoiler-button--visible button'), (element) => {
element.click();
});
});
Rails.delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => { Rails.delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => {
target.form.submit(); target.form.submit();
}); });
@ -144,11 +135,11 @@ Rails.delegate(document, '#form_admin_settings_enable_bootstrap_timeline_account
const onChangeRegistrationMode = (target) => { const onChangeRegistrationMode = (target) => {
const enabled = target.value === 'approved'; const enabled = target.value === 'approved';
[].forEach.call(document.querySelectorAll('.form_admin_settings_registrations_mode .warning-hint'), (warning_hint) => { document.querySelectorAll('.form_admin_settings_registrations_mode .warning-hint').forEach((warning_hint) => {
warning_hint.style.display = target.value === 'open' ? 'inline' : 'none'; warning_hint.style.display = target.value === 'open' ? 'inline' : 'none';
}); });
[].forEach.call(document.querySelectorAll('#form_admin_settings_require_invite_text'), (input) => { document.querySelectorAll('#form_admin_settings_require_invite_text').forEach((input) => {
input.disabled = !enabled; input.disabled = !enabled;
if (enabled) { if (enabled) {
let element = input; let element = input;
@ -194,8 +185,9 @@ ready(() => {
const checkAllElement = document.querySelector('#batch_checkbox_all'); const checkAllElement = document.querySelector('#batch_checkbox_all');
if (checkAllElement) { if (checkAllElement) {
checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); const allCheckboxes = Array.from(document.querySelectorAll(batchCheckboxClassName));
checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); checkAllElement.checked = allCheckboxes.every( (content) => content.checked);
checkAllElement.indeterminate = !checkAllElement.checked && allCheckboxes.some((content) => content.checked);
} }
document.querySelector('a#add-instance-button')?.addEventListener('click', (e) => { document.querySelector('a#add-instance-button')?.addEventListener('click', (e) => {
@ -208,7 +200,7 @@ ready(() => {
} }
}); });
[].forEach.call(document.querySelectorAll('input[type="datetime-local"]'), element => { document.querySelectorAll('input[type="datetime-local"]').forEach(element => {
if (element.value) { if (element.value) {
element.value = convertUTCDateTimeToLocal(element.value); element.value = convertUTCDateTimeToLocal(element.value);
} }
@ -218,7 +210,7 @@ ready(() => {
}); });
Rails.delegate(document, 'form', 'submit', ({ target }) => { Rails.delegate(document, 'form', 'submit', ({ target }) => {
[].forEach.call(target.querySelectorAll('input[type="datetime-local"]'), element => { target.querySelectorAll('input[type="datetime-local"]').forEach(element => {
if (element.value && element.validity.valid) { if (element.value && element.validity.valid) {
element.value = convertLocalDatetimeToUTC(element.value); element.value = convertLocalDatetimeToUTC(element.value);
} }

View file

@ -80,7 +80,7 @@ export default class MediaContainer extends PureComponent {
return ( return (
<IntlProvider> <IntlProvider>
<> <>
{[].map.call(components, (component, i) => { {Array.from(components).map((component, i) => {
const componentName = component.getAttribute('data-component'); const componentName = component.getAttribute('data-component');
const Component = MEDIA_COMPONENTS[componentName]; const Component = MEDIA_COMPONENTS[componentName];
const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props')); const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props'));

View file

@ -5,7 +5,7 @@ import Overlay from 'react-overlays/Overlay';
import { IconButton } from 'flavours/glitch/components/icon_button'; import { IconButton } from 'flavours/glitch/components/icon_button';
import DropdownMenu from './dropdown_menu'; import { PrivacyDropdownMenu } from './privacy_dropdown_menu';
export const DropdownIconButton = ({ value, disabled, icon, onChange, iconComponent, title, options }) => { export const DropdownIconButton = ({ value, disabled, icon, onChange, iconComponent, title, options }) => {
const containerRef = useRef(null); const containerRef = useRef(null);
@ -53,7 +53,7 @@ export const DropdownIconButton = ({ value, disabled, icon, onChange, iconCompon
{({ props, placement }) => ( {({ props, placement }) => (
<div {...props}> <div {...props}>
<div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}> <div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>
<DropdownMenu <PrivacyDropdownMenu
items={options} items={options}
value={value} value={value}
onClose={handleClose} onClose={handleClose}

View file

@ -1,125 +0,0 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import { Icon } from 'flavours/glitch/components/icon';
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
// copied from PrivacyDropdown; will require refactor with upstream down the line
class DropdownMenu extends PureComponent {
static propTypes = {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};
handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) {
this.props.onClose();
e.stopPropagation();
}
};
handleKeyDown = e => {
const { items } = this.props;
const value = e.currentTarget.getAttribute('data-index');
const index = items.findIndex(item => {
return (item.value === value);
});
let element = null;
switch(e.key) {
case 'Escape':
this.props.onClose();
break;
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.node.childNodes[index + 1] || this.node.firstChild;
break;
case 'ArrowUp':
element = this.node.childNodes[index - 1] || this.node.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.node.childNodes[index - 1] || this.node.lastChild;
} else {
element = this.node.childNodes[index + 1] || this.node.firstChild;
}
break;
case 'Home':
element = this.node.firstChild;
break;
case 'End':
element = this.node.lastChild;
break;
}
if (element) {
element.focus();
this.props.onChange(element.getAttribute('data-index'));
e.preventDefault();
e.stopPropagation();
}
};
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
this.props.onClose();
this.props.onChange(value);
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
}
setRef = c => {
this.node = c;
};
setFocusRef = c => {
this.focusedItem = c;
};
render () {
const { style, items, value } = this.props;
return (
<div style={{ ...style }} role='listbox' ref={this.setRef}>
{items.map(item => (
<div role='option' tabIndex={0} key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} icon={item.iconComponent} />
</div>
<div className='privacy-dropdown__option__content'>
<strong>{item.text}</strong>
{item.meta}
</div>
</div>
))}
</div>
);
}
}
export default DropdownMenu;

View file

@ -141,6 +141,7 @@ class LanguageDropdownMenu extends PureComponent {
case 'Escape': case 'Escape':
onClose(); onClose();
break; break;
case ' ':
case 'Enter': case 'Enter':
this.handleClick(e); this.handleClick(e);
break; break;

View file

@ -5,16 +5,16 @@ import { injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
import { Icon } from 'flavours/glitch/components/icon'; import { Icon } from 'flavours/glitch/components/icon';
import { PrivacyDropdownMenu } from './privacy_dropdown_menu';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' }, public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' },
@ -28,126 +28,6 @@ const messages = defineMessages({
unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' }, unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' },
}); });
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
class PrivacyDropdownMenu extends PureComponent {
static propTypes = {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};
handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) {
this.props.onClose();
e.stopPropagation();
}
};
handleKeyDown = e => {
const { items } = this.props;
const value = e.currentTarget.getAttribute('data-index');
const index = items.findIndex(item => {
return (item.value === value);
});
let element = null;
switch(e.key) {
case 'Escape':
this.props.onClose();
break;
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.node.childNodes[index + 1] || this.node.firstChild;
break;
case 'ArrowUp':
element = this.node.childNodes[index - 1] || this.node.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.node.childNodes[index - 1] || this.node.lastChild;
} else {
element = this.node.childNodes[index + 1] || this.node.firstChild;
}
break;
case 'Home':
element = this.node.firstChild;
break;
case 'End':
element = this.node.lastChild;
break;
}
if (element) {
element.focus();
this.props.onChange(element.getAttribute('data-index'));
e.preventDefault();
e.stopPropagation();
}
};
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
this.props.onClose();
this.props.onChange(value);
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
}
setRef = c => {
this.node = c;
};
setFocusRef = c => {
this.focusedItem = c;
};
render () {
const { style, items, value } = this.props;
return (
<div style={{ ...style }} role='listbox' ref={this.setRef}>
{items.map(item => (
<div role='option' tabIndex={0} key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} icon={item.iconComponent} />
</div>
<div className='privacy-dropdown__option__content'>
<strong>{item.text}</strong>
{item.meta}
</div>
{item.extra && (
<div className='privacy-dropdown__option__additional' title={item.extra}>
<Icon id='info-circle' icon={InfoIcon} />
</div>
)}
</div>
))}
</div>
);
}
}
class PrivacyDropdown extends PureComponent { class PrivacyDropdown extends PureComponent {
static propTypes = { static propTypes = {

View file

@ -0,0 +1,128 @@
import PropTypes from 'prop-types';
import { useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
export const PrivacyDropdownMenu = ({ style, items, value, onClose, onChange }) => {
const nodeRef = useRef(null);
const focusedItemRef = useRef(null);
const [currentValue, setCurrentValue] = useState(value);
const handleDocumentClick = useCallback((e) => {
if (nodeRef.current && !nodeRef.current.contains(e.target)) {
onClose();
e.stopPropagation();
}
}, [nodeRef, onClose]);
const handleClick = useCallback((e) => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
onClose();
onChange(value);
}, [onClose, onChange]);
const handleKeyDown = useCallback((e) => {
const value = e.currentTarget.getAttribute('data-index');
const index = items.findIndex(item => (item.value === value));
let element = null;
switch (e.key) {
case 'Escape':
onClose();
break;
case ' ':
case 'Enter':
handleClick(e);
break;
case 'ArrowDown':
element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild;
break;
case 'ArrowUp':
element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild;
} else {
element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild;
}
break;
case 'Home':
element = nodeRef.current.firstChild;
break;
case 'End':
element = nodeRef.current.lastChild;
break;
}
if (element) {
element.focus();
setCurrentValue(element.getAttribute('data-index'));
e.preventDefault();
e.stopPropagation();
}
}, [nodeRef, items, onClose, handleClick, setCurrentValue]);
useEffect(() => {
document.addEventListener('click', handleDocumentClick, { capture: true });
document.addEventListener('touchend', handleDocumentClick, listenerOptions);
focusedItemRef.current?.focus({ preventScroll: true });
return () => {
document.removeEventListener('click', handleDocumentClick, { capture: true });
document.removeEventListener('touchend', handleDocumentClick, listenerOptions);
};
}, [handleDocumentClick]);
return (
<ul style={{ ...style }} role='listbox' ref={nodeRef}>
{items.map(item => (
<li
role='option'
tabIndex={0}
key={item.value}
data-index={item.value}
onKeyDown={handleKeyDown}
onClick={handleClick}
className={classNames('privacy-dropdown__option', { active: item.value === currentValue })}
aria-selected={item.value === currentValue}
ref={item.value === currentValue ? focusedItemRef : null}
>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} icon={item.iconComponent} />
</div>
<div className='privacy-dropdown__option__content'>
<strong>{item.text}</strong>
{item.meta}
</div>
{item.extra && (
<div className='privacy-dropdown__option__additional' title={item.extra}>
<Icon id='info-circle' icon={InfoIcon} />
</div>
)}
</li>
))}
</ul>
);
};
PrivacyDropdownMenu.propTypes = {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};

View file

@ -8,8 +8,8 @@ import { IconButton } from 'flavours/glitch/components/icon_button';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store'; import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
const messages = defineMessages({ const messages = defineMessages({
enable_threaded_mode: { id: 'compose.enable_threaded_mode', defaultMessage: 'Enable threaded more' }, enable_threaded_mode: { id: 'compose.enable_threaded_mode', defaultMessage: 'Enable threaded mode' },
disable_threaded_mode: { id: 'compose.disable_threaded_mode', defaultMessage: 'Disable threaded more' }, disable_threaded_mode: { id: 'compose.disable_threaded_mode', defaultMessage: 'Disable threaded mode' },
}); });
export const ThreadModeButton = () => { export const ThreadModeButton = () => {

View file

@ -7,10 +7,14 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PhotoLibraryIcon from '@/material-icons/400-20px/photo_library.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-20px/photo_library.svg?react';
import { IconButton } from 'flavours/glitch/components/icon_button'; import BrushIcon from '@/material-icons/400-24px/brush.svg?react';
import UploadFileIcon from '@/material-icons/400-24px/upload_file.svg?react';
import { DropdownIconButton } from './dropdown_icon_button';
const messages = defineMessages({ const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add images, a video or an audio file' }, upload: { id: 'upload_button.label', defaultMessage: 'Add images, a video or an audio file' },
doodle: { id: 'compose.attach.doodle', defaultMessage: 'Draw something' },
}); });
const makeMapStateToProps = () => { const makeMapStateToProps = () => {
@ -21,16 +25,12 @@ const makeMapStateToProps = () => {
return mapStateToProps; return mapStateToProps;
}; };
const iconStyle = {
height: null,
lineHeight: '27px',
};
class UploadButton extends ImmutablePureComponent { class UploadButton extends ImmutablePureComponent {
static propTypes = { static propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,
onSelectFile: PropTypes.func.isRequired, onSelectFile: PropTypes.func.isRequired,
onDoodleOpen: PropTypes.func.isRequired,
style: PropTypes.object, style: PropTypes.object,
resetFileKey: PropTypes.number, resetFileKey: PropTypes.number,
acceptContentTypes: ImmutablePropTypes.listOf(PropTypes.string).isRequired, acceptContentTypes: ImmutablePropTypes.listOf(PropTypes.string).isRequired,
@ -43,8 +43,12 @@ class UploadButton extends ImmutablePureComponent {
} }
}; };
handleClick = () => { handleSelect = (value) => {
if (value === 'upload') {
this.fileElement.click(); this.fileElement.click();
} else {
this.props.onDoodleOpen();
}
}; };
setRef = (c) => { setRef = (c) => {
@ -56,9 +60,32 @@ class UploadButton extends ImmutablePureComponent {
const message = intl.formatMessage(messages.upload); const message = intl.formatMessage(messages.upload);
const options = [
{
icon: 'cloud-upload',
iconComponent: UploadFileIcon,
value: 'upload',
text: intl.formatMessage(messages.upload),
},
{
icon: 'paint-brush',
iconComponent: BrushIcon,
value: 'doodle',
text: intl.formatMessage(messages.doodle),
},
];
return ( return (
<div className='compose-form__upload-button'> <div className='compose-form__upload-button'>
<IconButton icon='paperclip' iconComponent={PhotoLibraryIcon} title={message} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} /> <DropdownIconButton
icon='paperclip'
iconComponent={PhotoLibraryIcon}
title={message}
disabled={disabled}
onChange={this.handleSelect}
value='upload'
options={options}
/>
<label> <label>
<span style={{ display: 'none' }}>{message}</span> <span style={{ display: 'none' }}>{message}</span>
<input <input

View file

@ -1,6 +1,7 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { uploadCompose } from '../../../actions/compose'; import { uploadCompose } from '../../../actions/compose';
import { openModal } from '../../../actions/modal';
import UploadButton from '../components/upload_button'; import UploadButton from '../components/upload_button';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
@ -14,6 +15,12 @@ const mapDispatchToProps = dispatch => ({
dispatch(uploadCompose(files)); dispatch(uploadCompose(files));
}, },
onDoodleOpen() {
dispatch(openModal({
modalType: 'DOODLE',
modalProps: { noEsc: true, noClose: true },
}));
},
}); });
export default connect(mapStateToProps, mapDispatchToProps)(UploadButton); export default connect(mapStateToProps, mapDispatchToProps)(UploadButton);

View file

@ -36,7 +36,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key]; let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this // Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) { if (Object.hasOwn(emoji, '1')) {
emoji = emoji['1']; emoji = emoji['1'];
} }
@ -88,7 +88,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key]; let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this // Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) { if (Object.hasOwn(emoji, '1')) {
emoji = emoji['1']; emoji = emoji['1'];
} }

View file

@ -135,19 +135,19 @@ function getData(emoji, skin, set) {
} }
} }
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji)) { if (Object.hasOwn(data.short_names, emoji)) {
emoji = data.short_names[emoji]; emoji = data.short_names[emoji];
} }
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji)) { if (Object.hasOwn(data.emojis, emoji)) {
emojiData = data.emojis[emoji]; emojiData = data.emojis[emoji];
} }
} else if (emoji.id) { } else if (emoji.id) {
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji.id)) { if (Object.hasOwn(data.short_names, emoji.id)) {
emoji.id = data.short_names[emoji.id]; emoji.id = data.short_names[emoji.id];
} }
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji.id)) { if (Object.hasOwn(data.emojis, emoji.id)) {
emojiData = data.emojis[emoji.id]; emojiData = data.emojis[emoji.id];
skin = skin || emoji.skin; skin = skin || emoji.skin;
} }
@ -216,7 +216,7 @@ function deepMerge(a, b) {
let originalValue = a[key], let originalValue = a[key],
value = originalValue; value = originalValue;
if (Object.prototype.hasOwnProperty.call(b, key)) { if (Object.hasOwn(b, key)) {
value = b[key]; value = b[key];
} }

View file

@ -9,8 +9,8 @@ import { NavLink, Switch, Route } from 'react-router-dom';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ExploreIcon from '@/material-icons/400-24px/explore.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
import Column from 'flavours/glitch/components/column'; import Column from 'flavours/glitch/components/column';
import ColumnHeader from 'flavours/glitch/components/column_header'; import ColumnHeader from 'flavours/glitch/components/column_header';
import Search from 'flavours/glitch/features/compose/containers/search_container'; import Search from 'flavours/glitch/features/compose/containers/search_container';
@ -59,8 +59,8 @@ class Explore extends PureComponent {
return ( return (
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}> <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>
<ColumnHeader <ColumnHeader
icon={isSearching ? 'search' : 'hashtag'} icon={isSearching ? 'search' : 'explore'}
iconComponent={isSearching ? SearchIcon : TagIcon} iconComponent={isSearching ? SearchIcon : ExploreIcon}
title={intl.formatMessage(isSearching ? messages.searchResults : messages.title)} title={intl.formatMessage(isSearching ? messages.searchResults : messages.title)}
onClick={this.handleHeaderClick} onClick={this.handleHeaderClick}
multiColumn={multiColumn} multiColumn={multiColumn}

View file

@ -158,7 +158,7 @@ class GettingStarted extends ImmutablePureComponent {
} }
if (showTrends) { if (showTrends) {
navItems.push(<ColumnLink key='explore' icon='hashtag' iconComponent={TagIcon} text={intl.formatMessage(messages.explore)} to='/explore' />); navItems.push(<ColumnLink key='explore' icon='explore' iconComponent={TagIcon} text={intl.formatMessage(messages.explore)} to='/explore' />);
} }
if (signedIn) { if (signedIn) {

View file

@ -4,6 +4,7 @@ import { Component } from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react';
import ExploreIcon from '@/material-icons/400-24px/explore.svg?react';
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import MailIcon from '@/material-icons/400-24px/mail.svg?react'; import MailIcon from '@/material-icons/400-24px/mail.svg?react';
@ -13,7 +14,6 @@ import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react'; import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
import { NavigationPortal } from 'flavours/glitch/components/navigation_portal'; import { NavigationPortal } from 'flavours/glitch/components/navigation_portal';
import { timelinePreview, trendsEnabled } from 'flavours/glitch/initial_state'; import { timelinePreview, trendsEnabled } from 'flavours/glitch/initial_state';
import { transientSingleColumn } from 'flavours/glitch/is_mobile'; import { transientSingleColumn } from 'flavours/glitch/is_mobile';
@ -91,7 +91,7 @@ class NavigationPanel extends Component {
)} )}
{trendsEnabled ? ( {trendsEnabled ? (
<ColumnLink transparent to={(signedIn || timelinePreview) ? '/explore' : '/explore/tags'} icon='hashtag' iconComponent={TagIcon} text={intl.formatMessage(messages.explore)} /> <ColumnLink transparent to={(signedIn || timelinePreview) ? '/explore' : '/explore/tags'} icon='explore' iconComponent={ExploreIcon} text={intl.formatMessage(messages.explore)} />
) : ( ) : (
<ColumnLink transparent to='/search' icon='search' iconComponent={SearchIcon} text={intl.formatMessage(messages.search)} /> <ColumnLink transparent to='/search' icon='search' iconComponent={SearchIcon} text={intl.formatMessage(messages.search)} />
)} )}

View file

@ -14,6 +14,7 @@
"column_subheading.lists": "Lists", "column_subheading.lists": "Lists",
"column_subheading.navigation": "Navigation", "column_subheading.navigation": "Navigation",
"community.column_settings.allow_local_only": "Show local-only toots", "community.column_settings.allow_local_only": "Show local-only toots",
"compose.attach.doodle": "Draw something",
"compose.change_federation": "Change federation settings", "compose.change_federation": "Change federation settings",
"compose.content-type.change": "Change advanced formatting options", "compose.content-type.change": "Change advanced formatting options",
"compose.content-type.html": "HTML", "compose.content-type.html": "HTML",
@ -22,8 +23,8 @@
"compose.content-type.markdown_meta": "Format your posts using Markdown", "compose.content-type.markdown_meta": "Format your posts using Markdown",
"compose.content-type.plain": "Plain text", "compose.content-type.plain": "Plain text",
"compose.content-type.plain_meta": "Write with no advanced formatting", "compose.content-type.plain_meta": "Write with no advanced formatting",
"compose.disable_threaded_mode": "Disable threaded more", "compose.disable_threaded_mode": "Disable threaded mode",
"compose.enable_threaded_mode": "Enable threaded more", "compose.enable_threaded_mode": "Enable threaded mode",
"compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}", "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
"compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}", "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}", "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",

View file

@ -4,9 +4,9 @@ import { createRoot } from 'react-dom/client';
import ready from 'flavours/glitch/ready'; import ready from 'flavours/glitch/ready';
ready(() => { ready(() => {
[].forEach.call(document.querySelectorAll('[data-admin-component]'), element => { document.querySelectorAll('[data-admin-component]').forEach(element => {
const componentName = element.getAttribute('data-admin-component'); const componentName = element.getAttribute('data-admin-component');
const { ...componentProps } = JSON.parse(element.getAttribute('data-props')); const componentProps = JSON.parse(element.getAttribute('data-props'));
import('flavours/glitch/containers/admin_component').then(({ default: AdminComponent }) => { import('flavours/glitch/containers/admin_component').then(({ default: AdminComponent }) => {
return import('flavours/glitch/components/admin/' + componentName).then(({ default: Component }) => { return import('flavours/glitch/components/admin/' + componentName).then(({ default: Component }) => {

View file

@ -68,11 +68,11 @@ function main() {
return messageFormat.format(values); return messageFormat.format(values);
}; };
[].forEach.call(document.querySelectorAll('.emojify'), (content) => { document.querySelectorAll('.emojify').forEach((content) => {
content.innerHTML = emojify(content.innerHTML); content.innerHTML = emojify(content.innerHTML);
}); });
[].forEach.call(document.querySelectorAll('time.formatted'), (content) => { document.querySelectorAll('time.formatted').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
const formattedDate = dateTimeFormat.format(datetime); const formattedDate = dateTimeFormat.format(datetime);
@ -89,7 +89,7 @@ function main() {
}; };
const todayFormat = new IntlMessageFormat(localeData['relative_format.today'] || 'Today at {time}', locale); const todayFormat = new IntlMessageFormat(localeData['relative_format.today'] || 'Today at {time}', locale);
[].forEach.call(document.querySelectorAll('time.relative-formatted'), (content) => { document.querySelectorAll('time.relative-formatted').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
let formattedContent; let formattedContent;
@ -106,7 +106,7 @@ function main() {
content.textContent = formattedContent; content.textContent = formattedContent;
}); });
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => { document.querySelectorAll('time.time-ago').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
const now = new Date(); const now = new Date();
@ -122,8 +122,8 @@ function main() {
if (reactComponents.length > 0) { if (reactComponents.length > 0) {
import(/* webpackChunkName: "containers/media_container" */ 'flavours/glitch/containers/media_container') import(/* webpackChunkName: "containers/media_container" */ 'flavours/glitch/containers/media_container')
.then(({ default: MediaContainer }) => { .then(({ default: MediaContainer }) => {
[].forEach.call(reactComponents, (component) => { reactComponents.forEach((component) => {
[].forEach.call(component.children, (child) => { Array.from(component.children).forEach((child) => {
component.removeChild(child); component.removeChild(child);
}); });
}); });
@ -188,7 +188,7 @@ function main() {
return false; return false;
}); });
[].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => { document.querySelectorAll('.status__content__spoiler-link').forEach((spoilerLink) => {
const statusEl = spoilerLink.parentNode.parentNode; const statusEl = spoilerLink.parentNode.parentNode;
const message = (statusEl.dataset.spoiler === 'expanded') ? (localeData['status.show_less'] || 'Show less') : (localeData['status.show_more'] || 'Show more'); const message = (statusEl.dataset.spoiler === 'expanded') ? (localeData['status.show_less'] || 'Show less') : (localeData['status.show_more'] || 'Show more');
spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format(); spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();

View file

@ -324,6 +324,23 @@ $content-width: 840px;
padding-bottom: 0; padding-bottom: 0;
margin-bottom: 0; margin-bottom: 0;
border-bottom: 0; border-bottom: 0;
.comment {
display: block;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 4px;
&.private-comment {
display: block;
color: $darker-text-color;
}
&.public-comment {
display: block;
color: $secondary-text-color;
}
}
} }
& > p { & > p {
@ -643,17 +660,6 @@ body,
margin-bottom: 5px; margin-bottom: 5px;
margin-inline-end: 5px; margin-inline-end: 5px;
} }
.media-spoiler-toggle-buttons {
margin-inline-start: auto;
.button {
overflow: visible;
margin-bottom: 5px;
margin-inline-start: 5px;
float: right;
}
}
} }
.back-link { .back-link {
@ -1076,6 +1082,7 @@ a.name-tag,
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: 0; margin-bottom: 0;
word-break: break-word;
} }
&__permissions { &__permissions {

View file

@ -5737,7 +5737,6 @@ a.status-card {
.icon { .icon {
position: absolute; position: absolute;
top: 12px + 2px; top: 12px + 2px;
inset-inline-start: 16px - 2px;
display: inline-block; display: inline-block;
opacity: 0; opacity: 0;
transition: all 100ms linear; transition: all 100ms linear;
@ -5747,11 +5746,16 @@ a.status-card {
color: $darker-text-color; color: $darker-text-color;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
margin-inline-start: 16px - 2px;
&.active { &.active {
pointer-events: auto; pointer-events: auto;
opacity: 1; opacity: 1;
} }
@media screen and (min-width: $no-gap-breakpoint) {
inset-inline-start: 16px - 2px;
}
} }
.icon-search { .icon-search {
@ -6521,6 +6525,7 @@ a.status-card {
.report-modal__comment { .report-modal__comment {
box-sizing: border-box; box-sizing: border-box;
width: 50%; width: 50%;
min-width: 50%;
@media screen and (width <= 480px) { @media screen and (width <= 480px) {
width: 100%; width: 100%;
@ -6589,6 +6594,14 @@ a.status-card {
min-height: 100px; min-height: 100px;
max-height: 50vh; max-height: 50vh;
border: 0; border: 0;
@media screen and (height <= 600px) {
max-height: 20vh;
}
@media screen and (max-width: $no-columns-breakpoint) {
max-height: 20vh;
}
} }
.setting-toggle { .setting-toggle {

View file

@ -1080,6 +1080,7 @@ code {
&__type { &__type {
color: $darker-text-color; color: $darker-text-color;
word-break: break-word;
} }
} }

View file

@ -40,7 +40,7 @@ function render(
ui: React.ReactElement, ui: React.ReactElement,
{ locale = 'en', signedIn = true, ...renderOptions } = {}, { locale = 'en', signedIn = true, ...renderOptions } = {},
) { ) {
const Wrapper = (props: { children: React.ReactElement }) => { const Wrapper = (props: { children: React.ReactNode }) => {
return ( return (
<MemoryRouter> <MemoryRouter>
<IntlProvider locale={locale}> <IntlProvider locale={locale}>

View file

@ -80,7 +80,7 @@ export default class MediaContainer extends PureComponent {
return ( return (
<IntlProvider> <IntlProvider>
<> <>
{[].map.call(components, (component, i) => { {Array.from(components).map((component, i) => {
const componentName = component.getAttribute('data-component'); const componentName = component.getAttribute('data-component');
const Component = MEDIA_COMPONENTS[componentName]; const Component = MEDIA_COMPONENTS[componentName];
const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props')); const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props'));

View file

@ -141,6 +141,7 @@ class LanguageDropdownMenu extends PureComponent {
case 'Escape': case 'Escape':
onClose(); onClose();
break; break;
case ' ':
case 'Enter': case 'Enter':
this.handleClick(e); this.handleClick(e);
break; break;

View file

@ -5,16 +5,16 @@ import { injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { PrivacyDropdownMenu } from './privacy_dropdown_menu';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' }, public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' },
@ -28,126 +28,6 @@ const messages = defineMessages({
unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' }, unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' },
}); });
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
class PrivacyDropdownMenu extends PureComponent {
static propTypes = {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};
handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) {
this.props.onClose();
e.stopPropagation();
}
};
handleKeyDown = e => {
const { items } = this.props;
const value = e.currentTarget.getAttribute('data-index');
const index = items.findIndex(item => {
return (item.value === value);
});
let element = null;
switch(e.key) {
case 'Escape':
this.props.onClose();
break;
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown':
element = this.node.childNodes[index + 1] || this.node.firstChild;
break;
case 'ArrowUp':
element = this.node.childNodes[index - 1] || this.node.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = this.node.childNodes[index - 1] || this.node.lastChild;
} else {
element = this.node.childNodes[index + 1] || this.node.firstChild;
}
break;
case 'Home':
element = this.node.firstChild;
break;
case 'End':
element = this.node.lastChild;
break;
}
if (element) {
element.focus();
this.props.onChange(element.getAttribute('data-index'));
e.preventDefault();
e.stopPropagation();
}
};
handleClick = e => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
this.props.onClose();
this.props.onChange(value);
};
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, { capture: true });
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
}
componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, { capture: true });
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
}
setRef = c => {
this.node = c;
};
setFocusRef = c => {
this.focusedItem = c;
};
render () {
const { style, items, value } = this.props;
return (
<div style={{ ...style }} role='listbox' ref={this.setRef}>
{items.map(item => (
<div role='option' tabIndex={0} key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} icon={item.iconComponent} />
</div>
<div className='privacy-dropdown__option__content'>
<strong>{item.text}</strong>
{item.meta}
</div>
{item.extra && (
<div className='privacy-dropdown__option__additional' title={item.extra}>
<Icon id='info-circle' icon={InfoIcon} />
</div>
)}
</div>
))}
</div>
);
}
}
class PrivacyDropdown extends PureComponent { class PrivacyDropdown extends PureComponent {
static propTypes = { static propTypes = {

View file

@ -0,0 +1,128 @@
import PropTypes from 'prop-types';
import { useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
import { Icon } from 'mastodon/components/icon';
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
export const PrivacyDropdownMenu = ({ style, items, value, onClose, onChange }) => {
const nodeRef = useRef(null);
const focusedItemRef = useRef(null);
const [currentValue, setCurrentValue] = useState(value);
const handleDocumentClick = useCallback((e) => {
if (nodeRef.current && !nodeRef.current.contains(e.target)) {
onClose();
e.stopPropagation();
}
}, [nodeRef, onClose]);
const handleClick = useCallback((e) => {
const value = e.currentTarget.getAttribute('data-index');
e.preventDefault();
onClose();
onChange(value);
}, [onClose, onChange]);
const handleKeyDown = useCallback((e) => {
const value = e.currentTarget.getAttribute('data-index');
const index = items.findIndex(item => (item.value === value));
let element = null;
switch (e.key) {
case 'Escape':
onClose();
break;
case ' ':
case 'Enter':
handleClick(e);
break;
case 'ArrowDown':
element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild;
break;
case 'ArrowUp':
element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild;
break;
case 'Tab':
if (e.shiftKey) {
element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild;
} else {
element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild;
}
break;
case 'Home':
element = nodeRef.current.firstChild;
break;
case 'End':
element = nodeRef.current.lastChild;
break;
}
if (element) {
element.focus();
setCurrentValue(element.getAttribute('data-index'));
e.preventDefault();
e.stopPropagation();
}
}, [nodeRef, items, onClose, handleClick, setCurrentValue]);
useEffect(() => {
document.addEventListener('click', handleDocumentClick, { capture: true });
document.addEventListener('touchend', handleDocumentClick, listenerOptions);
focusedItemRef.current?.focus({ preventScroll: true });
return () => {
document.removeEventListener('click', handleDocumentClick, { capture: true });
document.removeEventListener('touchend', handleDocumentClick, listenerOptions);
};
}, [handleDocumentClick]);
return (
<ul style={{ ...style }} role='listbox' ref={nodeRef}>
{items.map(item => (
<li
role='option'
tabIndex={0}
key={item.value}
data-index={item.value}
onKeyDown={handleKeyDown}
onClick={handleClick}
className={classNames('privacy-dropdown__option', { active: item.value === currentValue })}
aria-selected={item.value === currentValue}
ref={item.value === currentValue ? focusedItemRef : null}
>
<div className='privacy-dropdown__option__icon'>
<Icon id={item.icon} icon={item.iconComponent} />
</div>
<div className='privacy-dropdown__option__content'>
<strong>{item.text}</strong>
{item.meta}
</div>
{item.extra && (
<div className='privacy-dropdown__option__additional' title={item.extra}>
<Icon id='info-circle' icon={InfoIcon} />
</div>
)}
</li>
))}
</ul>
);
};
PrivacyDropdownMenu.propTypes = {
style: PropTypes.object,
items: PropTypes.array.isRequired,
value: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
};

View file

@ -36,7 +36,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key]; let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this // Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) { if (Object.hasOwn(emoji, '1')) {
emoji = emoji['1']; emoji = emoji['1'];
} }
@ -88,7 +88,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
let emoji = emojiIndex.emojis[key]; let emoji = emojiIndex.emojis[key];
// Emojis with skin tone modifiers are stored like this // Emojis with skin tone modifiers are stored like this
if (Object.prototype.hasOwnProperty.call(emoji, '1')) { if (Object.hasOwn(emoji, '1')) {
emoji = emoji['1']; emoji = emoji['1'];
} }

View file

@ -135,19 +135,19 @@ function getData(emoji, skin, set) {
} }
} }
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji)) { if (Object.hasOwn(data.short_names, emoji)) {
emoji = data.short_names[emoji]; emoji = data.short_names[emoji];
} }
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji)) { if (Object.hasOwn(data.emojis, emoji)) {
emojiData = data.emojis[emoji]; emojiData = data.emojis[emoji];
} }
} else if (emoji.id) { } else if (emoji.id) {
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji.id)) { if (Object.hasOwn(data.short_names, emoji.id)) {
emoji.id = data.short_names[emoji.id]; emoji.id = data.short_names[emoji.id];
} }
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji.id)) { if (Object.hasOwn(data.emojis, emoji.id)) {
emojiData = data.emojis[emoji.id]; emojiData = data.emojis[emoji.id];
skin = skin || emoji.skin; skin = skin || emoji.skin;
} }
@ -216,7 +216,7 @@ function deepMerge(a, b) {
let originalValue = a[key], let originalValue = a[key],
value = originalValue; value = originalValue;
if (Object.prototype.hasOwnProperty.call(b, key)) { if (Object.hasOwn(b, key)) {
value = b[key]; value = b[key];
} }

View file

@ -58,7 +58,7 @@ class Explore extends PureComponent {
return ( return (
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}> <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}>
<ColumnHeader <ColumnHeader
icon={isSearching ? 'search' : 'hashtag'} icon={isSearching ? 'search' : 'explore'}
iconComponent={isSearching ? SearchIcon : ExploreIcon} iconComponent={isSearching ? SearchIcon : ExploreIcon}
title={intl.formatMessage(isSearching ? messages.searchResults : messages.title)} title={intl.formatMessage(isSearching ? messages.searchResults : messages.title)}
onClick={this.handleHeaderClick} onClick={this.handleHeaderClick}

View file

@ -112,7 +112,7 @@ class GettingStarted extends ImmutablePureComponent {
if (showTrends) { if (showTrends) {
navItems.push( navItems.push(
<ColumnLink key='explore' icon='hashtag' iconComponent={TagIcon} text={intl.formatMessage(messages.explore)} to='/explore' />, <ColumnLink key='explore' icon='explore' iconComponent={TagIcon} text={intl.formatMessage(messages.explore)} to='/explore' />,
); );
} }

View file

@ -94,7 +94,7 @@ class NavigationPanel extends Component {
)} )}
{trendsEnabled ? ( {trendsEnabled ? (
<ColumnLink transparent to={(signedIn || timelinePreview) ? '/explore' : '/explore/tags'} icon='hashtag' iconComponent={ExploreIcon} text={intl.formatMessage(messages.explore)} /> <ColumnLink transparent to={(signedIn || timelinePreview) ? '/explore' : '/explore/tags'} icon='explore' iconComponent={ExploreIcon} text={intl.formatMessage(messages.explore)} />
) : ( ) : (
<ColumnLink transparent to='/search' icon='search' iconComponent={SearchIcon} text={intl.formatMessage(messages.search)} /> <ColumnLink transparent to='/search' icon='search' iconComponent={SearchIcon} text={intl.formatMessage(messages.search)} />
)} )}

View file

@ -500,7 +500,7 @@
"onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}", "onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}",
"onboarding.share.next_steps": "Hurrengo urrats posibleak:", "onboarding.share.next_steps": "Hurrengo urrats posibleak:",
"onboarding.share.title": "Partekatu zure profila", "onboarding.share.title": "Partekatu zure profila",
"onboarding.start.lead": "Zure Mastodoneko kontu berria prest dago. Jakin nola atera diezaioekun etekin handiena hemen:", "onboarding.start.lead": "Mastodonen parte zara orain, bakarra eta deszentralizatua den sare-sozialaren plataforma, non zuk, eta ez algoritmo batek, zeure esperientzia pertsonaliza dezakezun. Igaro ezazu muga soziala:",
"onboarding.start.skip": "Urrats guztiak saltatu nahi dituzu?", "onboarding.start.skip": "Urrats guztiak saltatu nahi dituzu?",
"onboarding.start.title": "Lortu duzu!", "onboarding.start.title": "Lortu duzu!",
"onboarding.steps.follow_people.body": "Zure jarioa zuk pertsonalizatzen duzu. Bete dezagun jende interesgarriaz.", "onboarding.steps.follow_people.body": "Zure jarioa zuk pertsonalizatzen duzu. Bete dezagun jende interesgarriaz.",

View file

@ -110,7 +110,7 @@
"column.about": "درباره", "column.about": "درباره",
"column.blocks": "کاربران مسدود شده", "column.blocks": "کاربران مسدود شده",
"column.bookmarks": "نشانک‌ها", "column.bookmarks": "نشانک‌ها",
"column.community": "خط زمانی محلّی", "column.community": "خط زمانی محلی",
"column.direct": "اشاره‌های خصوصی", "column.direct": "اشاره‌های خصوصی",
"column.directory": "مرور نمایه‌ها", "column.directory": "مرور نمایه‌ها",
"column.domain_blocks": "دامنه‌های مسدود شده", "column.domain_blocks": "دامنه‌های مسدود شده",
@ -131,7 +131,7 @@
"column_header.show_settings": "نمایش تنظیمات", "column_header.show_settings": "نمایش تنظیمات",
"column_header.unpin": "برداشتن سنجاق", "column_header.unpin": "برداشتن سنجاق",
"column_subheading.settings": "تنظیمات", "column_subheading.settings": "تنظیمات",
"community.column_settings.local_only": "فقط محلّی", "community.column_settings.local_only": "فقط محلی",
"community.column_settings.media_only": "فقط رسانه", "community.column_settings.media_only": "فقط رسانه",
"community.column_settings.remote_only": "تنها دوردست", "community.column_settings.remote_only": "تنها دوردست",
"compose.language.change": "تغییر زبان", "compose.language.change": "تغییر زبان",
@ -228,7 +228,7 @@
"empty_column.account_unavailable": "نمایهٔ موجود نیست", "empty_column.account_unavailable": "نمایهٔ موجود نیست",
"empty_column.blocks": "هنوز کسی را مسدود نکرده‌اید.", "empty_column.blocks": "هنوز کسی را مسدود نکرده‌اید.",
"empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشانه‌گذاری شده‌ای ندارید. هنگامی که فرسته‌ای را نشانه‌گذاری کنید، این‌جا نشان داده خواهد شد.", "empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشانه‌گذاری شده‌ای ندارید. هنگامی که فرسته‌ای را نشانه‌گذاری کنید، این‌جا نشان داده خواهد شد.",
"empty_column.community": "خط زمانی محلّی خالی است. چیزی بنویسید تا چرخش بچرخد!", "empty_column.community": "خط زمانی محلی خالیست. چیزی نوشته تا چرخش بچرخد!",
"empty_column.direct": "هنوز هیچ اشاره خصوصی‌ای ندارید. هنگامی که چنین پیامی بگیرید یا بفرستید این‌جا نشان داده خواهد شد.", "empty_column.direct": "هنوز هیچ اشاره خصوصی‌ای ندارید. هنگامی که چنین پیامی بگیرید یا بفرستید این‌جا نشان داده خواهد شد.",
"empty_column.domain_blocks": "هنوز هیچ دامنه‌ای مسدود نشده است.", "empty_column.domain_blocks": "هنوز هیچ دامنه‌ای مسدود نشده است.",
"empty_column.explore_statuses": "الآن چیزی پرطرفدار نیست. بعداً دوباره بررسی کنید!", "empty_column.explore_statuses": "الآن چیزی پرطرفدار نیست. بعداً دوباره بررسی کنید!",
@ -277,6 +277,17 @@
"follow_request.authorize": "اجازه دهید", "follow_request.authorize": "اجازه دهید",
"follow_request.reject": "رد کنید", "follow_request.reject": "رد کنید",
"follow_requests.unlocked_explanation": "با این که حسابتان قفل نیست، کارکنان {domain} فکر کردند که ممکن است بخواهید درخواست‌ها از این حساب‌ها را به صورت دستی بازبینی کنید.", "follow_requests.unlocked_explanation": "با این که حسابتان قفل نیست، کارکنان {domain} فکر کردند که ممکن است بخواهید درخواست‌ها از این حساب‌ها را به صورت دستی بازبینی کنید.",
"follow_suggestions.curated_suggestion": "گزینش سردبیر",
"follow_suggestions.dismiss": "دیگر نشان داده نشود",
"follow_suggestions.hints.featured": "این نمایه به دست گروه {domain} دستچین شده.",
"follow_suggestions.hints.friends_of_friends": "این نمایه بین کسانی که پی می‌گیرید محبوب است.",
"follow_suggestions.hints.most_followed": "این نمایه روی {domain} بسیار پی‌گرفته شده.",
"follow_suggestions.hints.most_interactions": "این نمایه اخیراُ روی {domain} توجّه زیادی گرفته.",
"follow_suggestions.hints.similar_to_recently_followed": "این نمایه شبیه نمایه‌هاییست که اخیراً پی‌گرفته‌اید.",
"follow_suggestions.personalized_suggestion": "پیشنهاد شخصی",
"follow_suggestions.popular_suggestion": "پیشنهاد محبوب",
"follow_suggestions.view_all": "دیدن همه",
"follow_suggestions.who_to_follow": "افرادی برای پی‌گیری",
"followed_tags": "برچسب‌های پی‌گرفته", "followed_tags": "برچسب‌های پی‌گرفته",
"footer.about": "درباره", "footer.about": "درباره",
"footer.directory": "فهرست نمایه‌ها", "footer.directory": "فهرست نمایه‌ها",
@ -345,7 +356,7 @@
"keyboard_shortcuts.home": "گشودن خط زمانی خانگی", "keyboard_shortcuts.home": "گشودن خط زمانی خانگی",
"keyboard_shortcuts.hotkey": "میان‌بر", "keyboard_shortcuts.hotkey": "میان‌بر",
"keyboard_shortcuts.legend": "نمایش این نشانه", "keyboard_shortcuts.legend": "نمایش این نشانه",
"keyboard_shortcuts.local": "گشودن خط زمانی محلّی", "keyboard_shortcuts.local": "گشودن خط زمانی محلی",
"keyboard_shortcuts.mention": "اشاره به نویسنده", "keyboard_shortcuts.mention": "اشاره به نویسنده",
"keyboard_shortcuts.muted": "گشودن فهرست کاربران خموش", "keyboard_shortcuts.muted": "گشودن فهرست کاربران خموش",
"keyboard_shortcuts.my_profile": "گشودن نمایه‌تان", "keyboard_shortcuts.my_profile": "گشودن نمایه‌تان",
@ -396,7 +407,7 @@
"navigation_bar.advanced_interface": "بازکردن در رابط کاربری وب پیشرفته", "navigation_bar.advanced_interface": "بازکردن در رابط کاربری وب پیشرفته",
"navigation_bar.blocks": "کاربران مسدود شده", "navigation_bar.blocks": "کاربران مسدود شده",
"navigation_bar.bookmarks": "نشانک‌ها", "navigation_bar.bookmarks": "نشانک‌ها",
"navigation_bar.community_timeline": "خط زمانی محلّی", "navigation_bar.community_timeline": "خط زمانی محلی",
"navigation_bar.compose": "نوشتن فرستهٔ تازه", "navigation_bar.compose": "نوشتن فرستهٔ تازه",
"navigation_bar.direct": "اشاره‌های خصوصی", "navigation_bar.direct": "اشاره‌های خصوصی",
"navigation_bar.discover": "گشت و گذار", "navigation_bar.discover": "گشت و گذار",
@ -475,8 +486,10 @@
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.discoverable": "نمایه خود را قابل نمایش کنید", "onboarding.profile.discoverable": "نمایه خود را قابل نمایش کنید",
"onboarding.profile.discoverable_hint": "خواسته‌اید روی ماستودون کشف شوید. ممکن است فرسته‌هایتان در نتیحهٔ جست‌وجوها و فرسته‌های داغ ظاهر شده و نمایه‌تان به افرادی با علایق مشابهتان پیشنهاد شود.",
"onboarding.profile.display_name": "نام نمایشی", "onboarding.profile.display_name": "نام نمایشی",
"onboarding.profile.display_name_hint": "نام کامل یا نام باحالتان…", "onboarding.profile.display_name_hint": "نام کامل یا نام باحالتان…",
"onboarding.profile.lead": "همواره می‌توانید این مورد را در تنظیمات که گزینه‌ّای شخصی سازی بیش‌تری نیز دارد کامل کنید.",
"onboarding.profile.note": "درباره شما", "onboarding.profile.note": "درباره شما",
"onboarding.profile.note_hint": "می‌توانید افراد دیگر را @نام‌بردن یا #برچسب بزنید…", "onboarding.profile.note_hint": "می‌توانید افراد دیگر را @نام‌بردن یا #برچسب بزنید…",
"onboarding.profile.save_and_continue": "ذخیره کن و ادامه بده", "onboarding.profile.save_and_continue": "ذخیره کن و ادامه بده",
@ -522,6 +535,7 @@
"privacy.private.short": "پی‌گیرندگان", "privacy.private.short": "پی‌گیرندگان",
"privacy.public.long": "هرکسی در و بیرون از ماستودون", "privacy.public.long": "هرکسی در و بیرون از ماستودون",
"privacy.public.short": "عمومی", "privacy.public.short": "عمومی",
"privacy.unlisted.additional": "درست مثل عمومی رفتار می‌کند؛ جز این که فرسته در برچسب‌ها یا خوراک‌های زنده، کشف یا جست‌وجوی ماستودون ظاهر نخواهد شد. حتا اگر کلیّت نمایه‌تان اجازه داده باشد.",
"privacy.unlisted.long": "سروصدای الگوریتمی کم‌تر", "privacy.unlisted.long": "سروصدای الگوریتمی کم‌تر",
"privacy.unlisted.short": "عمومی ساکت", "privacy.unlisted.short": "عمومی ساکت",
"privacy_policy.last_updated": "آخرین به‌روز رسانی در {date}", "privacy_policy.last_updated": "آخرین به‌روز رسانی در {date}",
@ -541,6 +555,7 @@
"relative_time.minutes": "{number} دقیقه", "relative_time.minutes": "{number} دقیقه",
"relative_time.seconds": "{number} ثانیه", "relative_time.seconds": "{number} ثانیه",
"relative_time.today": "امروز", "relative_time.today": "امروز",
"reply_indicator.attachments": "{count, plural, one {# پیوست} other {# پیوست}}",
"reply_indicator.cancel": "لغو", "reply_indicator.cancel": "لغو",
"reply_indicator.poll": "نظرسنجی", "reply_indicator.poll": "نظرسنجی",
"report.block": "انسداد", "report.block": "انسداد",

View file

@ -277,6 +277,17 @@
"follow_request.authorize": "Autoriser", "follow_request.authorize": "Autoriser",
"follow_request.reject": "Rejeter", "follow_request.reject": "Rejeter",
"follow_requests.unlocked_explanation": "Même si votre compte nest pas privé, léquipe de {domain} a pensé que vous pourriez vouloir peut-être consulter manuellement les demandes d'abonnement de ces comptes.", "follow_requests.unlocked_explanation": "Même si votre compte nest pas privé, léquipe de {domain} a pensé que vous pourriez vouloir peut-être consulter manuellement les demandes d'abonnement de ces comptes.",
"follow_suggestions.curated_suggestion": "Choix du staff",
"follow_suggestions.dismiss": "Ne plus afficher",
"follow_suggestions.hints.featured": "Ce profil a été sélectionné par l'équipe de {domain}.",
"follow_suggestions.hints.friends_of_friends": "Ce profil est populaire parmi les personnes que vous suivez.",
"follow_suggestions.hints.most_followed": "Ce profil est l'un des plus suivis sur {domain}.",
"follow_suggestions.hints.most_interactions": "Ce profil a récemment fait l'objet d'une grande attention sur {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Ce profil est similaire aux profils que vous avez suivis le plus récemment.",
"follow_suggestions.personalized_suggestion": "Suggestion personnalisée",
"follow_suggestions.popular_suggestion": "Suggestion populaire",
"follow_suggestions.view_all": "Tout afficher",
"follow_suggestions.who_to_follow": "Qui suivre",
"followed_tags": "Hashtags suivis", "followed_tags": "Hashtags suivis",
"footer.about": "À propos", "footer.about": "À propos",
"footer.directory": "Annuaire des profils", "footer.directory": "Annuaire des profils",

View file

@ -277,6 +277,17 @@
"follow_request.authorize": "Accepter", "follow_request.authorize": "Accepter",
"follow_request.reject": "Rejeter", "follow_request.reject": "Rejeter",
"follow_requests.unlocked_explanation": "Même si votre compte nest pas privé, léquipe de {domain} a pensé que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.", "follow_requests.unlocked_explanation": "Même si votre compte nest pas privé, léquipe de {domain} a pensé que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.",
"follow_suggestions.curated_suggestion": "Choix du staff",
"follow_suggestions.dismiss": "Ne plus afficher",
"follow_suggestions.hints.featured": "Ce profil a été sélectionné par l'équipe de {domain}.",
"follow_suggestions.hints.friends_of_friends": "Ce profil est populaire parmi les personnes que vous suivez.",
"follow_suggestions.hints.most_followed": "Ce profil est l'un des plus suivis sur {domain}.",
"follow_suggestions.hints.most_interactions": "Ce profil a récemment fait l'objet d'une grande attention sur {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Ce profil est similaire aux profils que vous avez suivis le plus récemment.",
"follow_suggestions.personalized_suggestion": "Suggestion personnalisée",
"follow_suggestions.popular_suggestion": "Suggestion populaire",
"follow_suggestions.view_all": "Tout afficher",
"follow_suggestions.who_to_follow": "Qui suivre",
"followed_tags": "Hashtags suivis", "followed_tags": "Hashtags suivis",
"footer.about": "À propos", "footer.about": "À propos",
"footer.directory": "Annuaire des profils", "footer.directory": "Annuaire des profils",

View file

@ -277,7 +277,13 @@
"follow_request.authorize": "Autorisar", "follow_request.authorize": "Autorisar",
"follow_request.reject": "Rejecter", "follow_request.reject": "Rejecter",
"follow_requests.unlocked_explanation": "Benque tu conto ne es cludet, li administratores de {domain} pensat que tu fórsan vell voler tractar seque-petitiones de tis-ci contos manualmen.", "follow_requests.unlocked_explanation": "Benque tu conto ne es cludet, li administratores de {domain} pensat que tu fórsan vell voler tractar seque-petitiones de tis-ci contos manualmen.",
"follow_suggestions.curated_suggestion": "Selection del employates",
"follow_suggestions.dismiss": "Ne monstrar plu", "follow_suggestions.dismiss": "Ne monstrar plu",
"follow_suggestions.hints.featured": "Ti-ci profil ha esset selectet directmen del equip de {domain}.",
"follow_suggestions.hints.friends_of_friends": "Ti-ci profil es populari ínter tis qui tu seque.",
"follow_suggestions.hints.most_followed": "Ti-ci profil es un del max sequet sur {domain}.",
"follow_suggestions.hints.most_interactions": "Ti-ci profil ha recivet mult atention recentmen sur {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Ti-ci profil es simil al profiles queles tu ha recentmen sequet.",
"follow_suggestions.personalized_suggestion": "Personalisat suggestion", "follow_suggestions.personalized_suggestion": "Personalisat suggestion",
"follow_suggestions.popular_suggestion": "Populari suggestion", "follow_suggestions.popular_suggestion": "Populari suggestion",
"follow_suggestions.view_all": "Vider omnicos", "follow_suggestions.view_all": "Vider omnicos",

View file

@ -22,6 +22,7 @@
"account.followers": "Imeḍfaren", "account.followers": "Imeḍfaren",
"account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.", "account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.",
"account.followers_counter": "{count, plural, one {{count} n umeḍfar} other {{count} n imeḍfaren}}", "account.followers_counter": "{count, plural, one {{count} n umeḍfar} other {{count} n imeḍfaren}}",
"account.following": "Yeṭṭafaṛ",
"account.following_counter": "{count, plural, one {{counter} yettwaḍfaren} other {{counter} yettwaḍfaren}}", "account.following_counter": "{count, plural, one {{counter} yettwaḍfaren} other {{counter} yettwaḍfaren}}",
"account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.", "account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
"account.go_to_profile": "Ddu ɣer umaɣnu", "account.go_to_profile": "Ddu ɣer umaɣnu",
@ -39,6 +40,7 @@
"account.posts_with_replies": "Tisuffaɣ d tririyin", "account.posts_with_replies": "Tisuffaɣ d tririyin",
"account.report": "Cetki ɣef @{name}", "account.report": "Cetki ɣef @{name}",
"account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar", "account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar",
"account.requested_follow": "{name} yessuter ad k-yeḍfer",
"account.share": "Bḍu amaɣnu n @{name}", "account.share": "Bḍu amaɣnu n @{name}",
"account.show_reblogs": "Ssken-d inebḍa n @{name}", "account.show_reblogs": "Ssken-d inebḍa n @{name}",
"account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}", "account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
@ -57,7 +59,7 @@
"alert.unexpected.title": "Ayhuh!", "alert.unexpected.title": "Ayhuh!",
"announcement.announcement": "Ulɣu", "announcement.announcement": "Ulɣu",
"audio.hide": "Ffer amesli", "audio.hide": "Ffer amesli",
"boost_modal.combo": "Tzemreḍ ad tetekkiḍ ɣef {combo} akken ad tessurfeḍ aya tikelt-nniḍen", "boost_modal.combo": "Tzemreḍ ad tsiteḍ ɣef {combo} akken ad tzegleḍ aya tikelt i d-iteddun",
"bundle_column_error.copy_stacktrace": "Nɣel tuccḍa n uneqqis", "bundle_column_error.copy_stacktrace": "Nɣel tuccḍa n uneqqis",
"bundle_column_error.error.title": "Uh, ala !", "bundle_column_error.error.title": "Uh, ala !",
"bundle_column_error.network.title": "Tuccḍa deg uẓeṭṭa", "bundle_column_error.network.title": "Tuccḍa deg uẓeṭṭa",
@ -73,7 +75,8 @@
"column.blocks": "Imiḍanen yettusḥebsen", "column.blocks": "Imiḍanen yettusḥebsen",
"column.bookmarks": "Ticraḍ", "column.bookmarks": "Ticraḍ",
"column.community": "Tasuddemt tadigant", "column.community": "Tasuddemt tadigant",
"column.directory": "Inig deg imaɣnuten", "column.direct": "Tabdarin tusligin",
"column.directory": "Inig deg imeɣna",
"column.domain_blocks": "Taɣulin yeffren", "column.domain_blocks": "Taɣulin yeffren",
"column.favourites": "Imenyafen", "column.favourites": "Imenyafen",
"column.follow_requests": "Isuturen n teḍfeṛt", "column.follow_requests": "Isuturen n teḍfeṛt",
@ -105,6 +108,7 @@
"compose_form.lock_disclaimer.lock": "yettwacekkel", "compose_form.lock_disclaimer.lock": "yettwacekkel",
"compose_form.placeholder": "D acu i itezzin deg wallaɣ?", "compose_form.placeholder": "D acu i itezzin deg wallaɣ?",
"compose_form.poll.duration": "Tanzagt n tefrant", "compose_form.poll.duration": "Tanzagt n tefrant",
"compose_form.poll.multiple": "Aṭas n ufran",
"compose_form.poll.option_placeholder": "Taxtiṛt {number}", "compose_form.poll.option_placeholder": "Taxtiṛt {number}",
"compose_form.poll.single": "Fren yiwen", "compose_form.poll.single": "Fren yiwen",
"compose_form.publish": "Suffeɣ", "compose_form.publish": "Suffeɣ",
@ -187,17 +191,20 @@
"explore.trending_links": "Isallen", "explore.trending_links": "Isallen",
"explore.trending_statuses": "Tisuffaɣ", "explore.trending_statuses": "Tisuffaɣ",
"explore.trending_tags": "Ihacṭagen", "explore.trending_tags": "Ihacṭagen",
"filter_modal.added.review_and_configure_title": "Iɣewwaṛen n imzizdig",
"filter_modal.added.settings_link": "asebter n yiɣewwaṛen", "filter_modal.added.settings_link": "asebter n yiɣewwaṛen",
"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",
"firehose.all": "Akk", "firehose.all": "Akk",
"firehose.local": "Deg uqeddac-ayi", "firehose.local": "Deg uqeddac-ayi",
"firehose.remote": "Iqeddacen nniḍen",
"follow_request.authorize": "Ssireg", "follow_request.authorize": "Ssireg",
"follow_request.reject": "Agi", "follow_request.reject": "Agi",
"follow_suggestions.dismiss": "Ur ttɛawad ara ad t-id-sekneṭ",
"follow_suggestions.who_to_follow": "Menhu ara ḍefṛeḍ", "follow_suggestions.who_to_follow": "Menhu ara ḍefṛeḍ",
"followed_tags": "Ihacṭagen yettwaḍfaren", "followed_tags": "Ihacṭagen yettwaḍfaren",
"footer.about": "Ɣef", "footer.about": "Ɣef",
"footer.directory": "Akaram n imaɣnuten", "footer.directory": "Akaram n imeɣna",
"footer.get_app": "Awi-d asnas", "footer.get_app": "Awi-d asnas",
"footer.invite": "Ɛreḍ-d kra n yimdanen", "footer.invite": "Ɛreḍ-d kra n yimdanen",
"footer.keyboard_shortcuts": "Inegzumen n unasiw", "footer.keyboard_shortcuts": "Inegzumen n unasiw",
@ -221,9 +228,12 @@
"home.column_settings.show_reblogs": "Ssken-d beṭṭu", "home.column_settings.show_reblogs": "Ssken-d beṭṭu",
"home.column_settings.show_replies": "Ssken-d tiririyin", "home.column_settings.show_replies": "Ssken-d tiririyin",
"home.hide_announcements": "Ffer ulɣuyen", "home.hide_announcements": "Ffer ulɣuyen",
"home.pending_critical_update.body": "Ma ulac aɣilif, leqqem aqeddac-ik Mastodon akken kan tzemreḍ !",
"home.show_announcements": "Ssken-d ulɣuyen", "home.show_announcements": "Ssken-d ulɣuyen",
"interaction_modal.no_account_yet": "Ulac-ik·ikem deg Maṣṭudun?", "interaction_modal.no_account_yet": "Ulac-ik·ikem deg Maṣṭudun?",
"interaction_modal.on_another_server": "Deg uqeddac nniḍen",
"interaction_modal.on_this_server": "Deg uqeddac-ayi", "interaction_modal.on_this_server": "Deg uqeddac-ayi",
"interaction_modal.sign_in": "Ur tekcimeḍ ara ɣer uqeddac-a. Anda yella umiḍan-ik·im ?",
"interaction_modal.title.follow": "Ḍfer {name}", "interaction_modal.title.follow": "Ḍfer {name}",
"intervals.full.days": "{number, plural, one {# n wass} other {# n wussan}}", "intervals.full.days": "{number, plural, one {# n wass} other {# n wussan}}",
"intervals.full.hours": "{number, plural, one {# n usarag} other {# n yesragen}}", "intervals.full.hours": "{number, plural, one {# n usarag} other {# n yesragen}}",
@ -351,12 +361,15 @@
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.display_name": "Isem ara d-yettwaskanen", "onboarding.profile.display_name": "Isem ara d-yettwaskanen",
"onboarding.share.message": "Nekk d {username} deg #Mastodon! Ḍfer iyi-d sya {url}",
"onboarding.share.title": "Bḍu amaɣnu-inek·inem", "onboarding.share.title": "Bḍu amaɣnu-inek·inem",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.start.skip": "Want to skip right ahead?", "onboarding.start.skip": "Want to skip right ahead?",
"onboarding.start.title": "Tseggmeḍ-tt !",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
"onboarding.steps.publish_status.body": "Say hello to the world.", "onboarding.steps.publish_status.body": "Say hello to the world.",
"onboarding.steps.publish_status.title": "Aru tasuffeɣt-inek·inem tamezwarutt",
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
"onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
@ -371,7 +384,10 @@
"poll_button.add_poll": "Rnu asenqed", "poll_button.add_poll": "Rnu asenqed",
"poll_button.remove_poll": "Kkes asenqed", "poll_button.remove_poll": "Kkes asenqed",
"privacy.change": "Seggem tabaḍnit n yizen", "privacy.change": "Seggem tabaḍnit n yizen",
"privacy.direct.long": "Wid akk i d-yettwabdaren deg tuffeɣt",
"privacy.private.long": "Ala wid i k-yeṭṭafaṛen",
"privacy.private.short": "Imeḍfaren", "privacy.private.short": "Imeḍfaren",
"privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s",
"privacy.public.short": "Azayez", "privacy.public.short": "Azayez",
"privacy_policy.title": "Tasertit tabaḍnit", "privacy_policy.title": "Tasertit tabaḍnit",
"refresh": "Smiren", "refresh": "Smiren",
@ -404,9 +420,14 @@
"report_notification.categories.other": "Ayen nniḍen", "report_notification.categories.other": "Ayen nniḍen",
"report_notification.categories.spam": "Aspam", "report_notification.categories.spam": "Aspam",
"report_notification.open": "Ldi aneqqis", "report_notification.open": "Ldi aneqqis",
"search.no_recent_searches": "Ulac inadiyen ineggura",
"search.placeholder": "Nadi", "search.placeholder": "Nadi",
"search.search_or_paste": "Nadi neɣ senṭeḍ URL", "search.search_or_paste": "Nadi neɣ senṭeḍ URL",
"search_popout.language_code": "Tangalt ISO n tutlayt",
"search_popout.options": "Iwellihen n unadi",
"search_popout.recent": "Inadiyen ineggura",
"search_popout.user": "amseqdac", "search_popout.user": "amseqdac",
"search_results.accounts": "Imeɣna",
"search_results.all": "Akk", "search_results.all": "Akk",
"search_results.hashtags": "Ihacṭagen", "search_results.hashtags": "Ihacṭagen",
"search_results.see_all": "Wali-ten akk", "search_results.see_all": "Wali-ten akk",
@ -471,7 +492,7 @@
"timeline_hint.resources.followers": "Imeḍfaṛen", "timeline_hint.resources.followers": "Imeḍfaṛen",
"timeline_hint.resources.follows": "T·Yeṭafaṛ", "timeline_hint.resources.follows": "T·Yeṭafaṛ",
"timeline_hint.resources.statuses": "Tisuffaɣ tiqdimin", "timeline_hint.resources.statuses": "Tisuffaɣ tiqdimin",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", "trends.counter_by_accounts": "{count, plural, one {{counter} n wemdan} other {{counter} n medden}} deg {days, plural, one {ass} other {{days} n wussan}} iɛeddan",
"trends.trending_now": "Ayen mucaɛen tura", "trends.trending_now": "Ayen mucaɛen tura",
"ui.beforeunload": "Arewway-ik·im ad iruḥ ma yella tefeɣ-d deg Maṣṭudun.", "ui.beforeunload": "Arewway-ik·im ad iruḥ ma yella tefeɣ-d deg Maṣṭudun.",
"units.short.billion": "{count}B", "units.short.billion": "{count}B",

View file

@ -212,7 +212,7 @@
"emoji_button.custom": "사용자 지정", "emoji_button.custom": "사용자 지정",
"emoji_button.flags": "깃발", "emoji_button.flags": "깃발",
"emoji_button.food": "음식과 마실것", "emoji_button.food": "음식과 마실것",
"emoji_button.label": "에모지 추가", "emoji_button.label": "에모지 추가",
"emoji_button.nature": "자연", "emoji_button.nature": "자연",
"emoji_button.not_found": "해당하는 에모지가 없습니다", "emoji_button.not_found": "해당하는 에모지가 없습니다",
"emoji_button.objects": "물건", "emoji_button.objects": "물건",
@ -536,7 +536,7 @@
"privacy.public.long": "마스토돈 내외 모두", "privacy.public.long": "마스토돈 내외 모두",
"privacy.public.short": "공개", "privacy.public.short": "공개",
"privacy.unlisted.additional": "공개와 똑같지만 게시물이 실시간 피드나 해시태그, 둘러보기, (계정 설정에서 허용했더라도) 마스토돈 검색에서 제외됩니다.", "privacy.unlisted.additional": "공개와 똑같지만 게시물이 실시간 피드나 해시태그, 둘러보기, (계정 설정에서 허용했더라도) 마스토돈 검색에서 제외됩니다.",
"privacy.unlisted.long": "더 적은 알고리즘 팡파", "privacy.unlisted.long": "더 적은 알고리즘 팡파",
"privacy.unlisted.short": "조용한 공개", "privacy.unlisted.short": "조용한 공개",
"privacy_policy.last_updated": "{date}에 마지막으로 업데이트됨", "privacy_policy.last_updated": "{date}에 마지막으로 업데이트됨",
"privacy_policy.title": "개인정보처리방침", "privacy_policy.title": "개인정보처리방침",

View file

@ -277,7 +277,11 @@
"follow_request.authorize": "Benarkan", "follow_request.authorize": "Benarkan",
"follow_request.reject": "Tolak", "follow_request.reject": "Tolak",
"follow_requests.unlocked_explanation": "Walaupun akaun anda tidak dikunci, kakitangan {domain} merasakan anda mungkin ingin menyemak permintaan ikutan daripada akaun ini secara manual.", "follow_requests.unlocked_explanation": "Walaupun akaun anda tidak dikunci, kakitangan {domain} merasakan anda mungkin ingin menyemak permintaan ikutan daripada akaun ini secara manual.",
"follow_suggestions.curated_suggestion": "",
"follow_suggestions.dismiss": "Jangan papar lagi", "follow_suggestions.dismiss": "Jangan papar lagi",
"follow_suggestions.hints.featured": "Profil{domain.",
"follow_suggestions.hints.friends_of_friends": "This profile is popular among the people you follow.",
"follow_suggestions.hints.most_followed": ".",
"follow_suggestions.personalized_suggestion": "Cadangan peribadi", "follow_suggestions.personalized_suggestion": "Cadangan peribadi",
"follow_suggestions.popular_suggestion": "Cadangan terkenal", "follow_suggestions.popular_suggestion": "Cadangan terkenal",
"follow_suggestions.view_all": "Lihat semua", "follow_suggestions.view_all": "Lihat semua",

View file

@ -40,7 +40,7 @@
"account.following_counter": "{count, plural, one {Fylgjer {counter}} other {Fylgjer {counter}}}", "account.following_counter": "{count, plural, one {Fylgjer {counter}} other {Fylgjer {counter}}}",
"account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.", "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.",
"account.go_to_profile": "Gå til profil", "account.go_to_profile": "Gå til profil",
"account.hide_reblogs": "Skjul framhevingar frå @{name}", "account.hide_reblogs": "Gøym framhevingar frå @{name}",
"account.in_memoriam": "Til minne om.", "account.in_memoriam": "Til minne om.",
"account.joined_short": "Vart med", "account.joined_short": "Vart med",
"account.languages": "Endre språktingingar", "account.languages": "Endre språktingingar",
@ -113,7 +113,7 @@
"column.community": "Lokal tidsline", "column.community": "Lokal tidsline",
"column.direct": "Private omtaler", "column.direct": "Private omtaler",
"column.directory": "Sjå gjennom profilar", "column.directory": "Sjå gjennom profilar",
"column.domain_blocks": "Skjulte domene", "column.domain_blocks": "Blokkerte domene",
"column.favourites": "Favorittar", "column.favourites": "Favorittar",
"column.firehose": "Tidslinjer", "column.firehose": "Tidslinjer",
"column.follow_requests": "Fylgjeførespurnadar", "column.follow_requests": "Fylgjeførespurnadar",
@ -124,7 +124,7 @@
"column.pins": "Festa tut", "column.pins": "Festa tut",
"column.public": "Samla tidsline", "column.public": "Samla tidsline",
"column_back_button.label": "Attende", "column_back_button.label": "Attende",
"column_header.hide_settings": "Gøym innstillingar", "column_header.hide_settings": "Gøym innstillingane",
"column_header.moveLeft_settings": "Flytt kolonne til venstre", "column_header.moveLeft_settings": "Flytt kolonne til venstre",
"column_header.moveRight_settings": "Flytt kolonne til høgre", "column_header.moveRight_settings": "Flytt kolonne til høgre",
"column_header.pin": "Fest", "column_header.pin": "Fest",
@ -171,14 +171,14 @@
"confirmations.delete_list.message": "Er du sikker på at du vil sletta denne lista for alltid?", "confirmations.delete_list.message": "Er du sikker på at du vil sletta denne lista for alltid?",
"confirmations.discard_edit_media.confirm": "Forkast", "confirmations.discard_edit_media.confirm": "Forkast",
"confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller førehandsvisinga. Vil du forkasta dei likevel?", "confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller førehandsvisinga. Vil du forkasta dei likevel?",
"confirmations.domain_block.confirm": "Skjul alt frå domenet", "confirmations.domain_block.confirm": "Blokker heile domenet",
"confirmations.domain_block.message": "Er du heilt, heilt sikker på at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og føretrekt med nokre få målretta blokkeringar eller målbindingar. Du kjem ikkje til å sjå innhald frå domenet i fødererte tidsliner eller i varsla dine. Fylgjarane dine frå domenet vert fjerna.", "confirmations.domain_block.message": "Er du heilt, heilt sikker på at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og føretrekt med nokre få målretta blokkeringar eller målbindingar. Du kjem ikkje til å sjå innhald frå domenet i fødererte tidsliner eller i varsla dine. Fylgjarane dine frå domenet vert fjerna.",
"confirmations.edit.confirm": "Rediger", "confirmations.edit.confirm": "Rediger",
"confirmations.edit.message": "Å redigera no vil overskriva den meldinga du er i ferd med å skriva. Er du sikker på at du vil halda fram?", "confirmations.edit.message": "Å redigera no vil overskriva den meldinga du er i ferd med å skriva. Er du sikker på at du vil halda fram?",
"confirmations.logout.confirm": "Logg ut", "confirmations.logout.confirm": "Logg ut",
"confirmations.logout.message": "Er du sikker på at du vil logga ut?", "confirmations.logout.message": "Er du sikker på at du vil logga ut?",
"confirmations.mute.confirm": "Målbind", "confirmations.mute.confirm": "Målbind",
"confirmations.mute.explanation": "Dette vil skjula innlegg som kjem frå og som nemner dei, men vil framleis la dei sjå innlegga dine og fylgje deg.", "confirmations.mute.explanation": "Dette vil gøyma innlegga deira og innlegg som nemner dei, men dei vil framleis kunna sjå innlegga dine og fylgja deg.",
"confirmations.mute.message": "Er du sikker på at du vil målbinda {name}?", "confirmations.mute.message": "Er du sikker på at du vil målbinda {name}?",
"confirmations.redraft.confirm": "Slett & skriv på nytt", "confirmations.redraft.confirm": "Slett & skriv på nytt",
"confirmations.redraft.message": "Er du sikker på at du vil sletta denne statusen og skriva han på nytt? Då misser du favorittar og framhevingar, og svar til det opprinnelege innlegget vert foreldrelause.", "confirmations.redraft.message": "Er du sikker på at du vil sletta denne statusen og skriva han på nytt? Då misser du favorittar og framhevingar, og svar til det opprinnelege innlegget vert foreldrelause.",
@ -230,7 +230,7 @@
"empty_column.bookmarked_statuses": "Du har ikkje lagra noko bokmerke enno. Når du set bokmerke på eit innlegg, dukkar det opp her.", "empty_column.bookmarked_statuses": "Du har ikkje lagra noko bokmerke enno. Når du set bokmerke på eit innlegg, dukkar det opp her.",
"empty_column.community": "Den lokale tidslina er tom. Skriv noko offentleg å få ballen til å rulle!", "empty_column.community": "Den lokale tidslina er tom. Skriv noko offentleg å få ballen til å rulle!",
"empty_column.direct": "Du har ingen private omtaler enda. Etter du har sendt eller mottatt en, så vil den dukke opp her.", "empty_column.direct": "Du har ingen private omtaler enda. Etter du har sendt eller mottatt en, så vil den dukke opp her.",
"empty_column.domain_blocks": "Det er ingen skjulte domene til no.", "empty_column.domain_blocks": "Det er ingen blokkerte domene enno.",
"empty_column.explore_statuses": "Ingenting er i støytet nett no. Prøv igjen seinare!", "empty_column.explore_statuses": "Ingenting er i støytet nett no. Prøv igjen seinare!",
"empty_column.favourited_statuses": "Du har ingen favoritt-statusar ennå. Når du merkjer ein som favoritt, dukkar han opp her.", "empty_column.favourited_statuses": "Du har ingen favoritt-statusar ennå. Når du merkjer ein som favoritt, dukkar han opp her.",
"empty_column.favourites": "Ingen har merkt denne statusen som favoritt enno. Når nokon gjer det, dukkar dei opp her.", "empty_column.favourites": "Ingen har merkt denne statusen som favoritt enno. Når nokon gjer det, dukkar dei opp her.",
@ -277,7 +277,13 @@
"follow_request.authorize": "Autoriser", "follow_request.authorize": "Autoriser",
"follow_request.reject": "Avvis", "follow_request.reject": "Avvis",
"follow_requests.unlocked_explanation": "Sjølv om kontoen din ikkje er låst tenkte dei som driv {domain} at du kanskje ville gå gjennom førespurnadar frå desse kontoane manuelt.", "follow_requests.unlocked_explanation": "Sjølv om kontoen din ikkje er låst tenkte dei som driv {domain} at du kanskje ville gå gjennom førespurnadar frå desse kontoane manuelt.",
"follow_suggestions.curated_suggestion": "Utvalt av staben",
"follow_suggestions.dismiss": "Ikkje vis igjen", "follow_suggestions.dismiss": "Ikkje vis igjen",
"follow_suggestions.hints.featured": "Denne profilen er handplukka av folka på {domain}.",
"follow_suggestions.hints.friends_of_friends": "Denne profilen er populær hjå dei du fylgjer.",
"follow_suggestions.hints.most_followed": "Mange på {domain} fylgjer denne profilen.",
"follow_suggestions.hints.most_interactions": "Denne profilen har nyss fått mykje merksemd på {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Denne profilen liknar på dei andre profilane du har fylgt i det siste.",
"follow_suggestions.personalized_suggestion": "Personleg forslag", "follow_suggestions.personalized_suggestion": "Personleg forslag",
"follow_suggestions.popular_suggestion": "Populært forslag", "follow_suggestions.popular_suggestion": "Populært forslag",
"follow_suggestions.view_all": "Vis alle", "follow_suggestions.view_all": "Vis alle",
@ -395,7 +401,7 @@
"media_gallery.toggle_visible": "{number, plural, one {Skjul bilete} other {Skjul bilete}}", "media_gallery.toggle_visible": "{number, plural, one {Skjul bilete} other {Skjul bilete}}",
"moved_to_account_banner.text": "Kontoen din, {disabledAccount} er for tida deaktivert fordi du har flytta til {movedToAccount}.", "moved_to_account_banner.text": "Kontoen din, {disabledAccount} er for tida deaktivert fordi du har flytta til {movedToAccount}.",
"mute_modal.duration": "Varigheit", "mute_modal.duration": "Varigheit",
"mute_modal.hide_notifications": "Skjul varsel frå denne brukaren?", "mute_modal.hide_notifications": "Gøym varsel frå denne brukaren?",
"mute_modal.indefinite": "På ubestemt tid", "mute_modal.indefinite": "På ubestemt tid",
"navigation_bar.about": "Om", "navigation_bar.about": "Om",
"navigation_bar.advanced_interface": "Opne i avansert nettgrensesnitt", "navigation_bar.advanced_interface": "Opne i avansert nettgrensesnitt",
@ -479,7 +485,8 @@
"onboarding.follows.empty": "Me kan ikkje visa deg nokon resultat no. Du kan prøva å søkja eller bla gjennom utforsk-sida for å finna folk å fylgja, eller du kan prøva att seinare.", "onboarding.follows.empty": "Me kan ikkje visa deg nokon resultat no. Du kan prøva å søkja eller bla gjennom utforsk-sida for å finna folk å fylgja, eller du kan prøva att seinare.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.discoverable": "Gjør min profil synlig", "onboarding.profile.discoverable": "Gjer profilen min synleg",
"onboarding.profile.discoverable_hint": "Når du vel å gjera profilen din synleg på Mastodon, vil innlegga dine syna i søkjeresultat og populære innlegg, og profilen din kan bli føreslegen for folk med liknande interesser som deg.",
"onboarding.profile.display_name": "Synleg namn", "onboarding.profile.display_name": "Synleg namn",
"onboarding.profile.display_name_hint": "Det fulle namnet eller kallenamnet ditt…", "onboarding.profile.display_name_hint": "Det fulle namnet eller kallenamnet ditt…",
"onboarding.profile.lead": "Du kan alltid fullføra dette seinare i innstillingane, og der er det endå fleire tilpassingsalternativ.", "onboarding.profile.lead": "Du kan alltid fullføra dette seinare i innstillingane, og der er det endå fleire tilpassingsalternativ.",
@ -528,11 +535,12 @@
"privacy.private.short": "Følgjarar", "privacy.private.short": "Følgjarar",
"privacy.public.long": "Kven som helst på og av Mastodon", "privacy.public.long": "Kven som helst på og av Mastodon",
"privacy.public.short": "Offentleg", "privacy.public.short": "Offentleg",
"privacy.unlisted.additional": "Dette er akkurat som offentleg, bortsett frå at innlegga ikkje dukkar opp i direktestraumar eller merkelappar, i oppdagingar eller Mastodon-søk, sjølv om du har sagt ja til at kontoen skal vera synleg.",
"privacy.unlisted.long": "Færre algoritmiske fanfarar", "privacy.unlisted.long": "Færre algoritmiske fanfarar",
"privacy.unlisted.short": "Stille offentleg", "privacy.unlisted.short": "Stille offentleg",
"privacy_policy.last_updated": "Sist oppdatert {date}", "privacy_policy.last_updated": "Sist oppdatert {date}",
"privacy_policy.title": "Personvernsreglar", "privacy_policy.title": "Personvernsreglar",
"recommended": "Anbefalt", "recommended": "Tilrådd",
"refresh": "Oppdater", "refresh": "Oppdater",
"regeneration_indicator.label": "Lastar…", "regeneration_indicator.label": "Lastar…",
"regeneration_indicator.sublabel": "Heimetidslina di vert førebudd!", "regeneration_indicator.sublabel": "Heimetidslina di vert førebudd!",
@ -605,7 +613,7 @@
"search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.quick_action.status_search": "Innlegg som samsvarer med {x}",
"search.search_or_paste": "Søk eller lim inn URL", "search.search_or_paste": "Søk eller lim inn URL",
"search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.", "search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg på {domain}.",
"search_popout.full_text_search_logged_out_message": "Bare tilgjengelig når man er logget inn.", "search_popout.full_text_search_logged_out_message": "Berre tilgjengeleg når du er logga inn.",
"search_popout.language_code": "ISO-språkkode", "search_popout.language_code": "ISO-språkkode",
"search_popout.options": "Søkjealternativ", "search_popout.options": "Søkjealternativ",
"search_popout.quick_actions": "Hurtighandlinger", "search_popout.quick_actions": "Hurtighandlinger",
@ -654,7 +662,7 @@
"status.load_more": "Last inn meir", "status.load_more": "Last inn meir",
"status.media.open": "Klikk for å opne", "status.media.open": "Klikk for å opne",
"status.media.show": "Klikk for å vise", "status.media.show": "Klikk for å vise",
"status.media_hidden": "Medium gøymd", "status.media_hidden": "Mediet er gøymt",
"status.mention": "Nemn @{name}", "status.mention": "Nemn @{name}",
"status.more": "Meir", "status.more": "Meir",
"status.mute": "Målbind @{name}", "status.mute": "Målbind @{name}",

View file

@ -277,6 +277,7 @@
"follow_request.authorize": "Povoľ prístup", "follow_request.authorize": "Povoľ prístup",
"follow_request.reject": "Odmietni", "follow_request.reject": "Odmietni",
"follow_requests.unlocked_explanation": "Síce Váš učet nie je uzamknutý, ale {domain} tím si myslel že môžete chcieť skontrolovať žiadosti o sledovanie z týchto účtov manuálne.", "follow_requests.unlocked_explanation": "Síce Váš učet nie je uzamknutý, ale {domain} tím si myslel že môžete chcieť skontrolovať žiadosti o sledovanie z týchto účtov manuálne.",
"follow_suggestions.curated_suggestion": "Staff pick",
"follow_suggestions.dismiss": "Znovu nezobrazuj", "follow_suggestions.dismiss": "Znovu nezobrazuj",
"follow_suggestions.personalized_suggestion": "Prispôsobené odporúčania", "follow_suggestions.personalized_suggestion": "Prispôsobené odporúčania",
"follow_suggestions.popular_suggestion": "Populárne návrhy", "follow_suggestions.popular_suggestion": "Populárne návrhy",

View file

@ -2,25 +2,25 @@
"about.blocks": "Siū kuán-tsè ê su-hāu-khì", "about.blocks": "Siū kuán-tsè ê su-hāu-khì",
"about.contact": "Liân-lo̍k:", "about.contact": "Liân-lo̍k:",
"about.disclaimer": "Ling-khí-tshiūnn sī tsi̍t-ê khai-guân nńg-théi ê siong-phiau sī Mastodon gGmbH.", "about.disclaimer": "Ling-khí-tshiūnn sī tsi̍t-ê khai-guân nńg-théi ê siong-phiau sī Mastodon gGmbH.",
"account.badges.bot": "Bot", "account.badges.bot": "Tsū-tōng-ê",
"account.cancel_follow_request": "Withdraw follow request", "account.cancel_follow_request": "Mài-koh tui-tsong",
"account.media": "Mûi-thé", "account.media": "Mûi-thé",
"account.mention": "Thê-khí @{name}", "account.mention": "Thê-khí @{name}",
"account.posts": "Toots", "account.posts": "Huah-siann",
"account.posts_with_replies": "Toots and replies", "account.posts_with_replies": "Huah-siann kah huê-ìng",
"account.requested": "Awaiting approval", "account.requested": "Tán-thāi phue-tsún",
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", "account.statuses_counter": "{count, plural, one {{counter} Huah-siann} other {{counter} Huah-siann}}",
"account_note.placeholder": "Click to add a note", "account_note.placeholder": "Tiám tsi̍t-ē ka-thiam pī-tsù",
"column.pins": "Pinned toot", "column.pins": "Tah thâu-tsîng ê huah-siann",
"community.column_settings.media_only": "Media only", "community.column_settings.media_only": "Kan-na muî-thé",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.encryption_warning": "Tī Mastodon tah huah-siann m̄-sī tuan-tuì-tuan ka-pì ê. M̄-thang tī Mastodon hun-hióng jīm-hô bín-kám ê tsū-sìn.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.hashtag_warning": "Tsit-ê huah-siann in-uī m̄-sī kong-khai ê, sóo-í buē tī jīm-hô tsú-tê piau-tshiam hián-sī. Kan-na kong-khai ê huah-siann ē-tàng hōo tsú-tê piau-tshiam tshâ-tshuē.",
"compose_form.placeholder": "What is on your mind?", "compose_form.placeholder": "Lí teh siūnn siánn?",
"compose_form.publish_form": "Publish", "compose_form.publish_form": "Huah--tshut-khì",
"compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.marked": "Î-tû luē-iông kíng-kò",
"compose_form.spoiler.unmarked": "Text is not hidden", "compose_form.spoiler.unmarked": "Tsing-ka luē-iông kíng-kò",
"confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete.message": "Lí kám bueh thâi-tiāu tsi̍t-ē huah-siann?",
"confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.confirm": "Hong-só tsíng-kò bāng-hi̍k",
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
"embed.instructions": "Embed this status on your website by copying the code below.", "embed.instructions": "Embed this status on your website by copying the code below.",
@ -46,7 +46,7 @@
"keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.notifications": "to open notifications column",
"keyboard_shortcuts.open_media": "to open media", "keyboard_shortcuts.open_media": "Khui muî-thé",
"keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.reply": "to reply",

View file

@ -1,5 +1,5 @@
{ {
"about.blocks": "เซิร์ฟเวอร์ที่มีการควบคุม", "about.blocks": "เซิร์ฟเวอร์ที่มีการกลั่นกรอง",
"about.contact": "ติดต่อ:", "about.contact": "ติดต่อ:",
"about.disclaimer": "Mastodon เป็นซอฟต์แวร์เสรี โอเพนซอร์ส และเครื่องหมายการค้าของ Mastodon gGmbH", "about.disclaimer": "Mastodon เป็นซอฟต์แวร์เสรี โอเพนซอร์ส และเครื่องหมายการค้าของ Mastodon gGmbH",
"about.domain_blocks.no_reason_available": "เหตุผลไม่พร้อมใช้งาน", "about.domain_blocks.no_reason_available": "เหตุผลไม่พร้อมใช้งาน",
@ -380,7 +380,7 @@
"lightbox.next": "ถัดไป", "lightbox.next": "ถัดไป",
"lightbox.previous": "ก่อนหน้า", "lightbox.previous": "ก่อนหน้า",
"limited_account_hint.action": "แสดงโปรไฟล์ต่อไป", "limited_account_hint.action": "แสดงโปรไฟล์ต่อไป",
"limited_account_hint.title": "มีการซ่อนโปรไฟล์นี้โดยผู้ควบคุมของ {domain}", "limited_account_hint.title": "มีการซ่อนโปรไฟล์นี้โดยผู้กลั่นกรองของ {domain}",
"link_preview.author": "โดย {name}", "link_preview.author": "โดย {name}",
"lists.account.add": "เพิ่มไปยังรายการ", "lists.account.add": "เพิ่มไปยังรายการ",
"lists.account.remove": "เอาออกจากรายการ", "lists.account.remove": "เอาออกจากรายการ",
@ -637,9 +637,9 @@
"sign_in_banner.sign_in": "เข้าสู่ระบบ", "sign_in_banner.sign_in": "เข้าสู่ระบบ",
"sign_in_banner.sso_redirect": "เข้าสู่ระบบหรือลงทะเบียน", "sign_in_banner.sso_redirect": "เข้าสู่ระบบหรือลงทะเบียน",
"sign_in_banner.text": "เข้าสู่ระบบเพื่อติดตามโปรไฟล์หรือแฮชแท็ก ชื่นชอบ แชร์ และตอบกลับโพสต์ คุณยังสามารถโต้ตอบจากบัญชีของคุณในเซิร์ฟเวอร์อื่น", "sign_in_banner.text": "เข้าสู่ระบบเพื่อติดตามโปรไฟล์หรือแฮชแท็ก ชื่นชอบ แชร์ และตอบกลับโพสต์ คุณยังสามารถโต้ตอบจากบัญชีของคุณในเซิร์ฟเวอร์อื่น",
"status.admin_account": "เปิดส่วนติดต่อการควบคุมสำหรับ @{name}", "status.admin_account": "เปิดส่วนติดต่อการกลั่นกรองสำหรับ @{name}",
"status.admin_domain": "เปิดส่วนติดต่อการควบคุมสำหรับ {domain}", "status.admin_domain": "เปิดส่วนติดต่อการกลั่นกรองสำหรับ {domain}",
"status.admin_status": "เปิดโพสต์นี้ในส่วนติดต่อการควบคุม", "status.admin_status": "เปิดโพสต์นี้ในส่วนติดต่อการกลั่นกรอง",
"status.block": "ปิดกั้น @{name}", "status.block": "ปิดกั้น @{name}",
"status.bookmark": "เพิ่มที่คั่นหน้า", "status.bookmark": "เพิ่มที่คั่นหน้า",
"status.cancel_reblog_private": "เลิกดัน", "status.cancel_reblog_private": "เลิกดัน",

View file

@ -214,7 +214,7 @@
"emoji_button.food": "Yiyecek ve İçecek", "emoji_button.food": "Yiyecek ve İçecek",
"emoji_button.label": "İfade ekle", "emoji_button.label": "İfade ekle",
"emoji_button.nature": "Doğa", "emoji_button.nature": "Doğa",
"emoji_button.not_found": "İfade yok!! (╯°□°)╯︵ ┻━┻", "emoji_button.not_found": "Eşleşen emoji yok",
"emoji_button.objects": "Nesneler", "emoji_button.objects": "Nesneler",
"emoji_button.people": "Kullanıcılar", "emoji_button.people": "Kullanıcılar",
"emoji_button.recent": "Sık kullanılan", "emoji_button.recent": "Sık kullanılan",
@ -348,7 +348,7 @@
"keyboard_shortcuts.description": "Açıklama", "keyboard_shortcuts.description": "Açıklama",
"keyboard_shortcuts.direct": "özel değinmeler sütununu açmak için", "keyboard_shortcuts.direct": "özel değinmeler sütununu açmak için",
"keyboard_shortcuts.down": "Listede aşağıya inmek için", "keyboard_shortcuts.down": "Listede aşağıya inmek için",
"keyboard_shortcuts.enter": "gönderiyi aç", "keyboard_shortcuts.enter": "Gönderiyi açınız",
"keyboard_shortcuts.favourite": "Gönderiyi favorilerine ekle", "keyboard_shortcuts.favourite": "Gönderiyi favorilerine ekle",
"keyboard_shortcuts.favourites": "Gözde listeni aç", "keyboard_shortcuts.favourites": "Gözde listeni aç",
"keyboard_shortcuts.federated": "Federe akışı aç", "keyboard_shortcuts.federated": "Federe akışı aç",

View file

@ -40,7 +40,7 @@ function render(
ui: React.ReactElement, ui: React.ReactElement,
{ locale = 'en', signedIn = true, ...renderOptions } = {}, { locale = 'en', signedIn = true, ...renderOptions } = {},
) { ) {
const Wrapper = (props: { children: React.ReactElement }) => { const Wrapper = (props: { children: React.ReactNode }) => {
return ( return (
<MemoryRouter> <MemoryRouter>
<IntlProvider locale={locale}> <IntlProvider locale={locale}>

View file

@ -4,7 +4,7 @@ import { createRoot } from 'react-dom/client';
import ready from '../mastodon/ready'; import ready from '../mastodon/ready';
ready(() => { ready(() => {
[].forEach.call(document.querySelectorAll('[data-admin-component]'), element => { document.querySelectorAll('[data-admin-component]').forEach(element => {
const componentName = element.getAttribute('data-admin-component'); const componentName = element.getAttribute('data-admin-component');
const componentProps = JSON.parse(element.getAttribute('data-props')); const componentProps = JSON.parse(element.getAttribute('data-props'));

View file

@ -57,11 +57,11 @@ function loaded() {
return messageFormat.format(values); return messageFormat.format(values);
}; };
[].forEach.call(document.querySelectorAll('.emojify'), (content) => { document.querySelectorAll('.emojify').forEach((content) => {
content.innerHTML = emojify(content.innerHTML); content.innerHTML = emojify(content.innerHTML);
}); });
[].forEach.call(document.querySelectorAll('time.formatted'), (content) => { document.querySelectorAll('time.formatted').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
const formattedDate = dateTimeFormat.format(datetime); const formattedDate = dateTimeFormat.format(datetime);
@ -78,7 +78,7 @@ function loaded() {
}; };
const todayFormat = new IntlMessageFormat(localeData['relative_format.today'] || 'Today at {time}', locale); const todayFormat = new IntlMessageFormat(localeData['relative_format.today'] || 'Today at {time}', locale);
[].forEach.call(document.querySelectorAll('time.relative-formatted'), (content) => { document.querySelectorAll('time.relative-formatted').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
let formattedContent; let formattedContent;
@ -95,7 +95,7 @@ function loaded() {
content.textContent = formattedContent; content.textContent = formattedContent;
}); });
[].forEach.call(document.querySelectorAll('time.time-ago'), (content) => { document.querySelectorAll('time.time-ago').forEach((content) => {
const datetime = new Date(content.getAttribute('datetime')); const datetime = new Date(content.getAttribute('datetime'));
const now = new Date(); const now = new Date();
@ -112,8 +112,8 @@ function loaded() {
if (reactComponents.length > 0) { if (reactComponents.length > 0) {
import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container') import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container')
.then(({ default: MediaContainer }) => { .then(({ default: MediaContainer }) => {
[].forEach.call(reactComponents, (component) => { reactComponents.forEach((component) => {
[].forEach.call(component.children, (child) => { Array.from(component.children).forEach((child) => {
component.removeChild(child); component.removeChild(child);
}); });
}); });
@ -169,7 +169,7 @@ function loaded() {
return false; return false;
}); });
[].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => { document.querySelectorAll('.status__content__spoiler-link').forEach((spoilerLink) => {
const statusEl = spoilerLink.parentNode.parentNode; const statusEl = spoilerLink.parentNode.parentNode;
const message = (statusEl.dataset.spoiler === 'expanded') ? (localeData['status.show_less'] || 'Show less') : (localeData['status.show_more'] || 'Show more'); const message = (statusEl.dataset.spoiler === 'expanded') ? (localeData['status.show_less'] || 'Show less') : (localeData['status.show_more'] || 'Show more');
spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format(); spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();

View file

@ -324,6 +324,23 @@ $content-width: 840px;
padding-bottom: 0; padding-bottom: 0;
margin-bottom: 0; margin-bottom: 0;
border-bottom: 0; border-bottom: 0;
.comment {
display: block;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 4px;
&.private-comment {
display: block;
color: $darker-text-color;
}
&.public-comment {
display: block;
color: $secondary-text-color;
}
}
} }
& > p { & > p {
@ -638,16 +655,6 @@ body,
input.button { input.button {
margin: 0 5px 5px 0; margin: 0 5px 5px 0;
} }
.media-spoiler-toggle-buttons {
margin-inline-start: auto;
.button {
overflow: visible;
margin: 0 0 5px 5px;
float: right;
}
}
} }
.back-link { .back-link {
@ -1070,6 +1077,7 @@ a.name-tag,
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: 0; margin-bottom: 0;
word-break: break-word;
} }
&__permissions { &__permissions {

View file

@ -5195,7 +5195,6 @@ a.status-card {
.icon { .icon {
position: absolute; position: absolute;
top: 12px + 2px; top: 12px + 2px;
inset-inline-start: 16px - 2px;
display: inline-block; display: inline-block;
opacity: 0; opacity: 0;
transition: all 100ms linear; transition: all 100ms linear;
@ -5205,11 +5204,16 @@ a.status-card {
color: $darker-text-color; color: $darker-text-color;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
margin-inline-start: 16px - 2px;
&.active { &.active {
pointer-events: auto; pointer-events: auto;
opacity: 1; opacity: 1;
} }
@media screen and (min-width: $no-gap-breakpoint) {
inset-inline-start: 16px - 2px;
}
} }
.icon-search { .icon-search {
@ -5965,6 +5969,7 @@ a.status-card {
.report-modal__comment { .report-modal__comment {
box-sizing: border-box; box-sizing: border-box;
width: 50%; width: 50%;
min-width: 50%;
@media screen and (width <= 480px) { @media screen and (width <= 480px) {
width: 100%; width: 100%;
@ -6033,6 +6038,14 @@ a.status-card {
min-height: 100px; min-height: 100px;
max-height: 50vh; max-height: 50vh;
border: 0; border: 0;
@media screen and (height <= 600px) {
max-height: 20vh;
}
@media screen and (max-width: $no-columns-breakpoint) {
max-height: 20vh;
}
} }
.setting-toggle { .setting-toggle {

View file

@ -1078,6 +1078,7 @@ code {
&__type { &__type {
color: $darker-text-color; color: $darker-text-color;
word-break: break-word;
} }
} }

View file

@ -50,7 +50,7 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics:
WHERE date_trunc('day', media_attachments.created_at)::date = axis.period WHERE date_trunc('day', media_attachments.created_at)::date = axis.period
AND #{account_domain_sql(params[:include_subdomains])} AND #{account_domain_sql(params[:include_subdomains])}
) )
SELECT SUM(size) FROM new_media_attachments SELECT COALESCE(SUM(size), 0) FROM new_media_attachments
) AS value ) AS value
FROM ( FROM (
SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period

View file

@ -34,10 +34,10 @@ class Admin::Metrics::Measure::TagServersMeasure < Admin::Metrics::Measure::Base
INNER JOIN accounts ON statuses.account_id = accounts.id INNER JOIN accounts ON statuses.account_id = accounts.id
WHERE statuses_tags.tag_id = :tag_id WHERE statuses_tags.tag_id = :tag_id
AND statuses.id BETWEEN :earliest_status_id AND :latest_status_id AND statuses.id BETWEEN :earliest_status_id AND :latest_status_id
AND date_trunc('day', statuses.created_at)::date = axis.day AND date_trunc('day', statuses.created_at)::date = axis.period
) )
FROM ( FROM (
SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, ('1 day')::interval) AS day SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period
) as axis ) as axis
SQL SQL
end end

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
module RankedTrend
extend ActiveSupport::Concern
included do
scope :by_rank, -> { order(rank: :desc) }
scope :ranked_below, ->(value) { where(rank: ..value) }
end
class_methods do
def recalculate_ordered_rank
connection
.exec_update(<<~SQL.squish)
UPDATE #{table_name}
SET rank = inner_ordered.calculated_rank
FROM (
SELECT id, row_number() OVER w AS calculated_rank
FROM #{table_name}
WINDOW w AS (
PARTITION BY language
ORDER BY score DESC
)
) inner_ordered
WHERE #{table_name}.id = inner_ordered.id
SQL
end
end
end

View file

@ -12,6 +12,8 @@
# language :string # language :string
# #
class PreviewCardTrend < ApplicationRecord class PreviewCardTrend < ApplicationRecord
include RankedTrend
belongs_to :preview_card belongs_to :preview_card
scope :allowed, -> { where(allowed: true) } scope :allowed, -> { where(allowed: true) }
end end

View file

@ -14,6 +14,8 @@
# #
class StatusTrend < ApplicationRecord class StatusTrend < ApplicationRecord
include RankedTrend
belongs_to :status belongs_to :status
belongs_to :account belongs_to :account

View file

@ -81,12 +81,12 @@ class Trends::Links < Trends::Base
# Now that all trends have up-to-date scores, and all the ones below the threshold have # Now that all trends have up-to-date scores, and all the ones below the threshold have
# been removed, we can recalculate their positions # been removed, we can recalculate their positions
PreviewCardTrend.connection.exec_update('UPDATE preview_card_trends SET rank = t0.calculated_rank FROM (SELECT id, row_number() OVER w AS calculated_rank FROM preview_card_trends WINDOW w AS (PARTITION BY language ORDER BY score DESC)) t0 WHERE preview_card_trends.id = t0.id') PreviewCardTrend.recalculate_ordered_rank
end end
def request_review def request_review
PreviewCardTrend.pluck('distinct language').flat_map do |language| PreviewCardTrend.pluck('distinct language').flat_map do |language|
score_at_threshold = PreviewCardTrend.where(language: language, allowed: true).order(rank: :desc).where('rank <= ?', options[:review_threshold]).first&.score || 0 score_at_threshold = PreviewCardTrend.where(language: language, allowed: true).by_rank.ranked_below(options[:review_threshold]).first&.score || 0
preview_card_trends = PreviewCardTrend.where(language: language, allowed: false).joins(:preview_card) preview_card_trends = PreviewCardTrend.where(language: language, allowed: false).joins(:preview_card)
preview_card_trends.filter_map do |trend| preview_card_trends.filter_map do |trend|

View file

@ -74,12 +74,12 @@ class Trends::Statuses < Trends::Base
# Now that all trends have up-to-date scores, and all the ones below the threshold have # Now that all trends have up-to-date scores, and all the ones below the threshold have
# been removed, we can recalculate their positions # been removed, we can recalculate their positions
StatusTrend.connection.exec_update('UPDATE status_trends SET rank = t0.calculated_rank FROM (SELECT id, row_number() OVER w AS calculated_rank FROM status_trends WINDOW w AS (PARTITION BY language ORDER BY score DESC)) t0 WHERE status_trends.id = t0.id') StatusTrend.recalculate_ordered_rank
end end
def request_review def request_review
StatusTrend.pluck('distinct language').flat_map do |language| StatusTrend.pluck('distinct language').flat_map do |language|
score_at_threshold = StatusTrend.where(language: language, allowed: true).order(rank: :desc).where('rank <= ?', options[:review_threshold]).first&.score || 0 score_at_threshold = StatusTrend.where(language: language, allowed: true).by_rank.ranked_below(options[:review_threshold]).first&.score || 0
status_trends = StatusTrend.where(language: language, allowed: false).joins(:status).includes(status: :account) status_trends = StatusTrend.where(language: language, allowed: false).joins(:status).includes(status: :account)
status_trends.filter_map do |trend| status_trends.filter_map do |trend|

View file

@ -7,6 +7,10 @@
%small %small
- if instance.domain_block - if instance.domain_block
= instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ') = instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ')
- if instance.domain_block.public_comment.present?
%span.comment.public-comment #{t('admin.domain_blocks.public_comment')}: #{instance.domain_block.public_comment}
- if instance.domain_block.private_comment.present?
%span.comment.private-comment #{t('admin.domain_blocks.private_comment')}: #{instance.domain_block.private_comment}
- elsif instance.domain_allow - elsif instance.domain_allow
= t('admin.accounts.whitelisted') = t('admin.accounts.whitelisted')
- else - else

View file

@ -16,7 +16,7 @@
%small= t('accounts.followers', count: account.followers_count).downcase %small= t('accounts.followers', count: account.followers_count).downcase
%td.accounts-table__count %td.accounts-table__count
- if account.last_status_at.present? - if account.last_status_at.present?
%time.time-ago{ datetime: account.last_status_at.to_date.iso8601, title: l(account.last_status_at.to_date) }= l account.last_status_at %time.time-ago{ datetime: account.last_status_at.to_date.iso8601, title: l(account.last_status_at.to_date) }= l account.last_status_at.to_date
- else - else
\- \-
%small= t('accounts.last_active') %small= t('accounts.last_active')

View file

@ -53,3 +53,7 @@ el:
position: position:
elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας
own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας
webhook:
attributes:
events:
invalid_permissions: δεν μπορείτε να συμπεριλάβετε συμβάντα για τα οποία δεν έχετε τα δικαιώματα

View file

@ -795,6 +795,7 @@ be:
disabled: Нікому disabled: Нікому
users: Лакальным карыстальнікам, якія ўвайшлі users: Лакальным карыстальнікам, якія ўвайшлі
registrations: registrations:
moderation_recommandation: Пераканайцеся, што ў вас ёсць адэкватная і аператыўная каманда мадэратараў, перш чым адчыняць рэгістрацыю для ўсіх жадаючых!
preamble: Кантралюйце, хто можа ствараць уліковы запіс на вашым серверы. preamble: Кантралюйце, хто можа ствараць уліковы запіс на вашым серверы.
title: Рэгістрацыя title: Рэгістрацыя
registrations_mode: registrations_mode:
@ -802,6 +803,7 @@ be:
approved: Для рэгістрацыі патрабуецца пацвярджэнне approved: Для рэгістрацыі патрабуецца пацвярджэнне
none: Нікому не магчыма зарэгістравацца none: Нікому не магчыма зарэгістравацца
open: Любому магчыма зарэгістравацца open: Любому магчыма зарэгістравацца
warning_hint: Мы рэкамендуем выкарыстоўваць рэжым "для рэгістрацыі патрабуецца пацвярджэнне", калі вы не ўпэўненыя, што ваша каманда мадэратараў зможа своечасова спраўляцца са спамам і шкоднымі рэгістрацыямі.
security: security:
authorized_fetch: Патрабаваць аўтэнтыфікацыю ад федэратыўных сервераў authorized_fetch: Патрабаваць аўтэнтыфікацыю ад федэратыўных сервераў
authorized_fetch_hint: Патрабаванне аўтэнтыфікацыі ад федэратыўных сервераў дазваляе больш строга выконваць блакіроўкі як на ўзроўні карыстача, так і на ўзроўні сервера. Аднак пры гэтым зніжаецца прадукцыйнасць, памяншаецца ахоп вашых адказаў на допісы і могуць узнікнуць праблемы сумяшчальнасці з некаторымі федэратыўнымі сэрвісамі. Акрамя таго, гэта не перашкодзіць атрымліваць вашыя публічныя допісы і ўліковыя запісы. authorized_fetch_hint: Патрабаванне аўтэнтыфікацыі ад федэратыўных сервераў дазваляе больш строга выконваць блакіроўкі як на ўзроўні карыстача, так і на ўзроўні сервера. Аднак пры гэтым зніжаецца прадукцыйнасць, памяншаецца ахоп вашых адказаў на допісы і могуць узнікнуць праблемы сумяшчальнасці з некаторымі федэратыўнымі сэрвісамі. Акрамя таго, гэта не перашкодзіць атрымліваць вашыя публічныя допісы і ўліковыя запісы.
@ -1002,6 +1004,9 @@ be:
title: Вэбхукі title: Вэбхукі
webhook: Вэбхук webhook: Вэбхук
admin_mailer: admin_mailer:
auto_close_registrations:
body: У сувязі з адсутнасцю актыўнасці мадэратараў у апошні час, рэгістрацыя на %{instance} была аўтаматычна пераведзена ў рэжым, які патрабуе ручной праверкі, каб прадухіліць выкарыстанне %{instance} у якасці платформы для патэнцыйных зламыснікаў. Вы можаце ў любы момант пераключыць яго назад ў рэжым "вольная рэгістрацыя".
subject: Рэгістрацыі для %{instance} былі аўтаматычна пераведзены ў рэжым "патрабуецца пацвярджэнне"
new_appeal: new_appeal:
actions: actions:
delete_statuses: выдаліць іх допісы delete_statuses: выдаліць іх допісы

View file

@ -969,8 +969,8 @@ ca:
webhook: Webhook webhook: Webhook
admin_mailer: admin_mailer:
auto_close_registrations: auto_close_registrations:
body: A causa de la manca d'activitat recent dels moderadors, les altes a %{instance} han passat automàticament a necessitar una revisió manual, per tal d'evitar que %{instance} es faci servir com a plataforma de potencials mals actuants. Podeu revertir-ho a altes obertes en qualsevol moment. body: A causa de la manca d'activitat recent dels moderadors, s'ha passat el procés d'alta de %{instance} al mode de revisió manual, a fi d'evitar que malfactors l'utilitzin com a plataforma. Podeu obrir el procés de registre en qualsevol moment.
subject: Les altes a %{instance} han passat automàticament a necessitar aprovació subject: S'ha passat el procés d'alta de %{instance} al mode de validació manual
new_appeal: new_appeal:
actions: actions:
delete_statuses: eliminar els seus tuts delete_statuses: eliminar els seus tuts

View file

@ -500,7 +500,7 @@ da:
instance_accounts_dimension: Mest fulgte konti instance_accounts_dimension: Mest fulgte konti
instance_accounts_measure: gemte konti instance_accounts_measure: gemte konti
instance_followers_measure: vores følgere dér instance_followers_measure: vores følgere dér
instance_follows_measure: deres følgere r instance_follows_measure: deres følgere her
instance_languages_dimension: Topsprog instance_languages_dimension: Topsprog
instance_media_attachments_measure: gemte medievedhæftninger instance_media_attachments_measure: gemte medievedhæftninger
instance_reports_measure: anmeldelser af dem instance_reports_measure: anmeldelser af dem
@ -1445,7 +1445,7 @@ da:
before: 'Inder der fortsættes, læs venligst disse notater omhyggeligt:' before: 'Inder der fortsættes, læs venligst disse notater omhyggeligt:'
cooldown: Efter flytningen er der en venteperiode, hvor kontoen ikke kan flyttes igen cooldown: Efter flytningen er der en venteperiode, hvor kontoen ikke kan flyttes igen
disabled_account: Efterfølgende er din nuværende konto ikke fuldt funktionsdygtig, der er dog adgang til dataeksport samt genaktivering. disabled_account: Efterfølgende er din nuværende konto ikke fuldt funktionsdygtig, der er dog adgang til dataeksport samt genaktivering.
followers: Denne handling vil flytte alle følgere fra den aktuelle konto til den nye ditto followers: Denne handling vil flytte alle følgere fra den aktuelle konto til den nye konto
only_redirect_html: Alternativt kan du <a href="%{path}">oprette en omdirigering for din profil alene</a>. only_redirect_html: Alternativt kan du <a href="%{path}">oprette en omdirigering for din profil alene</a>.
other_data: Ingen øvrige data flyttes automatisk other_data: Ingen øvrige data flyttes automatisk
redirect: Din nuværende kontoprofil opdateres med en omdirigeringsnotits og ekskluderes fra søgninger redirect: Din nuværende kontoprofil opdateres med en omdirigeringsnotits og ekskluderes fra søgninger

View file

@ -2,16 +2,17 @@
fa: fa:
devise: devise:
confirmations: confirmations:
confirmed: نشانی ایمیل شما با موفقیت تأیید شد. confirmed: نشانی رایانامه‌تان با موفقیت تأیید شد.
send_instructions: تا دقایقی دیگر ایمیلی خواهید گرفت که به شما می‌گوید چگونه باید نشانی ایمیل خود را تأیید کنید. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. send_instructions: تا دقایقی دیگر رایانامه‌ای با دستورالعمل تأیید نشانی رایانامه‌تان دریافت خواهید کرد. اگر این رایانامه را نگرفتید، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید.
send_paranoid_instructions: اگر ایمیل شما در پایگاه دادهٔ ما موجود باشد، تا دقایقی دیگر ایمیلی خواهید گرفت که به شما می‌گوید چگونه باید نشانی ایمیل خود را تأیید کنید. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. send_paranoid_instructions: اگر نشانی رایانامه‌تان در پایگاه داده‌مان وجود داشته باشد، تا دقایقی دیگر تا دقایقی دیگر رایانامه‌ای با دستورالعمل تأیید نشانی رایانامه‌تان دریافت خواهید کرد. اگر این رایانامه را نگرفتید، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید.
failure: failure:
already_authenticated: همین الآن هم وارد شده‌اید. already_authenticated: از پیش وارد شده‌اید.
inactive: حساب شما هنوز فعال نشده است. inactive: هنوز حسابتان فعّال نشده.
invalid: "%{authentication_keys} یا گذرواژه نامعتبر." invalid: "%{authentication_keys} یا گذرواژه نامعتبر."
last_attempt: پیش از آن که حساب شما قفل شود، یک فرصت دیگر دارید. last_attempt: پیش از آن که حساب شما قفل شود، یک فرصت دیگر دارید.
locked: حساب شما قفل شده است. locked: حسابتان قفل شده.
not_found_in_database: "%{authentication_keys} یا گذرواژه نامعتبر." not_found_in_database: "%{authentication_keys} یا گذرواژه نامعتبر."
omniauth_user_creation_failure: خطای ایجاد حسابی برای این هویت.
pending: حساب شما همچنان در دست بررسی است. pending: حساب شما همچنان در دست بررسی است.
timeout: مهلت این ورود شما به سر رسید. برای ادامه، دوباره وارد شوید. timeout: مهلت این ورود شما به سر رسید. برای ادامه، دوباره وارد شوید.
unauthenticated: برای ادامه باید وارد شوید یا ثبت نام کنید. unauthenticated: برای ادامه باید وارد شوید یا ثبت نام کنید.
@ -24,37 +25,42 @@ fa:
explanation_when_pending: شما با این نشانی ایمیل برای %{host} درخواست دعوت‌نامه داده‌اید. اگر ایمیل خود را تأیید کنید، ما درخواست شما را بررسی خواهیم کرد. تا وقتی بررسی تمام نشده، شما نمی‌توانید به حساب خود وارد شوید. اگر درخواست شما رد شود، ما اطلاعاتی را که از شما داریم پاک خواهیم کرد پس نیازی به کاری از سمت شما نخواهد بود. اگر شما چنین درخواستی نداده‌اید، لطفاً این ایمیل را نادیده بگیرید. explanation_when_pending: شما با این نشانی ایمیل برای %{host} درخواست دعوت‌نامه داده‌اید. اگر ایمیل خود را تأیید کنید، ما درخواست شما را بررسی خواهیم کرد. تا وقتی بررسی تمام نشده، شما نمی‌توانید به حساب خود وارد شوید. اگر درخواست شما رد شود، ما اطلاعاتی را که از شما داریم پاک خواهیم کرد پس نیازی به کاری از سمت شما نخواهد بود. اگر شما چنین درخواستی نداده‌اید، لطفاً این ایمیل را نادیده بگیرید.
extra_html: لطفاً همچنین <a href="%{terms_path}">قوانین کارساز</a> و <a href="%{policy_path}">شرایط خدمتمان</a> را بررسی کنید. extra_html: لطفاً همچنین <a href="%{terms_path}">قوانین کارساز</a> و <a href="%{policy_path}">شرایط خدمتمان</a> را بررسی کنید.
subject: 'ماستودون: دستورالعمل تأیید برای %{instance}' subject: 'ماستودون: دستورالعمل تأیید برای %{instance}'
title: تأیید نشانی ایمیل title: تأیید نشانی رایانامه
email_changed: email_changed:
explanation: 'نشانی ایمیل حساب شما تغییر می‌کند به:' explanation: 'نشانی رایانامهٔ حسابتان تغییر می‌کند به:'
extra: اگر شما ایمیل خود را عوض نکردید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر گذرواژه حسابتان را عوض کنید. اگر گذرواژه‌تان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. extra: اگر رایانامه‌تان را عوض نکرده‌اید، ممکن است کسی به حسابتان دسترسی پیدا کرده باشد. لطفاً فوراُ گذرواژه‌تان را عوض کرده و اگر از حسابتان بیرون مانده‌اید با مدیر کارساز تماس بگیرید.
subject: 'ماستودون: نشانی ایمیل عوض شد' subject: 'ماستودون: رایانامه عوض شد'
title: نشانی ایمیل تازه title: نشانی جدید رایانامه
password_change: password_change:
explanation: گذرواژه حساب شما تغییر کرد. explanation: گذرواژهٔ حسابتان عوض شده.
extra: اگر شما گذرواژه حسابتان را تغییر ندادید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر گذرواژه حسابتان را عوض کنید. اگر گذرواژه‌تان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. extra: اگر گذرواژه‌تان را عوض نکرده‌اید، ممکن است کسی به حسابتان دسترسی پیدا کرده باشد. لطفاً فوراُ گذرواژه‌تان را عوض کرده و اگر از حسابتان بیرون مانده‌اید با مدیر کارساز تماس بگیرید.
subject: 'ماستودون: گذرواژه‌تان عوض شد' subject: 'ماستودون: گذرواژه عوض شد'
title: گذرواژه‌تان عوض شد title: گذرواژه عوض شد
reconfirmation_instructions: reconfirmation_instructions:
explanation: نشانی تازه را تأیید کنید تا ایمیل‌تان عوض شود. explanation: برای تغییر رایانامه‌تان نشانی جدید را تأیید کنید.
extra: اگر شما باعث این تغییر نبودید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید، نشانی ایمیل مربوط به حساب شما عوض نخواهد شد. extra: اگر خودتان چنین درخواستی نداده‌اید لطفاً از این رایانامه چشم بپوشید. نشانی رایانامهٔ حساب ماستودون تا وقتی به پیوند بالا دسترسی پیدا نکنید عوض نخواهد شد.
subject: 'ماستودون: تأیید رایانامه برای %{instance}' subject: 'ماستودون: تأیید رایانامه برای %{instance}'
title: تأیید نشانی ایمیل title: تأیید نشانی رایانامه
reset_password_instructions: reset_password_instructions:
action: تغییر گذرواژه action: تغییر گذرواژه
explanation: شما گذرواژه تازه‌ای برای حسابتان درخواست کردید. explanation: درخواست گذرواژه‌ای تازه‌ای برای حسابتان کرده‌اید.
extra: اگر شما چنین درخواستی نکردید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید و گذرواژه تازه‌ای نسازید، گذرواژه شما عوض نخواهد شد. extra: اگر خودتان چنین درخواستی نداده‌اید لطفاً از این رایانامه چشم بپوشید. گذرواژه‌تان تا وقتی به پیوند بالا دسترسی پیدا نکرده و گذرواژهٔ جدیدی نسازید عوض نخواهد شد.
subject: 'ماستودون: راهنمایی برای بازنشانی گذرواژه' subject: 'ماستودون: دستورالعمل‌های بازنشانی گذرواژه'
title: بازنشانی گذرواژه title: بازنشانی گذرواژه
two_factor_disabled: two_factor_disabled:
subject: 'ماستودون: تأیید هویت دو مرحله‌ای از کار افتاد' explanation: ورود اکنون تنها با نشانی رایانامه و گذرواژه ممکن است.
title: ورود دومرحله‌ای غیرفعال subject: 'ماستودون: هویت‌سنجی دو مرحله‌ای از کار افتاده'
subtitle: هویت‌سنجی دو مرحله‌ای برای حسابتان از کار افتاده.
title: ورود دومرحله‌ای از کار افتاده
two_factor_enabled: two_factor_enabled:
subject: 'ماستودون: تأیید هویت دومرحله‌ای به کار افتاد' explanation: ورود نیازمند ژتونی تولید شده به دست کارهٔ TOTP جفت‌شده است.
title: ورود دومرحله‌ای فعال subject: 'ماستودون: هویت‌سنجی دومرحله‌ای به کار افتاده'
subtitle: هویت‌سنجی دو عاملی برای حسابتان به کار افتاده.
title: ورود دومرحله‌ای به کار افتاده
two_factor_recovery_codes_changed: two_factor_recovery_codes_changed:
explanation: کدهای بازیابی پیشین نامعتبر شده و کدهای جدیدی ساخته شدند. explanation: کدهای بازیابی پیشین نامعتبر شده و کدهای جدیدی ساخته شدند.
subject: 'ماستودون: کدهای بازیابی برای تأیید هویت دو مرحله‌ای دوباره ساخته شدند' subject: 'ماستودون: کدهای بازیابی برای تأیید هویت دو مرحله‌ای دوباره ساخته شدند'
subtitle: کدهای بازیابی پیشین از اعتبار ساقط شده و کدهایی جدید ایجاد شدند.
title: کدهای بازیابی تأیید هویت دو مرحله‌ای عوض شده‌اند title: کدهای بازیابی تأیید هویت دو مرحله‌ای عوض شده‌اند
unlock_instructions: unlock_instructions:
subject: 'ماستودون: دستورالعمل‌های قفل‌گشایی' subject: 'ماستودون: دستورالعمل‌های قفل‌گشایی'
@ -68,9 +74,13 @@ fa:
subject: 'ماستودون: کلید امنیتی حذف شد' subject: 'ماستودون: کلید امنیتی حذف شد'
title: یکی از کلیدهای امنیتیتان حذف شد title: یکی از کلیدهای امنیتیتان حذف شد
webauthn_disabled: webauthn_disabled:
explanation: هویت‌سنجی با کلیدهای امنیتی برای حسابتان از کار افتاده.
extra: ورود اکنون تنها با ژتون تولید شده به دست کارهٔ TOTP جفت‌شده ممکن است.
subject: 'ماستودون: تأیید هویت با کلیدهای امنیتی از کار افتاد' subject: 'ماستودون: تأیید هویت با کلیدهای امنیتی از کار افتاد'
title: کلیدهای امنیتی از کار افتادند title: کلیدهای امنیتی از کار افتادند
webauthn_enabled: webauthn_enabled:
explanation: هویت‌سنجی با کلیدهای امنیتی برای حسابتان به کار افتاده.
extra: کلید امنیتیتان اکنون می‌تواند برای ورود استفاده شود.
subject: 'ماستودون: تأیید هویت با کلید امنیتی به کار افتاد' subject: 'ماستودون: تأیید هویت با کلید امنیتی به کار افتاد'
title: کلیدهای امنیتی به کار افتادند title: کلیدهای امنیتی به کار افتادند
omniauth_callbacks: omniauth_callbacks:
@ -86,22 +96,22 @@ fa:
destroyed: بدرود! حساب شما با موفقیت لغو شد. امیدواریم دوباره شما را ببینیم. destroyed: بدرود! حساب شما با موفقیت لغو شد. امیدواریم دوباره شما را ببینیم.
signed_up: خوش آمدید! شما با موفقیت ثبت نام کردید. signed_up: خوش آمدید! شما با موفقیت ثبت نام کردید.
signed_up_but_inactive: خوش آمدید! با موفقیت ثبت نام کردید. ولی هنوز وارد نشده‌اید؛ چرا که حسابتان هنوز فعال نشده است. signed_up_but_inactive: خوش آمدید! با موفقیت ثبت نام کردید. ولی هنوز وارد نشده‌اید؛ چرا که حسابتان هنوز فعال نشده است.
signed_up_but_locked: خوش آمدید! با موفقیت ثبت نام کردید. ولی هنوز وارد نشده‌اید؛ چرا که حسابتان قفل است. signed_up_but_locked: با موفّقیت ثبت‌نام کرده‌اید. با این حال نمی‌توان واردتان کرد؛ چرا که حسابتان قفل است.
signed_up_but_pending: پیغامی که دارای یک پیوند برای تأیید است به نشانی ایمیل شما فرستاده شده. پس از این‌که پیوند را باز کردید، ما درخواست شما را بررسی خواهیم کرد. اگر درخواست شما پذیرفته شود، به شما خواهیم گفت. signed_up_but_pending: پیامی با پیوند تأیید به نشانی رایانامه‌تان فرستاده شده. پس از زدن پیوند درخواستتان را بازبینی خواهیم کرد. در صورت پذیرش آگاه خواهید شد.
signed_up_but_unconfirmed: پیامی با یک پیوند تأیید به نشانی ایمیل شما فرستاده شده. لطفاً پیوند موجود در ایمیل را دنبال کنید تا حسابتان فعال شود. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. signed_up_but_unconfirmed: پیامی با پیوند تأیید به نشانی رایانامه‌تان فرستاده شده. لطفاً برای فعّال کردن حسابتان پیوند را بزنید. اگر این رایانامه را نگرفته‌اید شاخهٔ هرزنامه‌ها را بررسی کنید.
update_needs_confirmation: شما با موفقیت حسابتان را به‌روز کردید، ولی لازم است که ما نشانی ایمیل تازهٔ شما را تأیید کنیم. لطفاً ایمیل خود را ببینید و پیوند موجود در ایمیل را دنبال کنید تا تا نشانی ایمیل تازهٔ شما تأیید شود. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. update_needs_confirmation: حسابتان را با موفّقیت به‌روز کردید؛‌ ولی باید نشانی رایانامهٔ جدیتان را تأیید کنیم. لطفاً رایانامه‌تان را بررسی کرده و برای تأیید نشانی رایانهٔ جدیدتان پیوند را بزنید. اگر این رایانامه را نگرفته‌اید شاخهٔ هرزنامه‌ها را بررسی کنید.
updated: حسابتان با موفقبت به‌روز شد. updated: حسابتان با موفّقیت به‌روز شد.
sessions: sessions:
already_signed_out: با موفقیت خارج شدید. already_signed_out: با موفّقیت خارج شدید.
signed_in: با موفقیت وارد شدید. signed_in: با موفّقیت وارد شدید.
signed_out: با موفقیت خارج شدید. signed_out: با موفّقیت خارج شدید.
unlocks: unlocks:
send_instructions: تا دقایقی دیگر ایمیلی خواهید گرفت که به شما می‌گوید چگونه باید قفل حساب خود را باز کنید. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. send_instructions: تا دقایقی دیگر رایانامه‌ای با دستورالعمل قفل‌گشایی حسابتان دریافت خواهید کرد. اگر این رایانامه را نگرفتید، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید.
send_paranoid_instructions: اگر حساب شما موجود باشد، تا دقایقی دیگر ایمیلی خواهید گرفت که به شما می‌گوید چگونه باید قفل آن را باز کنید. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. send_paranoid_instructions: اگر حسابتان وجود داشته باشد تا دقایقی دیگر رایانامه‌ای با دستورالعمل قفل‌گشاییش دریافت خواهید کرد. اگر این رایانامه را نگرفتید، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید.
unlocked: قفل حساب شما با موفقیت باز شد. لطفاً برای ادامه وارد سیستم شوید. unlocked: حسابتان با موفّقیت قفل‌گشایی شد. لطفاً برای ادامه وارد شوید.
errors: errors:
messages: messages:
already_confirmed: تأیید شده، لطفاً وارد شوید already_confirmed: از پیش تأیید شده. لطفاً ورود را بیازمایید
confirmation_period_expired: باید ظرف %{period} تأیید شود، لطفاً دوباره درخواست دهید confirmation_period_expired: باید ظرف %{period} تأیید شود، لطفاً دوباره درخواست دهید
expired: مهلتش به سر رسید، لطفاً دوباره درخواست دهید expired: مهلتش به سر رسید، لطفاً دوباره درخواست دهید
not_found: پیدا نشد not_found: پیدا نشد

View file

@ -12,6 +12,7 @@ nn:
last_attempt: Du har eitt forsøk igjen før kontoen din vert låst. last_attempt: Du har eitt forsøk igjen før kontoen din vert låst.
locked: Kontoen din er låst. locked: Kontoen din er låst.
not_found_in_database: Ugyldig %{authentication_keys} eller passord. not_found_in_database: Ugyldig %{authentication_keys} eller passord.
omniauth_user_creation_failure: Greidde ikkje laga konto for denne identiteten.
pending: Kontoen din er vert gjennomgått enno. pending: Kontoen din er vert gjennomgått enno.
timeout: Økta di er utgått. Logg inn omatt for å halde fram. timeout: Økta di er utgått. Logg inn omatt for å halde fram.
unauthenticated: Du må logge inn eller registere deg før du kan halde fram. unauthenticated: Du må logge inn eller registere deg før du kan halde fram.
@ -47,19 +48,19 @@ nn:
subject: 'Mastodon: Instuksjonar for å endra passord' subject: 'Mastodon: Instuksjonar for å endra passord'
title: Attstilling av passord title: Attstilling av passord
two_factor_disabled: two_factor_disabled:
explanation: Innlogging er nå mulig med kun e-postadresse og passord. explanation: No kan du logga inn med berre epostadresse og passord.
subject: 'Mastodon: To-faktor-autentisering deaktivert' subject: 'Mastodon: To-faktor-autentisering deaktivert'
subtitle: To-faktor autentisering for din konto har blitt deaktivert. subtitle: Tofaktorinnlogging for denne kontoen er skrudd av.
title: 2FA deaktivert title: 2FA deaktivert
two_factor_enabled: two_factor_enabled:
explanation: En token generert av den sammenkoblede TOTP-appen vil være påkrevd for innlogging. explanation: Du treng ein kode frå den tilkopla tofaktor-appen din for å logga inn.
subject: 'Mastodon: To-faktor-autentisering aktivert' subject: 'Mastodon: To-faktor-autentisering aktivert'
subtitle: Tofaktorautentisering er aktivert for din konto. subtitle: Tofaktorpålogging er skrudd på for kontoen din.
title: 2FA aktivert title: 2FA aktivert
two_factor_recovery_codes_changed: two_factor_recovery_codes_changed:
explanation: Dei førre gjenopprettingskodane er ugyldige og nye er genererte. explanation: Dei førre gjenopprettingskodane er ugyldige og nye er genererte.
subject: 'Mastodon: To-faktor-gjenopprettingskodar har vorte genererte på nytt' subject: 'Mastodon: To-faktor-gjenopprettingskodar har vorte genererte på nytt'
subtitle: De forrige gjenopprettingskodene er gjort ugyldige og nye er generert. subtitle: Dei førre innloggingskodane er ikkje gyldige lenger, og nye kodar er laga.
title: 2FA-gjenopprettingskodane er endra title: 2FA-gjenopprettingskodane er endra
unlock_instructions: unlock_instructions:
subject: 'Mastodon: Instruksjonar for å opne kontoen igjen' subject: 'Mastodon: Instruksjonar for å opne kontoen igjen'
@ -73,13 +74,13 @@ nn:
subject: 'Mastodon: Sikkerheitsnøkkel sletta' subject: 'Mastodon: Sikkerheitsnøkkel sletta'
title: Ein av sikkerheitsnøklane dine har blitt sletta title: Ein av sikkerheitsnøklane dine har blitt sletta
webauthn_disabled: webauthn_disabled:
explanation: Autentisering med sikkerhetsnøkler er deaktivert for kontoen din. explanation: Innlogging med tryggingsnykjel er skrudd av for kontoen din.
extra: Innlogging er nå mulig med kun tilgangstoken generert av den sammenkoblede TOTP-appen. extra: No kan du logga inn med berre kodane som er laga av den tilkopla tofaktor-appen din.
subject: 'Mastodon: Autentisering med sikkerheitsnøklar vart skrudd av' subject: 'Mastodon: Autentisering med sikkerheitsnøklar vart skrudd av'
title: Sikkerheitsnøklar deaktivert title: Sikkerheitsnøklar deaktivert
webauthn_enabled: webauthn_enabled:
explanation: Sikkerhetsnøkkelautentisering har blitt aktivert for kontoen din. explanation: Innlogging med tryggingsnyklar er skrudd på for kontoen din.
extra: Sikkerhetsnøkkelen din kan nå bli brukt for innlogging. extra: No kan du bruka tryggingsnykjelen din for å logga inn.
subject: 'Mastodon: Sikkerheitsnøkkelsautentisering vart skrudd på' subject: 'Mastodon: Sikkerheitsnøkkelsautentisering vart skrudd på'
title: Sikkerheitsnøklar aktivert title: Sikkerheitsnøklar aktivert
omniauth_callbacks: omniauth_callbacks:

View file

@ -12,6 +12,7 @@ pt-BR:
last_attempt: Você tem mais uma tentativa antes de sua conta ser bloqueada. last_attempt: Você tem mais uma tentativa antes de sua conta ser bloqueada.
locked: Sua conta está bloqueada. locked: Sua conta está bloqueada.
not_found_in_database: "%{authentication_keys} ou senha inválida." not_found_in_database: "%{authentication_keys} ou senha inválida."
omniauth_user_creation_failure: Erro ao criar uma conta para esta identidade.
pending: Sua conta está sendo revisada. pending: Sua conta está sendo revisada.
timeout: Sua sessão expirou. Por favor, entre novamente para continuar. timeout: Sua sessão expirou. Por favor, entre novamente para continuar.
unauthenticated: Você precisa entrar ou criar uma conta antes de continuar. unauthenticated: Você precisa entrar ou criar uma conta antes de continuar.

View file

@ -156,13 +156,13 @@ th:
admin:read:ip_blocks: อ่านข้อมูลที่ละเอียดอ่อนของการปิดกั้น IP ทั้งหมด admin:read:ip_blocks: อ่านข้อมูลที่ละเอียดอ่อนของการปิดกั้น IP ทั้งหมด
admin:read:reports: อ่านข้อมูลที่ละเอียดอ่อนของรายงานและบัญชีที่ได้รับการรายงานทั้งหมด admin:read:reports: อ่านข้อมูลที่ละเอียดอ่อนของรายงานและบัญชีที่ได้รับการรายงานทั้งหมด
admin:write: ปรับเปลี่ยนข้อมูลทั้งหมดในเซิร์ฟเวอร์ admin:write: ปรับเปลี่ยนข้อมูลทั้งหมดในเซิร์ฟเวอร์
admin:write:accounts: ทำการกระทำการควบคุมบัญชี admin:write:accounts: ทำการกระทำการกลั่นกรองต่อบัญชี
admin:write:canonical_email_blocks: ทำการกระทำการควบคุมการปิดกั้นอีเมลมาตรฐาน admin:write:canonical_email_blocks: ทำการกระทำการกลั่นกรองต่อการปิดกั้นอีเมลมาตรฐาน
admin:write:domain_allows: ทำการกระทำการควบคุมการอนุญาตโดเมน admin:write:domain_allows: ทำการกระทำการกลั่นกรองต่อการอนุญาตโดเมน
admin:write:domain_blocks: ทำการกระทำการควบคุมการปิดกั้นโดเมน admin:write:domain_blocks: ทำการกระทำการกลั่นกรองต่อการปิดกั้นโดเมน
admin:write:email_domain_blocks: ทำการกระทำการควบคุมการปิดกั้นโดเมนอีเมล admin:write:email_domain_blocks: ทำการกระทำการกลั่นกรองต่อการปิดกั้นโดเมนอีเมล
admin:write:ip_blocks: ทำการกระทำการควบคุมการปิดกั้น IP admin:write:ip_blocks: ทำการกระทำการกลั่นกรองต่อการปิดกั้น IP
admin:write:reports: ทำการกระทำการควบคุมรายงาน admin:write:reports: ทำการกระทำการกลั่นกรองต่อรายงาน
crypto: ใช้การเข้ารหัสแบบต้นทางถึงปลายทาง crypto: ใช้การเข้ารหัสแบบต้นทางถึงปลายทาง
follow: ปรับเปลี่ยนความสัมพันธ์ของบัญชี follow: ปรับเปลี่ยนความสัมพันธ์ของบัญชี
push: รับการแจ้งเตือนแบบผลักของคุณ push: รับการแจ้งเตือนแบบผลักของคุณ

View file

@ -309,6 +309,7 @@ el:
unpublish: Αναίρεση δημοσίευσης unpublish: Αναίρεση δημοσίευσης
unpublished_msg: Επιτυχής ακύρωση δημοσίευσης ανακοίνωσης! unpublished_msg: Επιτυχής ακύρωση δημοσίευσης ανακοίνωσης!
updated_msg: Επιτυχής ενημέρωση ανακοίνωσης! updated_msg: Επιτυχής ενημέρωση ανακοίνωσης!
critical_update_pending: Κρίσιμη ενημέρωση σε αναμονή
custom_emojis: custom_emojis:
assign_category: Ανάθεση κατηγορίας assign_category: Ανάθεση κατηγορίας
by_domain: Τομέας by_domain: Τομέας
@ -382,6 +383,15 @@ el:
undo: Αφαίρεση συναλλαγής με τον τομέα undo: Αφαίρεση συναλλαγής με τον τομέα
domain_blocks: domain_blocks:
add_new: Προσθήκη νέου αποκλεισμού τομέα add_new: Προσθήκη νέου αποκλεισμού τομέα
confirm_suspension:
cancel: Άκυρο
confirm: Αναστολή
permanent_action: Η κατάργηση της αναστολής δε θα αποκαταστήσει καθόλου δεδομένα ή σχέση.
preamble_html: Πρόκειται να αναστείλετε το <strong>%{domain}</strong> και τους υποτομείς του.
remove_all_data: Αυτό θα αφαιρέσει όλο το περιεχόμενο, τα μέσα και τα δεδομένα προφίλ για τους λογαριασμούς αυτού του τομέα από το διακομιστή σας.
stop_communication: Ο διακομιστής σας θα σταματήσει να επικοινωνεί με αυτούς τους διακομιστές.
title: Επιβεβαίωση αποκλεισμού τομέα για %{domain}
undo_relationships: Αυτό θα αναιρέσει οποιαδήποτε σχέση ακολουθίας μεταξύ των λογαριασμών αυτών των διακομιστών και των δικών σας.
created_msg: Ο αποκλεισμός τομέα είναι υπό επεξεργασία created_msg: Ο αποκλεισμός τομέα είναι υπό επεξεργασία
destroyed_msg: Ο αποκλεισμός τομέα αναιρέθηκε destroyed_msg: Ο αποκλεισμός τομέα αναιρέθηκε
domain: Τομέας domain: Τομέας
@ -415,6 +425,7 @@ el:
view: Εμφάνιση αποκλεισμού τομέα view: Εμφάνιση αποκλεισμού τομέα
email_domain_blocks: email_domain_blocks:
add_new: Προσθήκη νέου add_new: Προσθήκη νέου
allow_registrations_with_approval: Να επιτρέπονται εγγραφές με έγκριση
attempts_over_week: attempts_over_week:
one: "%{count} προσπάθεια την τελευταία εβδομάδα" one: "%{count} προσπάθεια την τελευταία εβδομάδα"
other: "%{count} προσπάθειες εγγραφής την τελευταία εβδομάδα" other: "%{count} προσπάθειες εγγραφής την τελευταία εβδομάδα"
@ -524,6 +535,7 @@ el:
total_reported: Αναφορές προς εκείνους total_reported: Αναφορές προς εκείνους
total_storage: Συνημμένα πολυμέσα total_storage: Συνημμένα πολυμέσα
totals_time_period_hint_html: Τα σύνολα που εμφανίζονται παρακάτω περιλαμβάνουν στοιχεία από την αρχή. totals_time_period_hint_html: Τα σύνολα που εμφανίζονται παρακάτω περιλαμβάνουν στοιχεία από την αρχή.
unknown_instance: Προς το παρόν δεν υπάρχει καμία εγγραφή αυτού του τομέα σε αυτόν το διακομιστή.
invites: invites:
deactivate_all: Απενεργοποίηση όλων deactivate_all: Απενεργοποίηση όλων
filter: filter:
@ -600,6 +612,7 @@ el:
created_at: Αναφέρθηκε created_at: Αναφέρθηκε
delete_and_resolve: Διαγραφή αναρτήσεων delete_and_resolve: Διαγραφή αναρτήσεων
forwarded: Προωθημένα forwarded: Προωθημένα
forwarded_replies_explanation: Αυτή η αναφορά είναι από απομακρυσμένο χρήστη και για απομακρυσμένο περιεχόμενο. Σας έχει διαβιβαστεί, επειδή το αναφερόμενο περιεχόμενο απαντά σε έναν από τους χρήστες σας.
forwarded_to: Προώθημένα προς %{domain} forwarded_to: Προώθημένα προς %{domain}
mark_as_resolved: Σημείωση ως επιλυμένο mark_as_resolved: Σημείωση ως επιλυμένο
mark_as_sensitive: Σήμανση ως ευαίσθητο mark_as_sensitive: Σήμανση ως ευαίσθητο

View file

@ -1847,7 +1847,7 @@ es:
edit_profile_step: Puedes personalizar tu perfil subiendo una foto de perfil, cambiando tu nombre de usuario y mucho más. Puedes optar por revisar a los nuevos seguidores antes de que puedan seguirte. edit_profile_step: Puedes personalizar tu perfil subiendo una foto de perfil, cambiando tu nombre de usuario y mucho más. Puedes optar por revisar a los nuevos seguidores antes de que puedan seguirte.
explanation: Aquí hay algunos consejos para empezar explanation: Aquí hay algunos consejos para empezar
final_action: Empezar a publicar final_action: Empezar a publicar
final_step: "¡Empieza a publicar! Incluso sin seguidores, tus publicaciones públicas pueden ser vistas por otros, por ejemplo en la línea de tiempo local o en etiquetas. Tal vez quieras presentarte con la etiqueta de #introducciones." final_step: "¡Empieza a publicar! Incluso sin seguidores, tus publicaciones públicas pueden ser vistas por otros, por ejemplo en la línea de tiempo local o en etiquetas. Tal vez quieras presentarte con la etiqueta de #presentación."
full_handle: Su sobrenombre completo full_handle: Su sobrenombre completo
full_handle_hint: Esto es lo que le dirías a tus amigos para que ellos puedan enviarte mensajes o seguirte desde otra instancia. full_handle_hint: Esto es lo que le dirías a tus amigos para que ellos puedan enviarte mensajes o seguirte desde otra instancia.
subject: Bienvenido a Mastodon subject: Bienvenido a Mastodon

View file

@ -769,6 +769,7 @@ eu:
disabled: Inori ez disabled: Inori ez
users: Saioa hasita duten erabiltzaile lokalei users: Saioa hasita duten erabiltzaile lokalei
registrations: registrations:
moderation_recommandation: Mesedez, ziurtatu moderazio-talde egokia eta erreaktiboa duzula erregistroak guztiei ireki aurretik!
preamble: Kontrolatu nork sortu dezakeen kontua zerbitzarian. preamble: Kontrolatu nork sortu dezakeen kontua zerbitzarian.
title: Izen emateak title: Izen emateak
registrations_mode: registrations_mode:
@ -776,6 +777,7 @@ eu:
approved: Izena emateko onarpena behar da approved: Izena emateko onarpena behar da
none: Ezin du inork izena eman none: Ezin du inork izena eman
open: Edonork eman dezake izena open: Edonork eman dezake izena
warning_hint: "“Izena emateko onarpena behar da” erabiltzea gomendatzen dugu, baldin eta ez badakizu ziur zure moderazio-taldeak spama eta erregistro maltzurrak arrazoizko denboran erantzun ditzakeela."
security: security:
authorized_fetch: Eskatu autentifikazioa federatutako zerbitzarietatik authorized_fetch: Eskatu autentifikazioa federatutako zerbitzarietatik
authorized_fetch_hint: Zerbitzari federatuen autentifikazioa eskatzeak erabiltzaile-mailako zein zerbitzari-mailako blokeak zorrotzago betearaztea ahalbidetzen du. Hala ere, horrek errendimendu galera dakar, zure erantzunen irismena murrizten du eta baliteke federatutako zerbitzu batzuekin bateragarritasun-arazoak sortu ahal izatea. Horrez gain, horrek ez du eragotziko aktore dedikatuek zure mezu eta kontu publikoak eskuratzea. authorized_fetch_hint: Zerbitzari federatuen autentifikazioa eskatzeak erabiltzaile-mailako zein zerbitzari-mailako blokeak zorrotzago betearaztea ahalbidetzen du. Hala ere, horrek errendimendu galera dakar, zure erantzunen irismena murrizten du eta baliteke federatutako zerbitzu batzuekin bateragarritasun-arazoak sortu ahal izatea. Horrez gain, horrek ez du eragotziko aktore dedikatuek zure mezu eta kontu publikoak eskuratzea.

View file

@ -80,7 +80,7 @@ fa:
joined: عضو شده در joined: عضو شده در
location: location:
all: همه all: همه
local: محلّی local: محلی
remote: کارسازهای دیگر remote: کارسازهای دیگر
title: مکان title: مکان
login_status: وضعیت ورود login_status: وضعیت ورود
@ -415,13 +415,14 @@ fa:
public_comment: یادداشت عمومی public_comment: یادداشت عمومی
public_comment_hint: یادداشتی دربارهٔ محدودیت روی این دامین برای عموم، در صورتی که فهرست دامین‌های محدود شده منتشر شود. public_comment_hint: یادداشتی دربارهٔ محدودیت روی این دامین برای عموم، در صورتی که فهرست دامین‌های محدود شده منتشر شود.
reject_media: نپذیرفتن پرونده‌های رسانه‌ای reject_media: نپذیرفتن پرونده‌های رسانه‌ای
reject_media_hint: پرونده‌های رسانه‌ای ذخیره‌شدهٔ محلّی را پاک کرده و از بارگیریشان در آینده خودداری می‌کند. بی‌تأثیر روی معلق‌ها reject_media_hint: پرونده‌های رسانه‌ای ذخیره‌شدهٔ محلی را پاک کرده و از بارگیریشان در آینده خودداری می‌کند. بی‌تأثیر روی معلّق‌ها
reject_reports: نپذیرفتن گزارش‌ها reject_reports: نپذیرفتن گزارش‌ها
reject_reports_hint: گزارش‌هایی را که از این دامنه می‌آید نادیده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها reject_reports_hint: گزارش‌هایی را که از این دامنه می‌آید نادیده می‌گیرد. بی‌تأثیر برای معلق‌شده‌ها
undo: واگردانی مسدودسازی دامین undo: واگردانی مسدودسازی دامین
view: دیدن مسدودسازی دامنه view: دیدن مسدودسازی دامنه
email_domain_blocks: email_domain_blocks:
add_new: افزودن تازه add_new: افزودن تازه
allow_registrations_with_approval: اجازهٔ ثبت‌نام با تأیید
attempts_over_week: attempts_over_week:
one: "%{count} تلاش در هفتهٔ گذشته" one: "%{count} تلاش در هفتهٔ گذشته"
other: "%{count} تلاش ورود در هفتهٔ گذشته" other: "%{count} تلاش ورود در هفتهٔ گذشته"

View file

@ -767,6 +767,7 @@ fi:
disabled: Ei kenellekkään disabled: Ei kenellekkään
users: Kirjautuneille paikallisille käyttäjille users: Kirjautuneille paikallisille käyttäjille
registrations: registrations:
moderation_recommandation: Varmista, että sinulla on riittävä ja toimintavalmis joukko moderaattoreita ennen kuin avaat rekisteröitymiset kaikille!
preamble: Määritä, kuka voi luoda tilin palvelimellesi. preamble: Määritä, kuka voi luoda tilin palvelimellesi.
title: Rekisteröityminen title: Rekisteröityminen
registrations_mode: registrations_mode:
@ -774,6 +775,7 @@ fi:
approved: Rekisteröinti vaatii hyväksynnän approved: Rekisteröinti vaatii hyväksynnän
none: Kukaan ei voi rekisteröityä none: Kukaan ei voi rekisteröityä
open: Kaikki voivat rekisteröityä open: Kaikki voivat rekisteröityä
warning_hint: Suosittelemme käyttämään asetusta “Rekisteröinti vaatii hyväksynnän” ellet ole varma siitä, että moderaattorit ovat valmiina käsittelemään roskapostia ja haittarekisteröitymisiä oikea-aikaisesti.
security: security:
authorized_fetch: Vaadi todennus liittoutuvilta palvelimilta authorized_fetch: Vaadi todennus liittoutuvilta palvelimilta
authorized_fetch_hint: Todennuksen vaatiminen liittoutuvilta palvelimilta mahdollistaa sekä käyttäjä- että palvelintason estojen tiukemman valvonnan. Tämä tapahtuu kuitenkin suorituskyvyn kustannuksella, vähentää vastauksiesi tavoittavuutta ja voi aiheuttaa yhteensopivuusongelmia joidenkin liittoutuvien palvelujen kanssa. Tämä ei myöskään estä omistautuneita toimijoita hakemasta julkisia julkaisujasi ja tilejäsi. authorized_fetch_hint: Todennuksen vaatiminen liittoutuvilta palvelimilta mahdollistaa sekä käyttäjä- että palvelintason estojen tiukemman valvonnan. Tämä tapahtuu kuitenkin suorituskyvyn kustannuksella, vähentää vastauksiesi tavoittavuutta ja voi aiheuttaa yhteensopivuusongelmia joidenkin liittoutuvien palvelujen kanssa. Tämä ei myöskään estä omistautuneita toimijoita hakemasta julkisia julkaisujasi ja tilejäsi.
@ -966,6 +968,9 @@ fi:
title: Webhookit title: Webhookit
webhook: Webhook webhook: Webhook
admin_mailer: admin_mailer:
auto_close_registrations:
body: Viimeaikaisen moderaattoritoiminnan puutteen vuoksi %{instance} rekisteröinnit on vaihdettu automaattisesti manuaaliseen tarkasteluun, jotta %{instance} ei käytetä mahdollisien huonojen toimijoiden alustana. Voit vaihtaa sen takaisin avaamalla rekisteröinnit milloin tahansa.
subject: Rekisteröinnit %{instance} on automaattisesti vaihdettu vaatimaan hyväksyntää
new_appeal: new_appeal:
actions: actions:
delete_statuses: poistaa hänen julkaisunsa delete_statuses: poistaa hänen julkaisunsa

View file

@ -767,6 +767,7 @@ fo:
disabled: Til ongan disabled: Til ongan
users: Fyri lokalum brúkarum, sum eru ritaðir inn users: Fyri lokalum brúkarum, sum eru ritaðir inn
registrations: registrations:
moderation_recommandation: Vinarliga tryggja tær, at tú hevur eitt nøktandi og klárt umsjónartoymi, áðreen tú letur upp fyri skrásetingum frá øllum!
preamble: Stýr, hvør kann stovna eina kontu á tínum ambætara. preamble: Stýr, hvør kann stovna eina kontu á tínum ambætara.
title: Skrásetingar title: Skrásetingar
registrations_mode: registrations_mode:
@ -774,6 +775,7 @@ fo:
approved: Góðkenning kravd fyri tilmelding approved: Góðkenning kravd fyri tilmelding
none: Eingin kann tilmelda seg none: Eingin kann tilmelda seg
open: Øll kunnu tilmelda seg open: Øll kunnu tilmelda seg
warning_hint: Vit mæla til at brúka "Góðkenning kravd fyri tilmelding" uttan so at tú er fullvís/ur í, at umsjónartoymið hjá tær kann handfara ruskpost og óndsinnaðar skrásetingar so hvørt.
security: security:
authorized_fetch: Krev samgildi frá sameindum ambætarum authorized_fetch: Krev samgildi frá sameindum ambætarum
authorized_fetch_hint: At krevja samgildi frá sameindum ambætarum ger strangari útinning av blokkum bæði á brúkara- og ambætara-stigi møguliga. Tó so, kostnaðurin er ein avriksstraffur, minkar um hvussu langt svarini hjá tær røkka og kann viðføra sambæristruplleikar við summar sameindar tænastur. Harafturat forðar hetta ikki teimum, ið miðvíst leggja seg eftir at heinta tínar almennu postar og kontur. authorized_fetch_hint: At krevja samgildi frá sameindum ambætarum ger strangari útinning av blokkum bæði á brúkara- og ambætara-stigi møguliga. Tó so, kostnaðurin er ein avriksstraffur, minkar um hvussu langt svarini hjá tær røkka og kann viðføra sambæristruplleikar við summar sameindar tænastur. Harafturat forðar hetta ikki teimum, ið miðvíst leggja seg eftir at heinta tínar almennu postar og kontur.

View file

@ -795,6 +795,7 @@ he:
disabled: לאף אחד disabled: לאף אחד
users: למשתמשים מקומיים מחוברים users: למשתמשים מקומיים מחוברים
registrations: registrations:
moderation_recommandation: יש לוודא שלאתר יש צוות מנחות ומנחי שיחה מספק ושירותי בטרם תבחרו לפתוח הרשמה לכולם!
preamble: שליטה בהרשאות יצירת חשבון בשרת שלך. preamble: שליטה בהרשאות יצירת חשבון בשרת שלך.
title: הרשמות title: הרשמות
registrations_mode: registrations_mode:
@ -802,6 +803,7 @@ he:
approved: נדרש אישור הרשמה approved: נדרש אישור הרשמה
none: אף אחד לא יכול להרשם none: אף אחד לא יכול להרשם
open: כל אחד יכול להרשם open: כל אחד יכול להרשם
warning_hint: אנו ממליצים להפעיל דרישה לאישור ידני של הרשמה אלא אם אתם מאמינים שצוות הנחיית השיחות שלכם יוכל להסתדר בזריזות עם מפיצי תכנים פוגעניים או פרסומיים על בסיס קבוע.
security: security:
authorized_fetch: לדרוש הזדהות מול שרתים בפדרציה authorized_fetch: לדרוש הזדהות מול שרתים בפדרציה
authorized_fetch_hint: הדרישה להזדהות מול שרתים בפדרציה מאפשרת חסימה יותר יעילה ברמת המשתמש וברמת שרת. עם זאת, הדרישה באה עם מחיר של נפילת ביצועים, מקטינה את מעגל התפוצה של התשובות שלך, ועשויה ליצור אי תאימות מול שירותים אחרים בפדרציה. בנוסף, זה לא ימנע מצדדים החלטיים לקבל גישת קריאה להודעות ופרופילים ציבוריים. authorized_fetch_hint: הדרישה להזדהות מול שרתים בפדרציה מאפשרת חסימה יותר יעילה ברמת המשתמש וברמת שרת. עם זאת, הדרישה באה עם מחיר של נפילת ביצועים, מקטינה את מעגל התפוצה של התשובות שלך, ועשויה ליצור אי תאימות מול שירותים אחרים בפדרציה. בנוסף, זה לא ימנע מצדדים החלטיים לקבל גישת קריאה להודעות ופרופילים ציבוריים.

View file

@ -767,7 +767,7 @@ hu:
disabled: Senkinek disabled: Senkinek
users: Bejelentkezett helyi felhasználóknak users: Bejelentkezett helyi felhasználóknak
registrations: registrations:
moderation_recommandation: Győződjünk meg arról, hogy megfelelő és reaktív moderátor csapatunk van, mielőtt mindenki számára megnyitjuk a regisztrációt! moderation_recommandation: Győződj meg arról, hogy megfelelő és gyors reagálású moderátor csapatod van, mielőtt mindenki számára megnyitod a regisztrációt!
preamble: Szabályozd, hogy ki hozhat létre fiókot a kiszolgálón. preamble: Szabályozd, hogy ki hozhat létre fiókot a kiszolgálón.
title: Regisztrációk title: Regisztrációk
registrations_mode: registrations_mode:
@ -775,7 +775,7 @@ hu:
approved: A regisztráció engedélyhez kötött approved: A regisztráció engedélyhez kötött
none: Senki sem regisztrálhat none: Senki sem regisztrálhat
open: Bárki regisztrálhat open: Bárki regisztrálhat
warning_hint: Célszerű a "Jóváhagyás szükséges a regisztrációhoz” lehetőség használata, hkivéve, ha biztos vagyunk abban, hogy a moderátor csapat időben tudja kezelni a szemetet és a rosszindulatú regisztrációkat. warning_hint: Javasoljuk a "Jóváhagyás szükséges a regisztrációhoz” lehetőség használatát, hacsak nem vagy biztos abban, hogy a moderátor csapatod időben tudja kezelni a szemetet és a rosszindulatú regisztrációkat.
security: security:
authorized_fetch: Hitelesítés szükséges a föderációs kiszolgálóktól authorized_fetch: Hitelesítés szükséges a föderációs kiszolgálóktól
authorized_fetch_hint: A föderációs szerverek hitelesítésének szükségessége lehetővé teszi mind a felhasználói mind a szerver szintű blokkok szigorúbb végrehajtását. Ez azonban a teljesítménybüntetés árán jár, csökkenti a válaszok elérhetőségét és kompatibilitási problémákat vethet fel egyes föderációs szolgáltatásokkal. Emellett ez nem akadályozza meg a dedikált szereplőket abban, hogy nyilvános bejegyzéseiket és fiókjaikat letöltsék. authorized_fetch_hint: A föderációs szerverek hitelesítésének szükségessége lehetővé teszi mind a felhasználói mind a szerver szintű blokkok szigorúbb végrehajtását. Ez azonban a teljesítménybüntetés árán jár, csökkenti a válaszok elérhetőségét és kompatibilitási problémákat vethet fel egyes föderációs szolgáltatásokkal. Emellett ez nem akadályozza meg a dedikált szereplőket abban, hogy nyilvános bejegyzéseiket és fiókjaikat letöltsék.

View file

@ -767,6 +767,7 @@ ie:
disabled: A necun disabled: A necun
users: A local usatores qui ha initiat session users: A local usatores qui ha initiat session
registrations: registrations:
moderation_recommandation: Ples assecurar que tu have un equip de moderation quel es adequat e reactiv ante que tu aperte registrationes a omnes!
preamble: Decider qui posse crear un conto che vor servitor. preamble: Decider qui posse crear un conto che vor servitor.
title: Registrationes title: Registrationes
registrations_mode: registrations_mode:
@ -774,6 +775,7 @@ ie:
approved: Aprobation besonat por adhesion approved: Aprobation besonat por adhesion
none: Nequi posse registrar se none: Nequi posse registrar se
open: Quicunc posse registrar se open: Quicunc posse registrar se
warning_hint: Noi recomanda usar "Aprobation besonat por inscrir" si tu ne es confident que tui equip de moderation posse gerer spam e maliciosi registrationes in un curt témpor.
security: security:
authorized_fetch: Postular autentication de federat servitores authorized_fetch: Postular autentication de federat servitores
authorized_fetch_hint: Postular autentication de federat servitores possibilisa plu strict infortiament de ambi usatori e servitori bloccas. Támen, ti fórsan va limitar li potentie de vor servitor, reducter li atingement de vor responses, e possibilmen introducter problemas de compatibilitá con quelc federat servicies. Additionalmen, ti ne va preventer dedicat actores de accesser vor public postas e contos. authorized_fetch_hint: Postular autentication de federat servitores possibilisa plu strict infortiament de ambi usatori e servitori bloccas. Támen, ti fórsan va limitar li potentie de vor servitor, reducter li atingement de vor responses, e possibilmen introducter problemas de compatibilitá con quelc federat servicies. Additionalmen, ti ne va preventer dedicat actores de accesser vor public postas e contos.
@ -966,6 +968,9 @@ ie:
title: Webcrocs title: Webcrocs
webhook: Webcroc webhook: Webcroc
admin_mailer: admin_mailer:
auto_close_registrations:
body: Pro un manca de recent activitá moderatori, registrationes sur %{instance} ha esset automaticmen changeat al mode quel besona un manual recension, por que %{instance} ne mey esser usat quam un platform por malfatores. Tu posse rechangear a apert registrationes quandecunc.
subject: Registrationes por %{instance} ha esset automaticmen changeat al mode quel besona aprobation
new_appeal: new_appeal:
actions: actions:
delete_statuses: deleter su postas delete_statuses: deleter su postas

View file

@ -11,7 +11,7 @@ kab:
followers: followers:
one: Umeḍfaṛ one: Umeḍfaṛ
other: Imeḍfaṛen other: Imeḍfaṛen
following: Yeṭafaṛ following: Yeṭafaṛ
last_active: armud aneggaru last_active: armud aneggaru
nothing_here: Ulac kra da! nothing_here: Ulac kra da!
posts: posts:
@ -542,7 +542,7 @@ kab:
add_new: Rnu amaynut add_new: Rnu amaynut
filters: filters:
contexts: contexts:
account: Imuɣna account: Imeɣna
notifications: Ilɣa notifications: Ilɣa
thread: Idiwenniyen thread: Idiwenniyen
edit: edit:
@ -654,7 +654,7 @@ kab:
relationships: relationships:
activity: Armud n umiḍan activity: Armud n umiḍan
followers: Imeḍfaṛen followers: Imeḍfaṛen
following: Yeṭafaṛ following: Yeṭafaṛ
invited: Yettwancad invited: Yettwancad
last_active: Armud aneggaru last_active: Armud aneggaru
most_recent: Melmi kan most_recent: Melmi kan

View file

@ -755,6 +755,7 @@ ko:
disabled: 아무에게도 안 함 disabled: 아무에게도 안 함
users: 로그인 한 사용자에게 users: 로그인 한 사용자에게
registrations: registrations:
moderation_recommandation: 모두에게 가입을 열기 전에 적절하고 반응이 빠른 중재 팀을 데리고 있는지 확인해 주세요!
preamble: 누가 이 서버에 계정을 만들 수 있는지 제어합니다. preamble: 누가 이 서버에 계정을 만들 수 있는지 제어합니다.
title: 가입 title: 가입
registrations_mode: registrations_mode:
@ -762,6 +763,7 @@ ko:
approved: 가입하려면 승인이 필요함 approved: 가입하려면 승인이 필요함
none: 아무도 가입 할 수 없음 none: 아무도 가입 할 수 없음
open: 누구나 가입 할 수 있음 open: 누구나 가입 할 수 있음
warning_hint: 당신의 중재 팀이 스팸이나 악의적인 가입을 시기적절하게 처리할 수 있다고 자신할 수 없다면 "가입이 승인을 요구하도록" 설정하는 것을 추천합니다.
security: security:
authorized_fetch: 연합된 서버들에게서 인증 필수 authorized_fetch: 연합된 서버들에게서 인증 필수
authorized_fetch_hint: 연합된 서버들에게서 인증을 요구하는 것은 사용자 레벨과 서버 레벨의 차단을 좀 더 확실하게 해줍니다. 한편으로는 성능적인 페널티, 답글의 전달 범위 감소, 몇몇 연합된 서비스들과의 호환성 문제가 있을 가능성이 있습니다. 추가적으로 이 기능은 전용 액터가 공개된 게시물이나 계정을 페치하는 것은 막지 않습니다. authorized_fetch_hint: 연합된 서버들에게서 인증을 요구하는 것은 사용자 레벨과 서버 레벨의 차단을 좀 더 확실하게 해줍니다. 한편으로는 성능적인 페널티, 답글의 전달 범위 감소, 몇몇 연합된 서비스들과의 호환성 문제가 있을 가능성이 있습니다. 추가적으로 이 기능은 전용 액터가 공개된 게시물이나 계정을 페치하는 것은 막지 않습니다.
@ -950,6 +952,9 @@ ko:
title: 웹훅 title: 웹훅
webhook: 웹훅 webhook: 웹훅
admin_mailer: admin_mailer:
auto_close_registrations:
body: 최근 모더레이터 활동 부족으로, %{instance}가 안좋은 일에 사용되는 것을 방지하기 위해 %{instance}의 가입이 수동 심사를 요구하도록 자동으로 변경되었습니다. 언제든지 가입을 다시 열 수 있습니다.
subject: "%{instance}의 가입이 승인을 필요로 하도록 자동으로 변경되었습니다"
new_appeal: new_appeal:
actions: actions:
delete_statuses: 게시물을 삭제하는 것 delete_statuses: 게시물을 삭제하는 것

View file

@ -767,6 +767,7 @@ lad:
disabled: A dinguno disabled: A dinguno
users: Para los utilizadores lokales ke entrado en su kuento users: Para los utilizadores lokales ke entrado en su kuento
registrations: registrations:
moderation_recommandation: Por favor, asigurate ke tyenes una taifa de moderasyon adekuada i reaktiva antes de avrir los enrejistramyentos a todos!
preamble: Kontrola ken puede kriyar un kuento en tu sirvidor. preamble: Kontrola ken puede kriyar un kuento en tu sirvidor.
title: Enrejistramientos title: Enrejistramientos
registrations_mode: registrations_mode:
@ -774,6 +775,7 @@ lad:
approved: Se rekiere achetasion para enrejistrarse approved: Se rekiere achetasion para enrejistrarse
none: Permete a los utilizadores trokar la konfigurasyon del sitio none: Permete a los utilizadores trokar la konfigurasyon del sitio
open: Kualkiera puede enrejistrarse open: Kualkiera puede enrejistrarse
warning_hint: Rekomendamos el uzo de "Se rekiere achetasion para enrejistrarse" a manko ke estes siguro ke tu taifa de moderasyon puede moderar el spam i los enrejistramyentos malisiozos en un tyempo razonavle.
security: security:
authorized_fetch: Rekere autentifikasyon de sirvidores federados authorized_fetch: Rekere autentifikasyon de sirvidores federados
authorized_fetch_hint: Rekerir autentifikasyon de sirvidores federados permite un forsamyento mas estrikto de los blokos a nivel de utilizador i a nivel de sirvidor. Malgrado esto, el koste de esto es una penalizasyon de efisyensya, reduksyon del alkanse de tus repuestas i puede introduzir problemas de kompatibilita kon algunos sirvisyos federados. Ademas, esto no impidira ke aktores dedikados obtengan tus kuentos publikos i publikasyones publikas. authorized_fetch_hint: Rekerir autentifikasyon de sirvidores federados permite un forsamyento mas estrikto de los blokos a nivel de utilizador i a nivel de sirvidor. Malgrado esto, el koste de esto es una penalizasyon de efisyensya, reduksyon del alkanse de tus repuestas i puede introduzir problemas de kompatibilita kon algunos sirvisyos federados. Ademas, esto no impidira ke aktores dedikados obtengan tus kuentos publikos i publikasyones publikas.
@ -966,6 +968,9 @@ lad:
title: Webhooks title: Webhooks
webhook: Webhook webhook: Webhook
admin_mailer: admin_mailer:
auto_close_registrations:
body: Por la falta de moderadores aktivos, los enrejistramyentos en %{instance} tyenen sido trokados otomatikamente para rekerir revizyon manuala, para ke %{instance} no se utilize potensyalmente komo platforma por malos aktores. Puedes trokarlo de muevo para avrir los enrejistramyentos en kualseker momento.
subject: Enrejistramyentos de %{instance} fueron otomatikamente trokados i agora nesesitan aprovasyon
new_appeal: new_appeal:
actions: actions:
delete_statuses: para supremir sus mesajes delete_statuses: para supremir sus mesajes

View file

@ -281,6 +281,8 @@ lt:
desc_html: Tai priklauso nuo hCaptcha išorinių skriptų, kurie gali kelti susirūpinimą dėl saugumo ir privatumo. Be to, <strong>dėl to registracijos procesas kai kuriems žmonėms (ypač neįgaliesiems) gali būti gerokai sunkiau prieinami</strong>. Dėl šių priežasčių apsvarstyk alternatyvias priemones, pavyzdžiui, patvirtinimu arba kvietimu grindžiamą registraciją. desc_html: Tai priklauso nuo hCaptcha išorinių skriptų, kurie gali kelti susirūpinimą dėl saugumo ir privatumo. Be to, <strong>dėl to registracijos procesas kai kuriems žmonėms (ypač neįgaliesiems) gali būti gerokai sunkiau prieinami</strong>. Dėl šių priežasčių apsvarstyk alternatyvias priemones, pavyzdžiui, patvirtinimu arba kvietimu grindžiamą registraciją.
domain_blocks: domain_blocks:
all: Visiems all: Visiems
registrations:
moderation_recommandation: Prieš atidarant registraciją visiems, įsitikink, kad turi tinkamą ir reaguojančią prižiūrėjimo komandą!
software_updates: software_updates:
description: Rekomenduojama nuolat atnaujinti Mastodon diegyklę, kad galėtum naudotis naujausiais pataisymais ir funkcijomis. Be to, kartais labai svarbu laiku naujinti Mastodon, kad būtų išvengta saugumo problemų. Dėl šių priežasčių Mastodon kas 30 minučių tikrina, ar yra atnaujinimų, ir praneša tau apie tai pagal tavo el. pašto pranešimų parinktis. description: Rekomenduojama nuolat atnaujinti Mastodon diegyklę, kad galėtum naudotis naujausiais pataisymais ir funkcijomis. Be to, kartais labai svarbu laiku naujinti Mastodon, kad būtų išvengta saugumo problemų. Dėl šių priežasčių Mastodon kas 30 minučių tikrina, ar yra atnaujinimų, ir praneša tau apie tai pagal tavo el. pašto pranešimų parinktis.
statuses: statuses:
@ -304,6 +306,9 @@ lt:
edit_preset: Keisti įspėjimo nustatymus edit_preset: Keisti įspėjimo nustatymus
title: Valdyti įspėjimo nustatymus title: Valdyti įspėjimo nustatymus
admin_mailer: admin_mailer:
auto_close_registrations:
body: Dėl pastarojo meto peržiūrėtojų aktyvumo trūkumo %{instance} registracija buvo automatiškai pakeista į reikalaujančią rankinės būdo peržiūros, kad %{instance} nebūtų naudojama kaip platforma potencialiems blogiems veikėjams. Bet kuriuo metu gali ją vėl perjungti į atvirą registraciją.
subject: "%{instance} registracijos automatiškai pakeistos į reikalaujančias patvirtinimo"
new_report: new_report:
body: "%{reporter} parašė skundą apie %{target}" body: "%{reporter} parašė skundą apie %{target}"
body_remote: Kažkas iš %{domain} parašė skundą apie %{target} body_remote: Kažkas iš %{domain} parašė skundą apie %{target}

View file

@ -31,7 +31,7 @@ nn:
created_msg: Moderatormerknad er laga! created_msg: Moderatormerknad er laga!
destroyed_msg: Moderatormerknad er utsletta! destroyed_msg: Moderatormerknad er utsletta!
accounts: accounts:
add_email_domain_block: Gøym e-postdomene add_email_domain_block: Blokker e-postdomene
approve: Godtak approve: Godtak
approved_msg: Godkjende %{username} sin registreringssøknad approved_msg: Godkjende %{username} sin registreringssøknad
are_you_sure: Er du sikker? are_you_sure: Er du sikker?
@ -767,13 +767,15 @@ nn:
disabled: Til ingen disabled: Til ingen
users: Til lokale brukarar som er logga inn users: Til lokale brukarar som er logga inn
registrations: registrations:
moderation_recommandation: Pass på at du har mange og kjappe redaktørar og moderatorar på laget ditt før du opnar for allmenn registrering!
preamble: Kontroller kven som kan oppretta konto på tenaren din. preamble: Kontroller kven som kan oppretta konto på tenaren din.
title: Registreringar title: Registreringar
registrations_mode: registrations_mode:
modes: modes:
approved: Godkjenning kreves for påmelding approved: Godkjenning krevst for å registrera seg
none: Ingen kan melda seg inn none: Ingen kan melda seg inn
open: Kven som helst kan melda seg inn open: Kven som helst kan melda seg inn
warning_hint: Me rår til at du bruker "Godkjenning krevst for å registrera seg" viss du ikkje er sikker på at moderatorane kan handtera søppel og illmeinte registreringar kvikt.
security: security:
authorized_fetch: Krev autentisering frå fødererte tenarar authorized_fetch: Krev autentisering frå fødererte tenarar
authorized_fetch_hint: Krav om autentisering frå fødererte tenarar gjer det mogleg med strengare handheving av blokkering, både på brukar- og tenar-nivå. Likevel, dette har ein kostnad når det gjeld yting, reduserer rekkevidda til svara dine og kan medføra kompabilitetsproblem med enkelte fødererte tenester. Dette vil heller ikkje hindra dei som verkeleg vil i å henta dei offentlege innlegga eller kontoane dine. authorized_fetch_hint: Krav om autentisering frå fødererte tenarar gjer det mogleg med strengare handheving av blokkering, både på brukar- og tenar-nivå. Likevel, dette har ein kostnad når det gjeld yting, reduserer rekkevidda til svara dine og kan medføra kompabilitetsproblem med enkelte fødererte tenester. Dette vil heller ikkje hindra dei som verkeleg vil i å henta dei offentlege innlegga eller kontoane dine.
@ -1450,7 +1452,7 @@ nn:
moderation: moderation:
title: Moderasjon title: Moderasjon
move_handler: move_handler:
carry_blocks_over_text: Denne brukaren flytta frå %{acct}, som du gøymde. carry_blocks_over_text: Denne brukaren flytta frå %{acct}, som du hadde blokkert.
carry_mutes_over_text: Denne brukeren flyttet fra %{acct}, som du hadde dempet. carry_mutes_over_text: Denne brukeren flyttet fra %{acct}, som du hadde dempet.
copy_account_note_text: 'Denne brukeren flyttet fra %{acct}, her var dine tidligere notater om dem:' copy_account_note_text: 'Denne brukeren flyttet fra %{acct}, her var dine tidligere notater om dem:'
navigation: navigation:
@ -1537,7 +1539,7 @@ nn:
privacy: privacy:
hint_html: "<strong>Tilpass korleis du vil at andre skal finna profilen og innlegga dine.</strong> Mastodon har fleire funksjonar du kan ta i bruk for å få kontakt med eit større publikum. Sjå gjerne gjennom innstillingane slik at du er sikker på at dei passar til deg og din bruk." hint_html: "<strong>Tilpass korleis du vil at andre skal finna profilen og innlegga dine.</strong> Mastodon har fleire funksjonar du kan ta i bruk for å få kontakt med eit større publikum. Sjå gjerne gjennom innstillingane slik at du er sikker på at dei passar til deg og din bruk."
privacy: Personvern privacy: Personvern
privacy_hint_html: Ha kontroll over kor mykje du vil dela. Folk finn interessante profilar og fine appar ved å sjå gjennom kva andre fylgjer og kva appar dei legg ut innlegg med, men det kan henda du vil gøyma desse opplysingane. privacy_hint_html: Kontroller kor mykje du vil dela. Folk finn interessante profilar og fine appar ved å sjå gjennom kva andre fylgjer og kva appar dei legg ut innlegg med, men det kan henda du vil gøyma desse opplysingane.
reach: Nå andre reach: Nå andre
reach_hint_html: Hald styring med om du vil at andre skal kunna oppdaga og fylgja deg. Vil du at innlegga dine skal stå på Utforsk-sida? Vil du at andre skal sjå deg i tilrådingane for kven dei skal fylgja? Vil du ta imot nye fylgjarar automatisk, eller vil du kontrollera kvar einskild fylgjar? reach_hint_html: Hald styring med om du vil at andre skal kunna oppdaga og fylgja deg. Vil du at innlegga dine skal stå på Utforsk-sida? Vil du at andre skal sjå deg i tilrådingane for kven dei skal fylgja? Vil du ta imot nye fylgjarar automatisk, eller vil du kontrollera kvar einskild fylgjar?
search: Søk search: Søk
@ -1550,8 +1552,8 @@ nn:
limit_reached: Grensen for forskjellige reaksjoner nådd limit_reached: Grensen for forskjellige reaksjoner nådd
unrecognized_emoji: er ikke en gjenkjent emoji unrecognized_emoji: er ikke en gjenkjent emoji
redirects: redirects:
prompt: Hvis du stoler på denne lenken, så trykk på den for å fortsette. prompt: Viss du stolar på denne lenka, klikkar du på ho for å halda fram.
title: Du forlater %{instance}. title: No forlèt du %{instance}.
relationships: relationships:
activity: Kontoaktivitet activity: Kontoaktivitet
confirm_follow_selected_followers: Er du sikker på at du ynskjer å fylgja dei valde fylgjarane? confirm_follow_selected_followers: Er du sikker på at du ynskjer å fylgja dei valde fylgjarane?
@ -1781,7 +1783,7 @@ nn:
webauthn: Sikkerhetsnøkler webauthn: Sikkerhetsnøkler
user_mailer: user_mailer:
appeal_approved: appeal_approved:
action: Kontoinnstillinger action: Kontoinnstillingar
explanation: Apellen på prikken mot din kontor på %{strike_date} som du la inn på %{appeal_date} har blitt godkjend. Din konto er nok ein gong i god stand. explanation: Apellen på prikken mot din kontor på %{strike_date} som du la inn på %{appeal_date} har blitt godkjend. Din konto er nok ein gong i god stand.
subject: Din klage fra %{date} er godkjent subject: Din klage fra %{date} er godkjent
subtitle: Kontoen din er tilbake i god stand. subtitle: Kontoen din er tilbake i god stand.
@ -1789,11 +1791,11 @@ nn:
appeal_rejected: appeal_rejected:
explanation: Klagen på advarselen mot din konto den %{strike_date} som du sendte inn den %{appeal_date} har blitt avvist. explanation: Klagen på advarselen mot din konto den %{strike_date} som du sendte inn den %{appeal_date} har blitt avvist.
subject: Din klage fra %{date} er avvist subject: Din klage fra %{date} er avvist
subtitle: Anken din har blitt avvist. subtitle: Klaga di vart avvist.
title: Anke avvist title: Anke avvist
backup_ready: backup_ready:
explanation: Du etterspurte en fullstendig sikkerhetskopi av din Mastodon-konto. explanation: Du ba om ein fullstendig tryggingskopi av Mastodon-kontoen din.
extra: Den er nå klar for nedlasting! extra: No kan du lasta han ned!
subject: Arkivet ditt er klart til å lastes ned subject: Arkivet ditt er klart til å lastes ned
title: Nedlasting av arkiv title: Nedlasting av arkiv
failed_2fa: failed_2fa:

View file

@ -767,6 +767,7 @@ pt-BR:
disabled: Para ninguém disabled: Para ninguém
users: Para usuários locais logados users: Para usuários locais logados
registrations: registrations:
moderation_recommandation: Por favor, certifique-se de ter uma equipe de moderação adequada e reativa antes de abrir as inscrições para todos!
preamble: Controle quem pode criar uma conta no seu servidor. preamble: Controle quem pode criar uma conta no seu servidor.
title: Inscrições title: Inscrições
registrations_mode: registrations_mode:

View file

@ -968,6 +968,9 @@ pt-PT:
title: Webhooks title: Webhooks
webhook: Webhook webhook: Webhook
admin_mailer: admin_mailer:
auto_close_registrations:
body: Devido à falta de atividade recente dos moderadores, as inscrições em %{instance} foram automaticamente alteradas para requererem revisão manual, para evitar que %{instance} seja utilizada como plataforma para potenciais maus atores. Pode voltar a alterar para inscrições abertas em qualquer altura.
subject: As incrições em %{instance} foram automaticamente alteradas para requererem aprovação
new_appeal: new_appeal:
actions: actions:
delete_statuses: para eliminar as suas publicações delete_statuses: para eliminar as suas publicações

View file

@ -31,14 +31,12 @@ an:
text: Nomás puetz apelar una amonestación una vegada text: Nomás puetz apelar una amonestación una vegada
defaults: defaults:
autofollow: Los usuarios que se rechistren per medio d'a invitación te seguirán automaticament autofollow: Los usuarios que se rechistren per medio d'a invitación te seguirán automaticament
avatar: PNG, GIF u JPG. Maximo %{size}. Será escalau a %{dimensions}px
bot: Esta cuenta executa prencipalment accions automatizadas y podría no estar monitorizada bot: Esta cuenta executa prencipalment accions automatizadas y podría no estar monitorizada
context: Un u multiples contextos en os quals ha d'aplicar-se lo filtro context: Un u multiples contextos en os quals ha d'aplicar-se lo filtro
current_password: Per razons de seguranza per favor ingrese la clau d'a cuenta actual current_password: Per razons de seguranza per favor ingrese la clau d'a cuenta actual
current_username: Pa confirmar, per favor ingrese lo nombre d'usuario d'a cuenta actual current_username: Pa confirmar, per favor ingrese lo nombre d'usuario d'a cuenta actual
digest: Solo ninviau dimpués d'un largo periodo d'inactividat y nomás si has recibiu mensaches personals entre la tuya ausencia digest: Solo ninviau dimpués d'un largo periodo d'inactividat y nomás si has recibiu mensaches personals entre la tuya ausencia
email: Se le ninviará un correu de confirmación email: Se le ninviará un correu de confirmación
header: PNG, GIF u JPG. Maximo %{size}. Será escalau a %{dimensions}px
inbox_url: Copia la URL d'a pachina prencipal d'o relés que quiers utilizar inbox_url: Copia la URL d'a pachina prencipal d'o relés que quiers utilizar
irreversible: Las publicacions filtradas desapareixerán irreversiblement, mesmo si este filtro ye eliminau mas abance irreversible: Las publicacions filtradas desapareixerán irreversiblement, mesmo si este filtro ye eliminau mas abance
locale: L'idioma d'a interficie d'usuario, correus y notificacions push locale: L'idioma d'a interficie d'usuario, correus y notificacions push

View file

@ -39,14 +39,12 @@ ar:
text: يمكنك الطعن في عقوبة مرة واحدة فقط text: يمكنك الطعن في عقوبة مرة واحدة فقط
defaults: defaults:
autofollow: سوف يتابعك تلقائيًا الأشخاص الذين يقومون بالتسجيل من خلال الدعوة autofollow: سوف يتابعك تلقائيًا الأشخاص الذين يقومون بالتسجيل من خلال الدعوة
avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px
bot: يقوم هذا الحساب أساسا بإجراءات آلية وقد لا يتم مراقبته bot: يقوم هذا الحساب أساسا بإجراءات آلية وقد لا يتم مراقبته
context: واحد أو أكثر من السياقات التي يجب أن ينطبق عليها عامل التصفية context: واحد أو أكثر من السياقات التي يجب أن ينطبق عليها عامل التصفية
current_password: لأسباب أمنية ، يرجى إدخال الكلمة السرية الخاصة بالحساب الحالي current_password: لأسباب أمنية ، يرجى إدخال الكلمة السرية الخاصة بالحساب الحالي
current_username: يرجى إدخال اسم المستخدم الخاص بالحساب الحالي قصد التأكيد current_username: يرجى إدخال اسم المستخدم الخاص بالحساب الحالي قصد التأكيد
digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة
email: سوف تتلقى رسالة إلكترونية للتأكيد email: سوف تتلقى رسالة إلكترونية للتأكيد
header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px
inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الاستقبال للمُرحَّل inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الاستقبال للمُرحَّل
irreversible: المنشورات التي تم تصفيتها ستختفي لا محالة حتى و إن تمت إزالة عامِل التصفية لاحقًا irreversible: المنشورات التي تم تصفيتها ستختفي لا محالة حتى و إن تمت إزالة عامِل التصفية لاحقًا
locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات

View file

@ -18,10 +18,8 @@ ast:
text: Pues usar la sintaxis de los artículos. Ten en cuenta l'espaciu que l'anunciu va ocupar na pantalla del usuariu/a text: Pues usar la sintaxis de los artículos. Ten en cuenta l'espaciu que l'anunciu va ocupar na pantalla del usuariu/a
defaults: defaults:
autofollow: Les persones que se rexistren pente la invitación van siguite automáticamente autofollow: Les persones que se rexistren pente la invitación van siguite automáticamente
avatar: Ficheros PNG, GIF o JPG de %{size} como muncho. La semeya va redimensionase a %{dimensions} px
bot: Avisa a otres persones de qu'esta cuenta fai principalmente aiciones automatizaes ya de que ye posible que nun tean supervisaes bot: Avisa a otres persones de qu'esta cuenta fai principalmente aiciones automatizaes ya de que ye posible que nun tean supervisaes
digest: Namás s'unvia dempués d'un periodu llongu d'inactividá ya namás si recibiesti dalgún mensaxe personal demientres la to ausencia digest: Namás s'unvia dempués d'un periodu llongu d'inactividá ya namás si recibiesti dalgún mensaxe personal demientres la to ausencia
header: Ficheros PNG, GIF o JPG de %{size} como muncho. La semeya va redimensionase a %{dimensions} px
irreversible: Los artículos peñeraos desapaecen de forma irreversible, magar que la peñera se quite dempués irreversible: Los artículos peñeraos desapaecen de forma irreversible, magar que la peñera se quite dempués
locale: La llingua de la interfaz, los mensaxes per corréu electrónicu ya los avisos push locale: La llingua de la interfaz, los mensaxes per corréu electrónicu ya los avisos push
password: Usa polo menos 8 caráuteres password: Usa polo menos 8 caráuteres

View file

@ -39,14 +39,14 @@ be:
text: Вы можаце абскардзіць рашэнне толькі адзін раз text: Вы можаце абскардзіць рашэнне толькі адзін раз
defaults: defaults:
autofollow: Людзі, якія зарэгістраваліся праз запрашэнне, аўтаматычна падпішуцца на вас autofollow: Людзі, якія зарэгістраваліся праз запрашэнне, аўтаматычна падпішуцца на вас
avatar: PNG, GIF ці JPG. Не больш за %{size}. Будзе сціснуты да памеру %{dimensions}} пікселяў avatar: WEBP, PNG, GIF ці JPG. Не больш за %{size}. Будзе сціснуты да памеру %{dimensions}} пікселяў
bot: Паведаміць іншым, што гэты ўліковы запіс у асноўным выконвае аўтаматычныя дзеянні і можа не кантралявацца bot: Паведаміць іншым, што гэты ўліковы запіс у асноўным выконвае аўтаматычныя дзеянні і можа не кантралявацца
context: Адзін ці некалькі кантэкстаў, да якіх трэба прымяніць фільтр context: Адзін ці некалькі кантэкстаў, да якіх трэба прымяніць фільтр
current_password: У мэтах бяспекі, калі ласка, увядзіце пароль бягучага ўліковага запісу current_password: У мэтах бяспекі, калі ласка, увядзіце пароль бягучага ўліковага запісу
current_username: Каб пацвердзіць, увядзіце, калі ласка імя карыстальніка бягучага ўліковага запісу current_username: Каб пацвердзіць, увядзіце, калі ласка імя карыстальніка бягучага ўліковага запісу
digest: Будзе даслана толькі пасля доўгага перыяду неактыўнасці і толькі калі вы атрымалі асабістыя паведамленні падчас вашай адсутнасці digest: Будзе даслана толькі пасля доўгага перыяду неактыўнасці і толькі калі вы атрымалі асабістыя паведамленні падчас вашай адсутнасці
email: Пацвярджэнне будзе выслана па электроннай пошце email: Пацвярджэнне будзе выслана па электроннай пошце
header: PNG, GIF ці JPG. Не больш за %{size}. Будзе сціснуты да памеру %{dimensions}} пікселяў header: WEBP, PNG, GIF ці JPG. Не больш за %{size}. Будзе сціснуты да памеру %{dimensions}} пікселяў
inbox_url: Капіраваць URL са старонкі рэтранслятара, якім вы хочаце карыстацца inbox_url: Капіраваць URL са старонкі рэтранслятара, якім вы хочаце карыстацца
irreversible: Адфільтраваныя пасты прападуць незваротна, нават калі фільтр потым будзе выдалены irreversible: Адфільтраваныя пасты прападуць незваротна, нават калі фільтр потым будзе выдалены
locale: Мова карыстальніцкага інтэрфейсу, электронных паведамленняў і апавяшчэнняў locale: Мова карыстальніцкага інтэрфейсу, электронных паведамленняў і апавяшчэнняў

View file

@ -9,7 +9,7 @@ bg:
indexable: Вашите обществени публикации може да се появят в резултатите от търсене в Mastodon. Взаимодействалите с публикациите ви може да ги търсят независимо. indexable: Вашите обществени публикации може да се появят в резултатите от търсене в Mastodon. Взаимодействалите с публикациите ви може да ги търсят независимо.
note: 'Може да @споменавате други хора или #хаштагове.' note: 'Може да @споменавате други хора или #хаштагове.'
show_collections: Хората ще може да разглеждат през вашите последвания и последователи. Хората, които сте следвали, ще видят, че ги следвате независимо от това. show_collections: Хората ще може да разглеждат през вашите последвания и последователи. Хората, които сте следвали, ще видят, че ги следвате независимо от това.
unlocked: Хората ще може да ви следват без да се изисква одобрение. Размаркирайте, ако искате да преглеждате заявките за последване и изберете дали да приемете или отхвърлите новите последователи. unlocked: Хората ще могат да ви последват без изискване на одобрение. Размаркирайте, ако искате да преглеждате заявките за последване и изберете дали да приемете или отхвърлите новите последователи.
account_alias: account_alias:
acct: Посочете потребителско_име@домейн на акаунта си, от който искате да се преместите acct: Посочете потребителско_име@домейн на акаунта си, от който искате да се преместите
account_migration: account_migration:
@ -39,14 +39,14 @@ bg:
text: Може да възразите срещу провинение само веднъж text: Може да възразите срещу провинение само веднъж
defaults: defaults:
autofollow: Хората, които се регистрират чрез поканата, автоматично ще ви последват autofollow: Хората, които се регистрират чрез поканата, автоматично ще ви последват
avatar: PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела avatar: WEBP, PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела
bot: Сигнализиране до другите, че акаунтът изпълнява предимно автоматизирани деяния и може да не се наблюдава bot: Сигнализиране до другите, че акаунтът изпълнява предимно автоматизирани деяния и може да не се наблюдава
context: Един или повече контексти, към които да се приложи филтърът context: Един или повече контексти, към които да се приложи филтърът
current_password: От съображения за сигурност, въведете паролата на текущия акаунт current_password: От съображения за сигурност, въведете паролата на текущия акаунт
current_username: Въведете потребителското име на текущия профил, за да потвърдите current_username: Въведете потребителското име на текущия профил, за да потвърдите
digest: Изпраща се само след дълъг период на бездействие и само ако сте получили лични съобщения във ваше отсъствие digest: Изпраща се само след дълъг период на бездействие и само ако сте получили лични съобщения във ваше отсъствие
email: Ще ви се изпрати имейл за потвърждение email: Ще ви се изпрати имейл за потвърждение
header: PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела header: WEBP, PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела
inbox_url: Копирайте URL адреса от заглавната страница на предаващия сървър, който искате да използвате inbox_url: Копирайте URL адреса от заглавната страница на предаващия сървър, който искате да използвате
irreversible: Филтрираните публикации ще изчезнат безвъзвратно, дори филтърът да бъде премахнат по-късно irreversible: Филтрираните публикации ще изчезнат безвъзвратно, дори филтърът да бъде премахнат по-късно
locale: Езикът на потребителския интерфейс, известиятата по имейл и насочените известия locale: Езикът на потребителския интерфейс, известиятата по имейл и насочените известия

Some files were not shown because too many files have changed in this diff Show more