Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • TransFem-org/Sharkey
  • fEmber/Sharkey
  • kopper/Sharkey
  • dakkar/Sharkey-thenautilus
  • esm/Sharkey
  • blueb/Sharkey
  • aura/Sharkey
  • alicem/Sharkey
  • dimkr/Sharkey
  • vvinrg/Sharkey
  • tess/Sharkey
  • Latte_macchiato/Sharkey
  • skyevg/Sharkey
  • TransFem-org/sharkey-trans-fem
  • limepotato/sharkey
  • elrant/villkey
  • kio/kitsukey
  • 4censord/Sharkey
  • kanade/Sharkey
  • kakkokari-gtyih/Sharkey
  • piuvas/Sharkey
  • kio/gaykey
  • owlbear/Sharkey
  • esurio/Sharkey
  • cuteBoiButt/Sharkey
  • magi/Sharkey
  • chikorita157/Sharkey
  • CenTdemeern1/Sharkey
  • GeopJr/Sharkey
  • lhcfl/sharkey
  • cody/Sharkey
  • puppygirlhornypost/Sharkey
  • Sneexy/Sharkey
  • zotan/Sharkey
  • Marie/Sharkey
  • maciejla/Sharkey
  • transitory/Sharkey
  • Caramel/Sharkey
  • fly_mc/Sharkey
  • 87/Sharkey
  • echo/Sharkey
  • transfemsoc/Sharkey
  • ch0ccyra1n/Sharkey
  • interru/Sharkey
  • legiayayana/Sharkey
  • elizabeth-dev/Sharkey
  • JeDaYoshi/Sharkey
  • bunnybeam/Sharkey
  • and-then-there-were-two/Sharkey
  • easrng/Sharkey
  • HellhoundSoftware/Sharkey
  • realkinetix/Sharkey
  • sandervankasteel/Sharkey
  • jacobwhall/Sharkey
  • Daniel/Sharkey
  • rhythmkey/rhythmkey
56 results
Show changes
Showing
with 3266 additions and 243 deletions
files:
- source: /locales/ja-JP.yml
translation: /locales/%locale%.yml
- source: /sharkey-locales/en-US.yml
translation: /sharkey-locales/%locale%.yml
update_option: update_as_unapproved
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
describe('Before setup instance', () => {
beforeEach(() => {
cy.resetState();
......@@ -18,6 +23,7 @@ describe('Before setup instance', () => {
cy.intercept('POST', '/api/admin/accounts/create').as('signup');
cy.get('[data-cy-admin-initial-password] input').type('example_password_please_change_this_or_you_will_get_hacked');
cy.get('[data-cy-admin-username] input').type('admin');
cy.get('[data-cy-admin-password] input').type('admin1234');
cy.get('[data-cy-admin-ok]').click();
......@@ -114,11 +120,16 @@ describe('After user signup', () => {
it('signin', () => {
cy.visitHome();
cy.intercept('POST', '/api/signin').as('signin');
cy.intercept('POST', '/api/signin-flow').as('signin');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
// Enterキーでサインインできるかの確認も兼ねる
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
// Enterキーで続行できるかの確認も兼ねる
cy.get('[data-cy-signin-username] input').type('alice{enter}');
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
// Enterキーで続行できるかの確認も兼ねる
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.wait('@signin');
......@@ -133,8 +144,9 @@ describe('After user signup', () => {
cy.visitHome();
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type('alice');
cy.get('[data-cy-signin-password] input').type('alice1234{enter}');
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
cy.get('[data-cy-signin-username] input').type('alice{enter}');
// TODO: cypressにブラウザの言語指定できる機能が実装され次第英語のみテストするようにする
cy.contains(/アカウントが凍結されています|This account has been suspended due to/gi);
......@@ -161,11 +173,13 @@ describe('After user signed in', () => {
});
it('successfully loads', () => {
cy.get('[data-cy-user-setup-continue]').should('be.visible');
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
cy.get('[data-cy-user-setup-continue]', { timeout: 30000 }).should('be.visible');
});
it('account setup wizard', () => {
cy.get('[data-cy-user-setup-continue]').click();
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
cy.get('[data-cy-user-setup-continue]', { timeout: 30000 }).click();
cy.get('[data-cy-user-setup-user-name] input').type('ありす');
cy.get('[data-cy-user-setup-user-description] textarea').type('ほげ');
......@@ -202,7 +216,8 @@ describe('After user setup', () => {
cy.login('alice', 'alice1234');
// アカウント初期設定ウィザード
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]').click();
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]', { timeout: 30000 }).click();
cy.get('[data-cy-modal-dialog-ok]').click();
});
......
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
describe('Router transition', () => {
describe('Redirect', () => {
// サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い)
before(() => {
cy.resetState();
// インスタンス初期セットアップ
cy.registerUser('admin', 'pass', true);
// ユーザー作成
cy.registerUser('alice', 'alice1234');
cy.login('alice', 'alice1234');
// アカウント初期設定ウィザード
// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
cy.get('[data-cy-user-setup] [data-cy-modal-window-close]', { timeout: 30000 }).click();
cy.wait(500);
cy.get('[data-cy-modal-dialog-ok]').click();
});
it('redirect to user profile', () => {
// テストのためだけに用意されたリダイレクト用ルートに飛ぶ
cy.visit('/redirect-test');
// プロフィールページのURLであることを確認する
cy.url().should('include', '/@alice')
});
});
});
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* flaky
describe('After user signed in', () => {
beforeEach(() => {
......
......@@ -30,9 +30,13 @@ Cypress.Commands.add('visitHome', () => {
})
Cypress.Commands.add('resetState', () => {
cy.window(win => {
// iframe.contentWindow.indexedDB.deleteDatabase() がchromeのバグで使用できないため、indexedDBを無効化している。
// see https://github.com/misskey-dev/misskey/issues/13605#issuecomment-2053652123
/*
cy.window().then(win => {
win.indexedDB.deleteDatabase('keyval-store');
});
*/
cy.request('POST', '/api/reset-db', {}).as('reset');
cy.get('@reset').its('status').should('equal', 204);
cy.reload(true);
......@@ -44,16 +48,19 @@ Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
cy.request('POST', route, {
username: username,
password: password,
...(isAdmin ? { setupPassword: 'example_password_please_change_this_or_you_will_get_hacked' } : {}),
}).its('body').as(username);
});
Cypress.Commands.add('login', (username, password) => {
cy.visitHome();
cy.intercept('POST', '/api/signin').as('signin');
cy.intercept('POST', '/api/signin-flow').as('signin');
cy.get('[data-cy-signin]').click();
cy.get('[data-cy-signin-username] input').type(username);
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
cy.get('[data-cy-signin-username] input').type(`${username}{enter}`);
cy.get('[data-cy-signin-page-password]').should('be.visible', { timeout: 10000 });
cy.get('[data-cy-signin-password] input').type(`${password}{enter}`);
cy.wait('@signin').as('signedIn');
......
File moved
declare global {
namespace Cypress {
interface Chainable {
login(username: string, password: string): Chainable<void>;
registerUser(
username: string,
password: string,
isAdmin?: boolean
): Chainable<void>;
resetState(): Chainable<void>;
visitHome(): Chainable<void>;
}
}
}
export {}
{
"compilerOptions": {
"lib": ["dom", "es5"],
"target": "es5",
"types": ["cypress", "node"]
},
"include": ["./**/*.ts"]
}
/*
* SPDX-FileCopyrightText: dakkar and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* This is a ESLint rule to report use of the `i18n.ts` and `i18n.tsx`
* objects that reference translation items that don't actually exist
* in the lexicon (the `locale/` files)
*/
/* given a MemberExpression node, collects all the member names
*
* e.g. for a bit of code like `foo=one.two.three`, `collectMembers`
* called on the node for `three` would return `['one', 'two',
* 'three']`
*/
function collectMembers(node) {
if (!node) return [];
if (node.type !== 'MemberExpression') return [];
// this is something like `foo[bar]`
if (node.computed) return [];
return [ node.property.name, ...collectMembers(node.parent) ];
}
/* given an object and an array of names, recursively descends the
* object via those names
*
* e.g. `walkDown({one:{two:{three:15}}},['one','two','three'])` would
* return 15
*/
function walkDown(locale, path) {
if (!locale) return null;
if (!path || path.length === 0 || !path[0]) return locale;
return walkDown(locale[path[0]], path.slice(1));
}
/* given a MemberExpression node, returns its attached CallExpression
* node if present
*
* e.g. for a bit of code like `foo=one.two.three()`,
* `findCallExpression` called on the node for `three` would return
* the node for function call (which is the parent of the `one` and
* `two` nodes, and holds the nodes for the argument list)
*
* if the code had been `foo=one.two.three`, `findCallExpression`
* would have returned null, because there's no function call attached
* to the MemberExpressions
*/
function findCallExpression(node) {
if (!node.parent) return null;
// the second half of this guard protects from cases like
// `foo(one.two.three)` where the CallExpression is parent of the
// MemberExpressions, but via `arguments`, not `callee`
if (node.parent.type === 'CallExpression' && node.parent.callee === node) return node.parent;
if (node.parent.type === 'MemberExpression') return findCallExpression(node.parent);
return null;
}
// same, but for Vue expressions (`<I18n :src="i18n.ts.foo">`)
function findVueExpression(node) {
if (!node.parent) return null;
if (node.parent.type.match(/^VExpr/) && node.parent.expression === node) return node.parent;
if (node.parent.type === 'MemberExpression') return findVueExpression(node.parent);
return null;
}
function areArgumentsOneObject(node) {
return node.arguments.length === 1 &&
node.arguments[0].type === 'ObjectExpression';
}
// only call if `areArgumentsOneObject(node)` is true
function getArgumentObjectProperties(node) {
return new Set(node.arguments[0].properties.map(
p => {
if (p.key && p.key.type === 'Identifier') return p.key.name;
return null;
},
));
}
function getTranslationParameters(translation) {
return new Set(Array.from(translation.matchAll(/\{(\w+)\}/g)).map( m => m[1] ));
}
function setDifference(a,b) {
const result = [];
for (const element of a.values()) {
if (!b.has(element)) {
result.push(element);
}
}
return result;
}
/* the actual rule body
*/
function theRuleBody(context,node) {
// we get the locale/translations via the options; it's the data
// that goes into a specific language's JSON file, see
// `scripts/build-assets.mjs`
const locale = context.options[0];
// sometimes we get MemberExpression nodes that have a
// *descendent* with the right identifier: skip them, we'll get
// the right ones as well
if (node.object?.name !== 'i18n') {
return;
}
// `method` is going to be `'ts'` or `'tsx'`, `path` is going to
// be the various translation steps/names
const [ method, ...path ] = collectMembers(node);
const pathStr = `i18n.${method}.${path.join('.')}`;
// does that path point to a real translation?
const translation = walkDown(locale, path);
if (!translation) {
context.report({
node,
message: `translation missing for ${pathStr}`,
});
return;
}
// we hit something weird, assume the programmers know what
// they're doing (this is usually some complicated slicing of
// the translation structure)
if (typeof(translation) !== 'string') return;
const callExpression = findCallExpression(node);
const vueExpression = findVueExpression(node);
// some more checks on how the translation is called
if (method === 'ts') {
// the `<I18n> component gets parametric translations via
// `i18n.ts.*`, but we error out elsewhere
if (translation.match(/\{/) && !vueExpression) {
context.report({
node,
message: `translation for ${pathStr} is parametric, but called via 'ts'`,
});
return;
}
if (callExpression) {
context.report({
node,
message: `translation for ${pathStr} is not parametric, but is called as a function`,
});
}
}
if (method === 'tsx') {
if (!translation.match(/\{/)) {
context.report({
node,
message: `translation for ${pathStr} is not parametric, but called via 'tsx'`,
});
return;
}
if (!callExpression && !vueExpression) {
context.report({
node,
message: `translation for ${pathStr} is parametric, but not called as a function`,
});
return;
}
// we're not currently checking arguments when used via the
// `<I18n>` component, because it's too complicated (also, it
// would have to be done inside the `if (method === 'ts')`)
if (!callExpression) return;
if (!areArgumentsOneObject(callExpression)) {
context.report({
node,
message: `translation for ${pathStr} should be called with a single object as argument`,
});
return;
}
const translationParameters = getTranslationParameters(translation);
const parameterCount = translationParameters.size;
const callArguments = getArgumentObjectProperties(callExpression);
const argumentCount = callArguments.size;
if (parameterCount !== argumentCount) {
context.report({
node,
message: `translation for ${pathStr} has ${parameterCount} parameters, but is called with ${argumentCount} arguments`,
});
}
// node 20 doesn't have `Set.difference`...
const extraArguments = setDifference(callArguments, translationParameters);
const missingArguments = setDifference(translationParameters, callArguments);
if (extraArguments.length > 0) {
context.report({
node,
message: `translation for ${pathStr} passes unused arguments ${extraArguments.join(' ')}`,
});
}
if (missingArguments.length > 0) {
context.report({
node,
message: `translation for ${pathStr} does not pass arguments ${missingArguments.join(' ')}`,
});
}
}
}
function theRule(context) {
// we get the locale/translations via the options; it's the data
// that goes into a specific language's JSON file, see
// `scripts/build-assets.mjs`
const locale = context.options[0];
// for all object member access that have an identifier 'i18n'...
return context.getSourceCode().parserServices.defineTemplateBodyVisitor(
{
// this is for <template> bits, needs work
'MemberExpression:has(Identifier[name=i18n])': (node) => theRuleBody(context, node),
},
{
// this is for normal code
'MemberExpression:has(Identifier[name=i18n])': (node) => theRuleBody(context, node),
},
);
}
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'assert that all translations used are present in the locale files',
},
schema: [
// here we declare that we need the locale/translation as a
// generic object
{ type: 'object', additionalProperties: true },
],
},
create: theRule,
};
/*
* SPDX-FileCopyrightText: dakkar and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
const {RuleTester} = require("eslint");
const localeRule = require("./locale");
const locale = { foo: { bar: 'ok', baz: 'good {x}' }, top: '123' };
const ruleTester = new RuleTester({
languageOptions: {
parser: require('vue-eslint-parser'),
ecmaVersion: 2015,
},
});
function testCase(code,errors) {
return { code, errors, options: [ locale ], filename: 'test.ts' };
}
function testCaseVue(code,errors) {
return { code, errors, options: [ locale ], filename: 'test.vue' };
}
ruleTester.run(
'sharkey-locale',
localeRule,
{
valid: [
testCase('i18n.ts.foo.bar'),
testCase('i18n.ts.top'),
testCase('i18n.tsx.foo.baz({x:1})'),
testCase('whatever.i18n.ts.blah.blah'),
testCase('whatever.i18n.tsx.does.not.matter'),
testCase('whatever(i18n.ts.foo.bar)'),
testCaseVue('<template><p>{{ i18n.ts.foo.bar }}</p></template>'),
testCaseVue('<template><I18n :src="i18n.ts.foo.baz"/></template>'),
// we don't detect the problem here, but should still accept it
testCase('i18n.ts.foo["something"]'),
testCase('i18n.ts.foo[something]'),
],
invalid: [
testCase('i18n.ts.not', 1),
testCase('i18n.tsx.deep.not', 1),
testCase('i18n.tsx.deep.not({x:12})', 1),
testCase('i18n.tsx.top({x:1})', 1),
testCase('i18n.ts.foo.baz', 1),
testCase('i18n.tsx.foo.baz', 1),
testCase('i18n.tsx.foo.baz({y:2})', 2),
testCaseVue('<template><p>{{ i18n.ts.not }}</p></template>', 1),
testCaseVue('<template><I18n :src="i18n.ts.not"/></template>', 1),
],
},
);
#!/bin/bash
# SPDX-FileCopyrightText: syuilo and other misskey contributors
# SPDX-FileCopyrightText: syuilo and misskey-project
# SPDX-License-Identifier: AGPL-3.0-only
PORT=$(grep '^port:' /sharkey/.config/default.yml | awk 'NR==1{print $2; exit}')
curl -s -S -o /dev/null "http://localhost:${PORT}"
curl -Sfso/dev/null "http://localhost:${PORT}/healthz"
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions';
import { StoryObj } from '@storybook/vue3';
import { rest } from 'msw';
import { abuseUserReport } from '../../.storybook/fakes';
import { commonHandlers } from '../../.storybook/mocks';
import { HttpResponse, http } from 'msw';
import { abuseUserReport } from '../packages/frontend/.storybook/fakes.js';
import { commonHandlers } from '../packages/frontend/.storybook/mocks.js';
import MkAbuseReport from './MkAbuseReport.vue';
export const Default = {
render(args) {
......@@ -44,9 +44,9 @@ export const Default = {
msw: {
handlers: [
...commonHandlers,
rest.post('/api/admin/resolve-abuse-user-report', async (req, res, ctx) => {
action('POST /api/admin/resolve-abuse-user-report')(await req.json());
return res(ctx.json({}));
http.post('/api/admin/resolve-abuse-user-report', async ({ request }) => {
action('POST /api/admin/resolve-abuse-user-report')(await request.json());
return HttpResponse.json({});
}),
],
},
......
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div :class="[$style.root]">
<div :inert="disabled" :class="[{ [$style.disabled]: disabled }]">
<slot></slot>
</div>
<div v-if="disabled" :class="[$style.cover]"></div>
</div>
</template>
<script lang="ts" setup>
defineProps<{
disabled?: boolean;
}>();
</script>
<style lang="scss" module>
.root {
position: relative;
}
.disabled {
opacity: 0.7;
}
.cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: not-allowed;
--color: color(from var(--MI_THEME-error) srgb r g b / 0.25);
background-size: auto auto;
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, var(--color) 4px, var(--color) 14px);
}
</style>
使われなくなったけど消すのは勿体ない(将来使えるかもしれない)コードを入れておくとこ
......@@ -123,6 +123,7 @@ reactions: "التفاعلات"
reactionSettingDescription2: "اسحب لترتيب ، انقر للحذف ، استخدم \"+\" للإضافة."
rememberNoteVisibility: "تذكر إعدادت مدى رؤية الملاحظات"
attachCancel: "أزل المرفق"
deleteFile: "حُذف الملف"
markAsSensitive: "علّمه كمحتوى حساس"
unmarkAsSensitive: "ألغ تعيينه كمحتوى حساس"
enterFileName: "ادخل اسم الملف"
......@@ -342,7 +343,6 @@ enableLocalTimeline: "تفعيل الخيط المحلي"
enableGlobalTimeline: "تفعيل الخيط الزمني الشامل"
disablingTimelinesInfo: "سيتمكن المديرون والمشرفون من الوصول إلى كل الخيوط الزمنية حتى وإن لم تفعّل."
registration: "إنشاء حساب"
enableRegistration: "تفعيل إنشاء الحسابات الجديدة"
invite: "دعوة"
driveCapacityPerLocalAccount: "حصة التخزين لكل مستخدم محلي"
driveCapacityPerRemoteAccount: "حصة التخزين لكل مستخدم بعيد"
......@@ -360,6 +360,8 @@ hcaptcha: "hCaptcha"
enableHcaptcha: "فعّل hCaptcha"
hcaptchaSiteKey: "مفتاح الموقع"
hcaptchaSecretKey: "المفتاح السري"
mcaptchaSiteKey: "مفتاح الموقع"
mcaptchaSecretKey: "المفتاح السري"
recaptcha: "reCAPTCHA"
enableRecaptcha: "تمكين reCAPTCHA"
recaptchaSiteKey: "مفتاح الموقع"
......@@ -623,10 +625,7 @@ abuseReported: "أُرسل البلاغ، شكرًا لك"
reporter: "المُبلّغ"
reporteeOrigin: "أصل البلاغ"
reporterOrigin: "أصل المُبلّغ"
forwardReport: "وجّه البلاغ إلى المثيل البعيد"
forwardReportIsAnonymous: "في المثيل البعيد سيظهر المبلّغ كحساب مجهول."
send: "أرسل"
abuseMarkAsResolved: "علّم البلاغ كمحلول"
openInNewTab: "افتح في لسان جديد"
defaultNavigationBehaviour: "سلوك الملاحة الافتراضي"
editTheseSettingsMayBreakAccount: "تعديل هذه الإعدادات قد يسبب عطبًا لحسابك"
......@@ -1009,7 +1008,12 @@ expired: "منتهية صلاحيته"
icon: "الصورة الرمزية"
replies: "رد"
renotes: "أعد النشر"
sourceCode: "الشفرة المصدرية"
flip: "اقلب"
lastNDays: "آخر {n} أيام"
surrender: "ألغِ"
_delivery:
stop: "مُعلّق"
_initialAccountSetting:
accountCreated: "نجح إنشاء حسابك!"
letsStartAccountSetup: "إذا كنت جديدًا لنعدّ حسابك الشخصي."
......@@ -1247,15 +1251,12 @@ _theme:
buttonBg: "خلفية الأزرار"
buttonHoverBg: "خلفية الأزرار (عند التمرير فوقها)"
inputBorder: "حواف حقل الإدخال"
listItemHoverBg: "خلفية عناصر القائمة (عند التمرير فوقها)"
driveFolderBg: "خلفية مجلد قرص التخزين"
messageBg: "خلفية المحادثة"
_sfx:
note: "الملاحظات"
noteMy: "ملاحظتي"
notification: "الإشعارات"
antenna: "الهوائيات"
channel: "إشعارات القنات"
_ago:
future: "المستقبَل"
justNow: "اللحظة"
......@@ -1414,6 +1415,7 @@ _profile:
_exportOrImport:
allNotes: "كل الملاحظات"
favoritedNotes: " الملاحظات المفضلة"
clips: "مِشبك"
followingList: "المتابَعون"
muteList: "المستخدمون المكتومون"
blockingList: "المستخدمون المحجوبون"
......@@ -1458,9 +1460,6 @@ _pages:
newPage: "أنشئ صفحة جديدة"
editPage: "عدّل الصفحة"
readPage: "نُشّط عرض المصدر"
created: "نجح إنشاء الصفحة"
updated: "نجح تعديل الصفحة"
deleted: "نجح حذف الصفحة"
pageSetting: "إعدادات الصفحة"
nameAlreadyExists: "رابط الصفحة موجود مسبقًا"
invalidNameTitle: "رابط الصفحة ليس صالحًا"
......@@ -1526,6 +1525,7 @@ _notification:
reaction: "التفاعل"
receiveFollowRequest: "طلبات المتابعة"
followRequestAccepted: "طلبات المتابعة المقبولة"
login: "لِج"
app: "إشعارات التطبيقات المرتبطة"
_actions:
followBack: "تابعك بالمثل"
......@@ -1557,7 +1557,30 @@ _webhookSettings:
active: "مُفعّل"
_events:
reaction: "عند التفاعل"
_abuseReport:
_notificationRecipient:
_recipientType:
mail: "البريد الإلكتروني "
_moderationLogTypes:
suspend: "علِق"
deleteDriveFile: "حُذف الملف"
deleteNote: "حُذفت الملاحظة"
createGlobalAnnouncement: "أُنشئ إعلان عام"
createUserAnnouncement: "أُنشئ إعلان مستخدم"
updateGlobalAnnouncement: "حُدث إعلان عام"
updateUserAnnouncement: "حُدث إعلان مستخدم"
resetPassword: "أعد تعيين كلمتك السرية"
createInvitation: "ولِّد دعوة"
_reversi:
total: "المجموع"
lookingForPlayer: "يبحث عن خصم..."
gameCanceled: "أُلغيت اللعبة."
opponentHasSettingsChanged: "غيَر الخصم إعدادته."
showBoardLabels: "اعرض ترقيم الصفوف والأعمدة على اللوح"
useAvatarAsStone: "حوَل الحجارة إلى صور مستخدمين"
_offlineScreen:
title: "غير متصل - يتعذر الاتصال بالخادم"
header: "يتعذر الاتصال بالخادم"
_remoteLookupErrors:
_noSuchObject:
title: "غير موجود"
......@@ -2,6 +2,7 @@
_lang_: "বাংলা"
headlineMisskey: "নোট ব্যাবহার করে সংযুক্ত নেটওয়ার্ক"
introMisskey: "স্বাগতম! মিসকি একটি ওপেন সোর্স, ডিসেন্ট্রালাইজড মাইক্রোব্লগিং পরিষেবা। \n\"নোট\" তৈরির মাধ্যমে যা ঘটছে তা সবার সাথে শেয়ার করুন 📡\n\"রিঅ্যাকশন\" গুলির মাধ্যমে যেকোনো নোট সম্পর্কে আপনার অনুভূতি ব্যাক্ত করতে পারেন 👍\nএকটি নতুন দুনিয়া ঘুরে দেখুন 🚀\n"
poweredByMisskeyDescription: "{name} হল ওপেন সোর্স প্ল্যাটফর্ম <b>Misskey</b>-এর সার্ভারগুলির একটি৷"
monthAndDay: "{day}/{month}"
search: "খুঁজুন"
notifications: "বিজ্ঞপ্তি"
......@@ -12,12 +13,14 @@ fetchingAsApObject: "ফেডিভার্স থেকে খবর আন
ok: "ঠিক"
gotIt: "বুঝেছি"
cancel: "বাতিল"
noThankYou: "না, ধন্যবাদ"
enterUsername: "ইউজারনেম লিখুন"
renotedBy: "{user} রিনোট করেছেন"
noNotes: "কোন নোট নেই"
noNotifications: "কোনো বিজ্ঞপ্তি নেই"
instance: "ইন্সট্যান্স"
settings: "সেটিংস"
notificationSettings: "বিজ্ঞপ্তির সেটিংস"
basicSettings: "সাধারণ সেটিংস"
otherSettings: "অন্যান্য সেটিংস"
openInWindow: "নতুন উইন্ডোতে খুলা"
......@@ -42,12 +45,20 @@ pin: "পিন করা"
unpin: "পিন সরান"
copyContent: "বিষয়বস্তু কপি করুন"
copyLink: "লিঙ্ক কপি করুন"
copyLinkRenote: "রিনোট লিঙ্ক কপি করুন"
delete: "মুছুন"
deleteAndEdit: "মুছুন এবং সম্পাদনা করুন"
deleteAndEditConfirm: "আপনি কি এই নোটটি মুছে এটি সম্পাদনা করার বিষয়ে নিশ্চিত? আপনি এটির সমস্ত রিঅ্যাকশন, রিনোট এবং জবাব হারাবেন।"
addToList: "লিস্ট যোগ করুন"
addToAntenna: "অ্যান্টেনা যোগ করুন"
sendMessage: "একটি বার্তা পাঠান"
copyRSS: "RSS কপি করুন"
copyUsername: "ব্যবহারকারীর নাম কপি করুন"
copyUserId: "ব্যবহারকারীর ID কপি করুন"
copyNoteId: "নোটের ID কপি করুন"
copyFileId: "ফাইল ID কপি করুন"
copyFolderId: "ফোল্ডার ID কপি করুন"
copyProfileUrl: "প্রোফাইল URL কপি করুন"
searchUser: "ব্যবহারকারী খুঁজুন..."
reply: "জবাব"
loadMore: "আরও দেখুন"
......@@ -100,6 +111,8 @@ renoted: "রিনোট করা হয়েছে"
cantRenote: "এই নোটটি রিনোট করা যাবে না।"
cantReRenote: "রিনোটকে রিনোট করা যাবে না।"
quote: "উদ্ধৃতি"
inChannelRenote: "চ্যানেলে রিনোট"
inChannelQuote: "চ্যানেলে উদ্ধৃতি"
pinnedNote: "পিন করা নোট"
pinned: "পিন করা"
you: "আপনি"
......@@ -108,6 +121,10 @@ sensitive: "সংবেদনশীল বিষয়বস্তু"
add: "যুক্ত করুন"
reaction: "প্রতিক্রিয়া"
reactions: "প্রতিক্রিয়া"
emojiPicker: "ইমোজি পিকার"
pinnedEmojisForReactionSettingDescription: "রিঅ্যাকশন দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।"
pinnedEmojisSettingDescription: "ইমোজি ইনপুট দেয়ার সময় আপনি ইমোজিটিকে পিন করা এবং প্রদর্শিত হওয়ার জন্য সেট করতে পারেন।"
emojiPickerDisplay: "পিকার ডিসপ্লে"
reactionSettingDescription2: "পুনরায় সাজাতে টেনে আনুন, মুছতে ক্লিক করুন, যোগ করতে + টিপুন।"
rememberNoteVisibility: "নোটের দৃশ্যমান্যতার সেটিংস মনে রাখুন"
attachCancel: "অ্যাটাচমেন্ট সরান "
......@@ -322,7 +339,6 @@ enableLocalTimeline: "স্থানীয় টাইমলাইন চাল
enableGlobalTimeline: "গ্লোবাল টাইমলাইন চালু করুন"
disablingTimelinesInfo: "আপনি এই টাইমলাইনগুলি বন্ধ করলেও প্রশাসক এবং মডারেটররা এই টাইমলাইনগুলি ব্যাবহার করতে পারবে"
registration: "নিবন্ধন"
enableRegistration: "নতুন ব্যাবহারকারী নিবন্ধন চালু করুন"
invite: "আমন্ত্রণ"
driveCapacityPerLocalAccount: "প্রত্যেক স্থানীয় ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
driveCapacityPerRemoteAccount: "প্রত্যেক রিমোট ব্যাবহারকারীর জন্য ড্রাইভের জায়গা"
......@@ -340,6 +356,8 @@ hcaptcha: "hCaptcha"
enableHcaptcha: "hCaptcha চালু করুন"
hcaptchaSiteKey: "সাইট কী"
hcaptchaSecretKey: "সিক্রেট কী"
mcaptchaSiteKey: "সাইট কী"
mcaptchaSecretKey: "সিক্রেট কী"
recaptcha: "reCAPTCHA"
enableRecaptcha: "reCAPTCHA চালু করুন"
recaptchaSiteKey: "সাইট কী"
......@@ -432,7 +450,6 @@ or: "অথবা"
language: "ভাষা"
uiLanguage: "UI এর ভাষা"
aboutX: "{x} সম্পর্কে"
disableDrawer: "ড্রয়ার মেনু প্রদর্শন করবেন না"
noHistory: "কোনো ইতিহাস নেই"
signinHistory: "প্রবেশ করার ইতিহাস"
doing: "প্রক্রিয়া করছে..."
......@@ -606,10 +623,7 @@ abuseReported: "আপনার অভিযোগটি দাখিল কর
reporter: "অভিযোগকারী"
reporteeOrigin: "অভিযোগটির উৎস"
reporterOrigin: "অভিযোগকারীর উৎস"
forwardReport: "রিমোট ইন্সত্যান্সে অভিযোগটি পাঠান"
forwardReportIsAnonymous: "আপনার তথ্য রিমোট ইন্সত্যান্সে পাঠানো হবে না এবং একটি বেনামী সিস্টেম অ্যাকাউন্ট হিসাবে প্রদর্শিত হবে।"
send: "পাঠান"
abuseMarkAsResolved: "অভিযোগটিকে সমাধাকৃত হিসাবে চিহ্নিত করুন"
openInNewTab: "নতুন ট্যাবে খুলুন"
openInSideView: "সাইড ভিউতে খুলুন"
defaultNavigationBehaviour: "ডিফল্ট নেভিগেশন"
......@@ -836,7 +850,12 @@ youFollowing: "অনুসরণ করা হচ্ছে"
icon: "প্রোফাইল ছবি"
replies: "জবাব"
renotes: "রিনোট"
sourceCode: "সোর্স কোড"
flip: "উল্টান"
_delivery:
stop: "স্থগিত করা হয়েছে"
_type:
none: "প্রকাশ করা হচ্ছে"
_role:
priority: "অগ্রাধিকার"
_priority:
......@@ -997,7 +1016,6 @@ _theme:
buttonBg: "বাটনের পটভূমি"
buttonHoverBg: "বাটনের পটভূমি (হভার)"
inputBorder: "ইনপুট ফিল্ডের বর্ডার"
listItemHoverBg: "লিস্ট আইটেমের পটভূমি (হোভার)"
driveFolderBg: "ড্রাইভ ফোল্ডারের পটভূমি"
wallpaperOverlay: "ওয়ালপেপার ওভারলে"
badge: "ব্যাজ"
......@@ -1009,8 +1027,6 @@ _sfx:
note: "নোটগুলি"
noteMy: "নোট (আপনার)"
notification: "বিজ্ঞপ্তি"
antenna: "অ্যান্টেনাগুলি"
channel: "চ্যানেলের বিজ্ঞপ্তি"
_ago:
future: "ভবিষ্যৎ"
justNow: "এইমাত্র"
......@@ -1034,6 +1050,7 @@ _2fa:
step3: "অ্যাপে প্রদর্শিত টোকেনটি লিখুন এবং আপনার কাজ শেষ।"
step4: "আপনাকে এখন থেকে লগ ইন করার সময়, এইভাবে টোকেন লিখতে হবে।"
securityKeyInfo: "আপনি একটি হার্ডওয়্যার সিকিউরিটি কী ব্যবহার করে লগ ইন করতে পারেন যা FIDO2 বা ডিভাইসের ফিঙ্গারপ্রিন্ট সেন্সর বা পিন সমর্থন করে৷"
renewTOTPCancel: "না, ধন্যবাদ"
_permissions:
"read:account": "অ্যাকাউন্টের তথ্য দেখুন"
"write:account": "অ্যাকাউন্টের তথ্য সম্পাদন করুন"
......@@ -1172,6 +1189,7 @@ _profile:
changeBanner: "ব্যানার পরিবর্তন করুন"
_exportOrImport:
allNotes: "সকল নোট"
clips: "ক্লিপ"
followingList: "অনুসরণ করা হচ্ছে"
muteList: "মিউট"
blockingList: "ব্লক"
......@@ -1219,9 +1237,6 @@ _pages:
newPage: "নতুন পৃষ্ঠা বানান"
editPage: "পৃষ্ঠাটি সম্পাদনা করুন"
readPage: "উৎস দেখছেন"
created: "পৃষ্ঠা তৈরি করা হয়েছে"
updated: "পৃষ্ঠা সম্পাদনা করা হয়েছে"
deleted: "পৃষ্ঠা মুছে ফেলা হয়েছে"
pageSetting: "পৃষ্ঠার সেটিংস"
nameAlreadyExists: "পৃষ্ঠার URLটি ইতিমধ্যেই ব্যাবহার করা হয়েছে"
invalidNameTitle: "পৃষ্ঠার URL অবৈধ"
......@@ -1290,6 +1305,7 @@ _notification:
pollEnded: "পোল শেষ"
receiveFollowRequest: "প্রাপ্ত অনুসরণের অনুরোধসমূহ"
followRequestAccepted: "গৃহীত অনুসরণের অনুরোধসমূহ"
login: "প্রবেশ করুন"
app: "লিঙ্ক করা অ্যাপ থেকে বিজ্ঞপ্তি"
_actions:
followBack: "ফলো ব্যাক করেছে"
......@@ -1320,6 +1336,15 @@ _deck:
_webhookSettings:
name: "নাম"
active: "চালু"
_abuseReport:
_notificationRecipient:
_recipientType:
mail: "ইমেইল"
_moderationLogTypes:
suspend: "স্থগিত করা"
resetPassword: "পাসওয়ার্ড রিসেট করুন"
_reversi:
total: "মোট"
_remoteLookupErrors:
_noSuchObject:
title: "পাওয়া যায়নি"
This diff is collapsed.
......@@ -348,7 +348,6 @@ enableLocalTimeline: "Povolit lokální čas"
enableGlobalTimeline: "Povolit globální čas"
disablingTimelinesInfo: "Administrátoři a Moderátoři budou mít stálý přístup ke všem časovým osám i přes to že nejsou zapnuté."
registration: "Registrace"
enableRegistration: "Povolit registraci novým uživatelům"
invite: "Pozvat"
driveCapacityPerLocalAccount: "Kapacita disku na lokálního uživatele"
driveCapacityPerRemoteAccount: "Kapacita disku na vzdáleného uživatele"
......@@ -366,6 +365,8 @@ hcaptcha: "hCaptcha"
enableHcaptcha: "Aktivovat hCaptchu"
hcaptchaSiteKey: "Klíč stránky"
hcaptchaSecretKey: "Tajný Klíč (Secret Key)"
mcaptchaSiteKey: "Klíč stránky"
mcaptchaSecretKey: "Tajný Klíč (Secret Key)"
recaptcha: "reCAPTCHA"
enableRecaptcha: "Zapnout ReCAPTCHu"
recaptchaSiteKey: "Klíč stránky"
......@@ -469,7 +470,6 @@ uiLanguage: "Jazyk uživatelského rozhraní"
aboutX: "O {x}"
emojiStyle: "Styl emoji"
native: "Výchozí"
disableDrawer: "Nepoužívat šuplíkové menu"
showNoteActionsOnlyHover: "Zobrazit akce poznámky jenom při naběhnutí myši"
noHistory: "Žádná historie"
signinHistory: "Historie přihlášení"
......@@ -656,10 +656,7 @@ abuseReported: "Nahlášení bylo odesláno. Děkujeme převelice."
reporter: "Nahlásil"
reporteeOrigin: "Původ nahlášení"
reporterOrigin: "Původ nahlasovače"
forwardReport: "Přeposlat nahlášení do vzdálené instance"
forwardReportIsAnonymous: "Místo vašeho účtu se ve vzdálené instanci zobrazí anonymní systémový účet jako nahlašovač."
send: "Odeslat"
abuseMarkAsResolved: "Označit nahlášení jako vyřešené"
openInNewTab: "Otevřít v nové kartě"
openInSideView: "Otevřít v bočním panelu"
defaultNavigationBehaviour: "Výchozí chování navigace"
......@@ -1003,6 +1000,7 @@ resetPasswordConfirm: "Opravdu chcete resetovat heslo?"
sensitiveWords: "Citlivá slova"
sensitiveWordsDescription: "Viditelnost všech poznámek obsahujících některé z nakonfigurovaných slov bude automaticky nastavena na \"Domů\". Můžete jich uvést více tak, že je oddělíte pomocí řádků."
sensitiveWordsDescription2: "Použití mezer vytvoří výrazy AND a obklopení klíčových slov lomítky je změní na regulární výraz."
prohibitedWordsDescription2: "Použití mezer vytvoří výrazy AND a obklopení klíčových slov lomítky je změní na regulární výraz."
notesSearchNotAvailable: "Vyhledávání poznámek je nedostupné."
license: "Licence"
unfavoriteConfirm: "Opravdu chcete odstranit z oblíbených?"
......@@ -1090,9 +1088,16 @@ doYouAgree: "Souhlasíte?"
beSureToReadThisAsItIsImportant: "Přečtěte si prosím tyto důležité informace."
iHaveReadXCarefullyAndAgree: "Přečetl jsem si text \"{x}\" a souhlasím s ním."
icon: "Avatar"
replies: "Odpovědi"
replies: "Odpovědět"
renotes: "Přeposlat"
sourceCode: "Zdrojový kód"
flip: "Otočit"
lastNDays: "Posledních {n} dnů"
surrender: "Zrušit"
_delivery:
stop: "Suspendováno"
_type:
none: "Publikuji"
_initialAccountSetting:
accountCreated: "Váš účet byl úspěšně vytvořen!"
letsStartAccountSetup: "Pro začátek si nastavte svůj profil."
......@@ -1623,7 +1628,6 @@ _theme:
buttonBg: "Pozadí tlačítka"
buttonHoverBg: "Pozadí tlačítka (Hover)"
inputBorder: "Ohraničení vstupního pole"
listItemHoverBg: "Pozadí položky seznamu (Hover)"
driveFolderBg: "Pozadí složky disku"
wallpaperOverlay: "Překrytí tapety"
badge: "Odznak"
......@@ -1635,8 +1639,6 @@ _sfx:
note: "Poznámky"
noteMy: "Moje poznámka"
notification: "Oznámení"
antenna: "Antény"
channel: "Oznámení kanálu"
_ago:
future: "Budoucí"
justNow: "Teď"
......@@ -1658,7 +1660,6 @@ _2fa:
registerTOTP: "Registrovat aplikaci autentizátoru"
step1: "Nejprve si do zařízení nainstalujte aplikaci pro ověřování (například {a} nebo {b})."
step2: "Poté naskenujte QR kód zobrazený na této obrazovce."
step2Click: "Kliknutím na tento QR kód můžete zaregistrovat 2FA do bezpečnostního klíče nebo aplikace autentizace telefonu."
step3Title: "Zadejte ověřovací kód"
step3: "Pro dokončení nastavení zadejte token poskytnutý vaší aplikací."
step4: "Od této chvíle budou všechny budoucí pokusy o přihlášení vyžadovat tento přihlašovací token."
......@@ -1712,7 +1713,7 @@ _auth:
shareAccessTitle: "Udělovat oprávnění k aplikacím"
shareAccess: "Chcete autorizovat \"{name}\" pro přístup k tomuto účtu?"
shareAccessAsk: "Opravdu chcete této aplikaci povolit přístup k vašemu účtu?"
permission: "{jméno} požaduje tato oprávnění"
permission: "{name} požaduje tato oprávnění"
permissionAsk: "Tato aplikace požaduje následující oprávnění"
pleaseGoBack: "Vraťte se prosím zpět do aplikace"
callback: "Návrat k aplikaci"
......@@ -1825,6 +1826,7 @@ _profile:
_exportOrImport:
allNotes: "Všechny poznámky"
favoritedNotes: "Oblíbené poznámky"
clips: "Oříznout"
followingList: "Sledovaní"
muteList: "Ztlumit"
blockingList: "Zablokovat"
......@@ -1881,9 +1883,6 @@ _pages:
newPage: "Vytvořit novou stránku"
editPage: "Upravit stránku"
readPage: "Prohlížení zdroje této stránky"
created: "Stránka byla úspěšně vytvořena"
updated: "Stránka byla úspěšně aktualizována"
deleted: "Stránka byla úspěšně smazána"
pageSetting: "Nastavení stránky"
nameAlreadyExists: "Zadaná adresa URL stránky již existuje"
invalidNameTitle: "Zadaná adresa URL stránky je neplatná"
......@@ -1935,7 +1934,7 @@ _notification:
youGotMention: "{name} vás zmínil"
youGotReply: "{name} vám odpověděl"
youGotQuote: "{name} vás citoval"
youRenoted: "Poznámka od {jméno}"
youRenoted: "Poznámka od {name}"
youWereFollowed: "Máte nového následovníka"
youReceivedFollowRequest: "Obdrželi jste žádost o sledování"
yourFollowRequestAccepted: "Vaše žádost o sledování byla přijata"
......@@ -1955,6 +1954,7 @@ _notification:
receiveFollowRequest: "Obdržené žádosti o sledování"
followRequestAccepted: "Přijaté žádosti o sledování"
achievementEarned: "Úspěch odemčen"
login: "Přihlásit se"
app: "Oznámení z propojených aplikací"
_actions:
followBack: "vás začal sledovat zpět"
......@@ -2002,7 +2002,6 @@ _webhookSettings:
createWebhook: "Vytvořit Webhook"
name: "Jméno"
secret: "Tajné"
events: "Události Webhook"
active: "Zapnuto"
_events:
follow: "Při sledování uživatele"
......@@ -2012,7 +2011,16 @@ _webhookSettings:
renote: "Při renotaci poznámky"
reaction: "Při obdržení reakce"
mention: "Při zmínce"
_abuseReport:
_notificationRecipient:
_recipientType:
mail: "Email"
_moderationLogTypes:
suspend: "Zmrazit"
resetPassword: "Resetovat heslo"
createInvitation: "Vygenerovat pozvánku"
_reversi:
total: "Celkem"
_remoteLookupErrors:
_noSuchObject:
title: "Nenalezeno"
---
_lang_: "Dansk"
headlineMisskey: ""
introMisskey: "ようこそ!Misskeyは、オープンソースの分散型マイクロブログサービスです。\n「ノート」を作成して、いま起こっていることを共有したり、あなたについて皆に発信しよう📡\n「リアクション」機能で、皆のノートに素早く反応を追加することもできます👍\n新しい世界を探検しよう🚀"
This diff is collapsed.