Merge branch 'develop' into swn

This commit is contained in:
tamaina 2021-11-07 23:01:06 +09:00 committed by GitHub
commit 7333fe80bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1383 changed files with 596 additions and 60691 deletions

View file

@ -10,6 +10,19 @@
--> -->
## 12.x.x (unreleased)
### Improvements
- フォロー/フォロワーを非公開にできるように
- インスタンスプロフィールレンダリング ready
- メールアドレスのバリデーションを強化
### Bugfixes
- クライアント: 長いメニューが画面からはみ出す問題を修正
- クライアント: コントロールパネルのジョブキューに個々のジョブが表示されないのを修正
- クライアント: fix missing i18n string
- fix html conversion issue with code blocks
## 12.95.0 (2021/10/31) ## 12.95.0 (2021/10/31)
### Improvements ### Improvements

View file

@ -49,10 +49,6 @@ If your language is not listed in Crowdin, please open an issue.
![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg) ![Crowdin](https://d322cqt584bo4o.cloudfront.net/misskey/localized.svg)
## Documentation
* Documents for instance admins are located in [`/docs`](/docs).
* Documents for end users are located in [`/src/docs`](/src/docs).
## Testing ## Testing
- Test codes are located in [`/test`](/test). - Test codes are located in [`/test`](/test).

View file

@ -2,6 +2,3 @@ files:
- source: /locales/ja-JP.yml - source: /locales/ja-JP.yml
translation: /locales/%locale%.yml translation: /locales/%locale%.yml
update_option: update_as_unapproved update_option: update_as_unapproved
- source: /src/docs/ja-JP/**/*.md
translation: /src/docs/%locale%/**/%original_file_name%
update_option: update_as_unapproved

View file

@ -620,6 +620,8 @@ reportAbuse: "通報"
reportAbuseOf: "{name}を通報する" reportAbuseOf: "{name}を通報する"
fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のートがある場合はそのURLも記入してください。" fillAbuseReportDescription: "通報理由の詳細を記入してください。対象のートがある場合はそのURLも記入してください。"
abuseReported: "内容が送信されました。ご報告ありがとうございました。" abuseReported: "内容が送信されました。ご報告ありがとうございました。"
reporteeOrigin: "通報先"
reporterOrigin: "通報元"
send: "送信" send: "送信"
abuseMarkAsResolved: "対応済みにする" abuseMarkAsResolved: "対応済みにする"
openInNewTab: "新しいタブで開く" openInNewTab: "新しいタブで開く"
@ -802,6 +804,20 @@ makeReactionsPublicDescription: "あなたがしたリアクション一覧を
classic: "クラシック" classic: "クラシック"
muteThread: "スレッドをミュート" muteThread: "スレッドをミュート"
unmuteThread: "スレッドのミュートを解除" unmuteThread: "スレッドのミュートを解除"
ffVisibility: "つながりの公開範囲"
ffVisibilityDescription: "自分のフォロー/フォロワー情報の公開範囲を設定できます。"
_emailUnavailable:
used: "既に使用されています"
format: "形式が正しくありません"
disposable: "恒久的に使用可能なアドレスではありません"
mx: "正しいメールサーバーではありません"
smtp: "メールサーバーが応答しません"
_ffVisibility:
public: "公開"
followers: "フォロワーだけに公開"
private: "非公開"
_signup: _signup:
almostThere: "ほとんど完了です" almostThere: "ほとんど完了です"
@ -816,14 +832,6 @@ _accountDelete:
started: "削除処理が開始されました。" started: "削除処理が開始されました。"
inProgress: "削除が進行中" inProgress: "削除が進行中"
_docs:
continueReading: "続きを読む"
features: "機能"
generalTopics: "一般的なトピック"
advancedTopics: "高度なトピック"
admin: "管理"
translateWarn: "このドキュメントは翻訳されたものです。オリジナルとは内容が異なる場合があります。"
_ad: _ad:
back: "戻る" back: "戻る"
reduceFrequencyOfThisAd: "この広告の表示頻度を下げる" reduceFrequencyOfThisAd: "この広告の表示頻度を下げる"

View file

@ -0,0 +1,16 @@
import {MigrationInterface, QueryRunner} from "typeorm";
export class ffVisibility1636197624383 implements MigrationInterface {
name = 'ffVisibility1636197624383'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TYPE "public"."user_profile_ffvisibility_enum" AS ENUM('public', 'followers', 'private')`);
await queryRunner.query(`ALTER TABLE "user_profile" ADD "ffVisibility" "public"."user_profile_ffvisibility_enum" NOT NULL DEFAULT 'public'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "ffVisibility"`);
await queryRunner.query(`DROP TYPE "public"."user_profile_ffvisibility_enum"`);
}
}

View file

@ -71,7 +71,6 @@
"@types/koa__cors": "3.0.3", "@types/koa__cors": "3.0.3",
"@types/koa__multer": "2.0.4", "@types/koa__multer": "2.0.4",
"@types/koa__router": "8.0.8", "@types/koa__router": "8.0.8",
"@types/markdown-it": "12.2.3",
"@types/matter-js": "0.17.6", "@types/matter-js": "0.17.6",
"@types/mocha": "8.2.3", "@types/mocha": "8.2.3",
"@types/node": "16.11.4", "@types/node": "16.11.4",
@ -131,6 +130,7 @@
"cssnano": "5.0.8", "cssnano": "5.0.8",
"date-fns": "2.25.0", "date-fns": "2.25.0",
"dateformat": "4.5.1", "dateformat": "4.5.1",
"deep-email-validator": "0.1.18",
"escape-regexp": "0.0.1", "escape-regexp": "0.0.1",
"eslint": "8.1.0", "eslint": "8.1.0",
"eslint-plugin-vue": "7.20.0", "eslint-plugin-vue": "7.20.0",
@ -169,8 +169,6 @@
"koa-slow": "2.1.0", "koa-slow": "2.1.0",
"koa-views": "7.0.1", "koa-views": "7.0.1",
"langmap": "0.0.16", "langmap": "0.0.16",
"markdown-it": "12.2.0",
"markdown-it-anchor": "7.1.0",
"matter-js": "0.17.1", "matter-js": "0.17.1",
"mfm-js": "0.20.0", "mfm-js": "0.20.0",
"misskey-js": "0.0.8", "misskey-js": "0.0.8",

View file

@ -122,7 +122,9 @@ export async function login(token: Account['token'], redirect?: string) {
await addAccount(me.id, token); await addAccount(me.id, token);
if (redirect) { if (redirect) {
// 他のタブは再読み込みするだけ
reloadChannel.postMessage(null); reloadChannel.postMessage(null);
// このページはredirectで指定された先に移動
location.href = redirect; location.href = redirect;
return; return;
} }

View file

@ -16,10 +16,10 @@
</template> </template>
</div> </div>
<div class="sub"> <div class="sub">
<MkA to="/docs" @click.passive="close()" v-click-anime> <a href="https://misskey-hub.net/help.html" target="_blank" @click.passive="close()" v-click-anime>
<i class="fas fa-question-circle icon"></i> <i class="fas fa-question-circle icon"></i>
<div class="text">{{ $ts.help }}</div> <div class="text">{{ $ts.help }}</div>
</MkA> </a>
<MkA to="/about" @click.passive="close()" v-click-anime> <MkA to="/about" @click.passive="close()" v-click-anime>
<i class="fas fa-info-circle icon"></i> <i class="fas fa-info-circle icon"></i>
<div class="text">{{ $t('aboutX', { x: instanceName }) }}</div> <div class="text">{{ $t('aboutX', { x: instanceName }) }}</div>

View file

@ -45,7 +45,7 @@ export default defineComponent({
); );
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention')); const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
bg.setAlpha(0.20); bg.setAlpha(0.1);
return { return {
localHost, localHost,

View file

@ -19,12 +19,17 @@
<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span> <span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span>
</template> </template>
</MkInput> </MkInput>
<MkInput v-if="meta.emailRequiredForSignup" class="_formBlock" v-model="email" type="email" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeEmail" data-cy-signup-email> <MkInput v-if="meta.emailRequiredForSignup" class="_formBlock" v-model="email" :debounce="true" type="email" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeEmail" data-cy-signup-email>
<template #label>{{ $ts.emailAddress }} <div class="_button _help" v-tooltip:dialog="$ts._signup.emailAddressInfo"><i class="far fa-question-circle"></i></div></template> <template #label>{{ $ts.emailAddress }} <div class="_button _help" v-tooltip:dialog="$ts._signup.emailAddressInfo"><i class="far fa-question-circle"></i></div></template>
<template #prefix><i class="fas fa-envelope"></i></template> <template #prefix><i class="fas fa-envelope"></i></template>
<template #caption> <template #caption>
<span v-if="emailState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse fa-fw"></i> {{ $ts.checking }}</span> <span v-if="emailState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse fa-fw"></i> {{ $ts.checking }}</span>
<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.available }}</span> <span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.available }}</span>
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts._emailUnavailable.used }}</span>
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts._emailUnavailable.format }}</span>
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts._emailUnavailable.disposable }}</span>
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts._emailUnavailable.mx }}</span>
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts._emailUnavailable.smtp }}</span>
<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.unavailable }}</span> <span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.unavailable }}</span>
<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.error }}</span> <span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.error }}</span>
</template> </template>
@ -171,7 +176,13 @@ export default defineComponent({
os.api('email-address/available', { os.api('email-address/available', {
emailAddress: this.email emailAddress: this.email
}).then(result => { }).then(result => {
this.emailState = result.available ? 'ok' : 'unavailable'; this.emailState = result.available ? 'ok' :
result.reason === 'used' ? 'unavailable:used' :
result.reason === 'format' ? 'unavailable:format' :
result.reason === 'disposable' ? 'unavailable:disposable' :
result.reason === 'mx' ? 'unavailable:mx' :
result.reason === 'smtp' ? 'unavailable:smtp' :
'unavailable';
}).catch(err => { }).catch(err => {
this.emailState = 'error'; this.emailState = 'error';
}); });

View file

@ -147,6 +147,8 @@ export default defineComponent({
.rrevdjwt { .rrevdjwt {
padding: 8px 0; padding: 8px 0;
min-width: 200px; min-width: 200px;
max-height: 90vh;
overflow: auto;
&.center { &.center {
> .item { > .item {

View file

@ -30,7 +30,7 @@ export default defineComponent({
methods: { methods: {
whatIsNew() { whatIsNew() {
this.$refs.modal.close(); this.$refs.modal.close();
this.$router.push('/docs/general/changelog'); window.open(`https://misskey-hub.net/docs/releases.html#_${version.replace(/\./g, '-')}`, '_blank');
} }
} }
}); });

View file

@ -11,7 +11,7 @@
</div> </div>
</section> </section>
<section class="_debobigegoItem" style="text-align: center; padding: 0 16px;"> <section class="_debobigegoItem" style="text-align: center; padding: 0 16px;">
{{ $ts._aboutMisskey.about }}<br><MkA class="_link" to="/docs/general/misskey">{{ $ts.learnMore }}</MkA> {{ $ts._aboutMisskey.about }}<br><a href="https://misskey-hub.net/docs/misskey.html" target="_blank" class="_link">{{ $ts.learnMore }}</a>
</section> </section>
<FormGroup> <FormGroup>
<FormLink to="https://github.com/misskey-dev/misskey" external> <FormLink to="https://github.com/misskey-dev/misskey" external>

View file

@ -10,7 +10,7 @@
<option value="resolved">{{ $ts.resolved }}</option> <option value="resolved">{{ $ts.resolved }}</option>
</MkSelect> </MkSelect>
<MkSelect v-model="targetUserOrigin" style="margin: 0; flex: 1;"> <MkSelect v-model="targetUserOrigin" style="margin: 0; flex: 1;">
<template #label>{{ $ts.targetUserOrigin }}</template> <template #label>{{ $ts.reporteeOrigin }}</template>
<option value="combined">{{ $ts.all }}</option> <option value="combined">{{ $ts.all }}</option>
<option value="local">{{ $ts.local }}</option> <option value="local">{{ $ts.local }}</option>
<option value="remote">{{ $ts.remote }}</option> <option value="remote">{{ $ts.remote }}</option>

View file

@ -55,8 +55,8 @@ export default defineComponent({
const jobs = ref([]); const jobs = ref([]);
onMounted(() => { onMounted(() => {
os.api(props.domain === 'inbox' ? 'admin/queue/inbox-delayed' : props.domain === 'deliver' ? 'admin/queue/deliver-delayed' : null, {}).then(jobs => { os.api(props.domain === 'inbox' ? 'admin/queue/inbox-delayed' : props.domain === 'deliver' ? 'admin/queue/deliver-delayed' : null, {}).then(result => {
jobs.value = jobs; jobs.value = result;
}); });
const onStats = (stats) => { const onStats = (stats) => {

View file

@ -1,240 +0,0 @@
<template>
<div class="qyqbqfal" v-size="{ max: [500] }">
<div class="main">
<div class="title">{{ title }}</div>
<div class="body" v-html="body"></div>
<div class="footer">
<MkLink :url="`https://github.com/misskey-dev/misskey/blob/master/src/docs/${lang}/${doc}.md`" class="at">{{ $ts.docSource }}</MkLink>
<p v-if="lang !== 'ja-JP'">{{ $ts.translateWarn }}</p>
</div>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import MarkdownIt from 'markdown-it';
import MarkdownItAnchor from 'markdown-it-anchor';
import { url, lang } from '@client/config';
import MkLink from '@client/components/link.vue';
import * as symbols from '@client/symbols';
const markdown = MarkdownIt({
html: true
});
markdown.use(MarkdownItAnchor, {
slugify: (s) => encodeURIComponent(String(s).trim().replace(/\s+/g, '-'))
});
export default defineComponent({
components: {
MkLink
},
props: {
doc: {
type: String,
required: true
}
},
data() {
return {
[symbols.PAGE_INFO]: computed(() => this.title ? {
title: this.title,
icon: 'fas fa-question-circle',
} : null),
title: null,
body: null,
markdown: null,
lang,
}
},
watch: {
doc: {
handler() {
this.fetchDoc();
},
immediate: true,
}
},
methods: {
fetchDoc() {
fetch(`${url}/doc-assets/${lang}/${this.doc}.md`).then(res => res.text()).then(md => {
this.parse(md);
}).catch(() => {
fetch(`${url}/doc-assets/ja-JP/${this.doc}.md`).then(res => res.text()).then(md => {
this.parse(md);
});
});
},
parse(md: string) {
//
md = md.replace(/\{_URL_\}/g, url);
// markdown
const parsed = markdown.parse(md, {});
if (parsed.length === 0) return;
const buf = [...parsed];
const headingTokens = [];
let headingStart = 0;
//
while (buf[0].type !== 'heading_open') {
buf.shift();
headingStart++;
}
buf.shift();
while (buf[0].type as string !== 'heading_close') {
const token = buf.shift();
if (token) {
headingTokens.push(token);
}
}
// body
const bodyTokens = [...parsed];
bodyTokens.splice(headingStart, headingTokens.length + 2);
//
this.title = markdown.renderer.render(headingTokens, {}, {});
this.body = markdown.renderer.render(bodyTokens, {}, {});
}
}
});
</script>
<style lang="scss" scoped>
.qyqbqfal {
padding: 32px;
background: var(--panel);
line-height: 1.5;
&.max-width_500px {
padding: 24px;
}
> .main {
max-width: 800px;
margin: 0 auto;
> .title {
font-size: 1.5em;
font-weight: bold;
padding: 0 0 0.75em 0;
margin: 0 0 1em 0;
border-bottom: solid 2px var(--divider);
}
> .body {
> *:first-child {
margin-top: 0;
}
> *:last-child {
margin-bottom: 0;
}
::v-deep(a) {
color: var(--link);
}
::v-deep(blockquote) {
display: block;
margin: 8px;
padding: 6px 0 6px 12px;
color: var(--fg);
border-left: solid 3px var(--fg);
opacity: 0.7;
p {
margin: 0;
}
}
::v-deep(h2) {
font-size: 1.25em;
padding: 0 0 0.5em 0;
margin: 1.5em 0 1em 0;
border-bottom: solid 0.5px var(--divider);
}
::v-deep(h3) {
margin: 1.25em 0 0.5em 0;
}
::v-deep(table) {
width: 100%;
max-width: 100%;
overflow: auto;
}
::v-deep(kbd.group) {
display: inline-block;
padding: 2px;
border: 1px solid var(--divider);
border-radius: 4px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
::v-deep(kbd.key) {
display: inline-block;
padding: 6px 8px;
border: solid 0.5px var(--divider);
border-radius: 4px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
::v-deep(code) {
display: inline-block;
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace;
tab-size: 2;
background: #272822;
color: #f8f8f2;
border-radius: 6px;
padding: 4px 6px;
}
::v-deep(pre) {
background: #272822;
color: #f8f8f2;
border-radius: 6px;
padding: 12px 16px;
> code {
padding: 0;
}
}
::v-deep(.info) {
font-size: 90%;
background: var(--infoBg);
color: var(--infoFg);
padding: 1em;
margin: 0.75em 0;
border-radius: 6px;
}
::v-deep(.warn) {
font-size: 90%;
background: var(--infoWarnBg);
color: var(--infoWarnFg);
padding: 1em;
margin: 0.75em 0;
border-radius: 6px;
}
}
> .footer {
padding: 1.5em 0 0 0;
margin: 1.5em 0 0 0;
border-top: solid 2px var(--divider);
}
}
}
</style>

View file

@ -1,152 +0,0 @@
<template>
<div class="vtaihdtm">
<div class="body">
<div class="search">
<MkInput v-model="query" :debounce="true" type="search" class="" :placeholder="$ts.search">
<template #prefix><i class="fas fa-search"></i></template>
</MkInput>
</div>
<div class="list">
<MkFolder>
<template #header>{{ $ts._docs.generalTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('general/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.features }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('features/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.advancedTopics }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('advanced/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
<MkFolder>
<template #header>{{ $ts._docs.admin }}</template>
<div class="docs">
<MkA v-for="doc in docs.filter(doc => doc.path.startsWith('admin/'))" :key="doc.path" :to="`/docs/${doc.path}`" class="doc">
<div class="title">{{ doc.title }}</div>
<div class="summary">{{ doc.summary }}</div>
<div class="read">{{ $ts._docs.continueReading }}</div>
</MkA>
</div>
</MkFolder>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { url, lang } from '@client/config';
import * as symbols from '@client/symbols';
import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/form/input.vue';
export default defineComponent({
components: {
MkFolder,
MkInput,
},
data() {
return {
[symbols.PAGE_INFO]: {
title: this.$ts.help,
icon: 'fas fa-question-circle'
},
docs: [],
query: null,
}
},
watch: {
query() {
fetch(`${url}/docs.json?lang=${lang}&q=${this.query}`).then(res => res.json()).then(docs => {
this.docs = docs;
});
}
},
created() {
fetch(`${url}/docs.json?lang=ja-JP`).then(res => res.json()).then(jaDocs => {
fetch(`${url}/docs.json?lang=${lang}`).then(res => res.json()).then(docs => {
this.docs = jaDocs.map(doc => {
const exist = docs.find(d => d.path === doc.path);
return exist || doc;
});
});
});
},
});
</script>
<style lang="scss" scoped>
.vtaihdtm {
background: var(--panel);
> .body {
max-width: 900px;
margin: 0 auto;
> .search {
padding: 16px;
}
> .list {
padding: 0 16px;
.docs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
grid-gap: 12px;
margin: 0 0 16px 0;
> .doc {
display: inline-block;
padding: 16px;
border: solid 1px var(--divider);
border-radius: 6px;
&:hover {
border: solid 1px var(--accent);
text-decoration: none;
}
> .title {
font-weight: bold;
}
> .summary {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.9em;
}
> .read {
color: var(--link);
font-size: 0.9em;
}
}
}
}
}
}
</style>

View file

@ -70,7 +70,7 @@
<MkRadios v-model="searchOrigin"> <MkRadios v-model="searchOrigin">
<option value="local">{{ $ts.local }}</option> <option value="local">{{ $ts.local }}</option>
<option value="remote">{{ $ts.remote }}</option> <option value="remote">{{ $ts.remote }}</option>
<option value="both">{{ $ts.both }}</option> <option value="both">{{ $ts.all }}</option>
</MkRadios> </MkRadios>
</div> </div>

View file

@ -9,6 +9,15 @@
{{ $ts.makeReactionsPublic }} {{ $ts.makeReactionsPublic }}
<template #desc>{{ $ts.makeReactionsPublicDescription }}</template> <template #desc>{{ $ts.makeReactionsPublicDescription }}</template>
</FormSwitch> </FormSwitch>
<FormGroup>
<template #label>{{ $ts.ffVisibility }}</template>
<FormSelect v-model="ffVisibility">
<option value="public">{{ $ts._ffVisibility.public }}</option>
<option value="followers">{{ $ts._ffVisibility.followers }}</option>
<option value="private">{{ $ts._ffVisibility.private }}</option>
</FormSelect>
<template #caption>{{ $ts.ffVisibilityDescription }}</template>
</FormGroup>
<FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()"> <FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
{{ $ts.hideOnlineStatus }} {{ $ts.hideOnlineStatus }}
<template #desc>{{ $ts.hideOnlineStatusDescription }}</template> <template #desc>{{ $ts.hideOnlineStatusDescription }}</template>
@ -69,6 +78,7 @@ export default defineComponent({
isExplorable: false, isExplorable: false,
hideOnlineStatus: false, hideOnlineStatus: false,
publicReactions: false, publicReactions: false,
ffVisibility: 'public',
} }
}, },
@ -86,6 +96,7 @@ export default defineComponent({
this.isExplorable = this.$i.isExplorable; this.isExplorable = this.$i.isExplorable;
this.hideOnlineStatus = this.$i.hideOnlineStatus; this.hideOnlineStatus = this.$i.hideOnlineStatus;
this.publicReactions = this.$i.publicReactions; this.publicReactions = this.$i.publicReactions;
this.ffVisibility = this.$i.ffVisibility;
}, },
mounted() { mounted() {
@ -101,6 +112,7 @@ export default defineComponent({
isExplorable: !!this.isExplorable, isExplorable: !!this.isExplorable,
hideOnlineStatus: !!this.hideOnlineStatus, hideOnlineStatus: !!this.hideOnlineStatus,
publicReactions: !!this.publicReactions, publicReactions: !!this.publicReactions,
ffVisibility: this.ffVisibility,
}); });
} }
} }

View file

@ -23,7 +23,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
// SPECIFICATION: /src/docs/ja-JP/advanced/share-page.md // SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import MkButton from '@client/components/ui/button.vue'; import MkButton from '@client/components/ui/button.vue';

View file

@ -43,7 +43,7 @@
<div>{{ $ts._tutorial.step7_1 }}</div> <div>{{ $ts._tutorial.step7_1 }}</div>
<I18n :src="$ts._tutorial.step7_2" tag="div"> <I18n :src="$ts._tutorial.step7_2" tag="div">
<template #help> <template #help>
<MkA class="_link" to="/docs">{{ $ts.help }}</MkA> <a href="https://misskey-hub.net/help.html" target="_blank" class="_link">{{ $ts.help }}</a>
</template> </template>
</I18n> </I18n>
<div>{{ $ts._tutorial.step7_3 }}</div> <div>{{ $ts._tutorial.step7_3 }}</div>

View file

@ -133,7 +133,7 @@ export default defineComponent({
text: this.$ts.help, text: this.$ts.help,
icon: 'fas fa-question-circle', icon: 'fas fa-question-circle',
action: () => { action: () => {
os.pageWindow('/docs'); window.open(`https://misskey-hub.net/help.md`, '_blank');
} }
}], ev.currentTarget || ev.target); }], ev.currentTarget || ev.target);
}, },

View file

@ -117,7 +117,7 @@ export default defineComponent({
text: this.$ts.help, text: this.$ts.help,
icon: 'fas fa-question-circle', icon: 'fas fa-question-circle',
action: () => { action: () => {
os.pageWindow('/docs'); window.open(`https://misskey-hub.net/help.md`, '_blank');
} }
}], ev.currentTarget || ev.target); }], ev.currentTarget || ev.target);
}, },

View file

@ -137,7 +137,7 @@ export default defineComponent({
text: this.$ts.help, text: this.$ts.help,
icon: 'fas fa-question-circle', icon: 'fas fa-question-circle',
action: () => { action: () => {
os.pageWindow('/docs'); window.open(`https://misskey-hub.net/help.md`, '_blank');
} }
}], ev.currentTarget || ev.target); }], ev.currentTarget || ev.target);
}, },

View file

@ -28,10 +28,8 @@ const defaultRoutes = [
{ path: '/about', component: page('about') }, { path: '/about', component: page('about') },
{ path: '/about-misskey', component: page('about-misskey') }, { path: '/about-misskey', component: page('about-misskey') },
{ path: '/featured', component: page('featured') }, { path: '/featured', component: page('featured') },
{ path: '/docs', component: page('docs') },
{ path: '/theme-editor', component: page('theme-editor') }, { path: '/theme-editor', component: page('theme-editor') },
{ path: '/advanced-theme-editor', component: page('advanced-theme-editor') }, { path: '/advanced-theme-editor', component: page('advanced-theme-editor') },
{ path: '/docs/:doc(.*)', component: page('doc'), props: route => ({ doc: route.params.doc }) },
{ path: '/explore', component: page('explore') }, { path: '/explore', component: page('explore') },
{ path: '/explore/tags/:tag', props: true, component: page('explore') }, { path: '/explore/tags/:tag', props: true, component: page('explore') },
{ path: '/federation', component: page('federation') }, { path: '/federation', component: page('federation') },

View file

@ -53,7 +53,7 @@ export default defineComponent({
methods: { methods: {
help() { help() {
this.$router.push('/docs/keyboard-shortcut'); window.open(`https://misskey-hub.net/docs/keyboard-shortcut.md`, '_blank');
}, },
} }
}); });

View file

@ -120,7 +120,7 @@ export default defineComponent({
}, },
help() { help() {
this.$router.push('/docs/keyboard-shortcut'); window.open(`https://misskey-hub.net/docs/keyboard-shortcut.md`, '_blank');
}, },
onTransition() { onTransition() {

View file

@ -134,7 +134,7 @@ export default defineComponent({
}, },
help() { help() {
this.$router.push('/docs/keyboard-shortcut'); window.open(`https://misskey-hub.net/docs/keyboard-shortcut.md`, '_blank');
}, },
onTransition() { onTransition() {

View file

@ -56,7 +56,7 @@ export default defineComponent({
}, },
help() { help() {
this.$router.push('/docs/keyboard-shortcut'); window.open(`https://misskey-hub.net/docs/keyboard-shortcut.md`, '_blank');
}, },
onTransition() { onTransition() {

View file

@ -1,8 +0,0 @@
# LTL/STL/GTLの無効化
Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。
LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。
<div class="warn">⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。</div>
なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。

View file

@ -1,5 +0,0 @@
# よくある質問
ここでは、サーバー管理者向けのよくある質問を掲載しています。
## デフォルトテーマを設定したい
現在、デフォルトテーマ設定機能は実装されていません。

View file

@ -1,7 +0,0 @@
# AiScript
AiScriptは、Misskeyで使用できるスクリプト言語です。
<div class="info"> AiScript実装はMisskeyとは別リポジトリで、<a href="https://github.com/syuilo/aiscript" target="_blank">オープンソースで公開されています。</a></div>
## 使い方
AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。

View file

@ -1,58 +0,0 @@
# Misskey API
MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
## アクセストークンの取得
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む
### 自分自身のアクセストークンを手動発行する
「設定 > API」で、自分のアクセストークンを発行できます。
[「APIの使い方」へ進む](#APIの使い方)
### アプリケーション利用者にアクセストークンの発行をリクエストする
アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。
#### Step 1
UUIDを生成する。以後これをセッションIDと呼びます。
> このセッションIDは毎回生成し、使いまわさないようにしてください。
#### Step 2
`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
* `name` ... アプリケーション名
* > 例: `MissDeck`
* `icon` ... アプリケーションのアイコン画像URL
* > 例: `https://missdeck.example.com/icon.png`
* `callback` ... 認証が終わった後にリダイレクトするURL
* > 例: `https://missdeck.example.com/callback`
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
* `permission` ... アプリケーションが要求する権限
* > 例: `write:notes,write:following,read:drive`
* 要求する権限を`,`で区切って列挙します
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
#### Step 3
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
レスポンスに含まれるプロパティ:
* `token` ... ユーザーのアクセストークン
* `user` ... ユーザーの情報
[「APIの使い方」へ進む](#APIの使い方)
## APIの使い方
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
* [APIリファレンス](/api-doc)
* [ストリーミングAPI](./stream)

View file

@ -1,74 +0,0 @@
# プラグインの作成
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## البيانات الوصفية
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
### name
プラグイン名
### author
プラグイン作者
### version
プラグインバージョン。数値を指定してください。
### description
プラグインの説明
### permissions
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
### config
プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。
#### type
設定値の種類を表す文字列。以下から選択します。 string number boolean
#### label
ユーザーに表示する設定名
#### description
設定の説明
#### default
設定のデフォルト値
## APIリファレンス
AiScript標準で組み込まれているAPIは掲載しません。
### Mk:dialog(title text type)
ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。
### Mk:confirm(title text type)
確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。
### Mk:api(endpoint params)
Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。
### Mk:save(key value)
任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。
### Mk:load(key)
Mk:saveで永続化した指定の名前の値を読み取ります。
### Plugin:register_post_form_action(title fn)
投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。
### Plugin:register_note_action(title fn)
ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。
### Plugin:register_user_action(title fn)
ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。
### Plugin:register_note_view_interruptor(fn)
UIに表示されるート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:register_note_post_interruptor(fn)
ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:open_url(url)
第一引数に渡されたURLをブラウザの新しいタブで開きます。
### Plugin:config
プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。

View file

@ -1,6 +0,0 @@
# Botの作成
[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。
- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装
Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。

View file

@ -1,160 +0,0 @@
# MisskeyリバーシBotの開発
Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。
1. `games/reversi`ストリームに以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる
* イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている
3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する
4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
* `game`: `game`の`id`
5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う
6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する
7. ゲームが開始すると、`started`イベントが流れてくる
* イベントの中身にはゲーム情報が含まれている
8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述)
9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる
* `color`として石の色が含まれている
* `pos`として位置情報が含まれている
## 位置の計算法
8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています:
```
+--+--+--+--+--+--+--+--+
| 0| 1| 2| 3| 4| 5| 6| 7|
+--+--+--+--+--+--+--+--+
| 8| 9|10|11|12|13|14|15|
+--+--+--+--+--+--+--+--+
|16|17|18|19|20|21|22|23|
...
```
### X,Y座標 から インデックス に変換する
```
pos = x + (y * mapWidth)
```
`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます:
```
mapWidth = map[0].length
```
### インデックス から X,Y座標 に変換する
```
x = pos % mapWidth
y = Math.floor(pos / mapWidth)
```
## マップ情報
マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます:
* `(スペース)` ... マス無し
* `-` ... マス
* `b` ... 初期配置される黒石
* `w` ... 初期配置される白石
例えば、4*4の次のような単純なマップがあるとします:
```text
+---+---+---+---+
| | | | |
+---+---+---+---+
| | ○ | ● | |
+---+---+---+---+
| | ● | ○ | |
+---+---+---+---+
| | | | |
+---+---+---+---+
```
この場合、マップデータはこのようになります:
```javascript
['----', '-wb-', '-bw-', '----']
```
## ユーザーにフォームを提示して対話可能Botを作成する
ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。
フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します:
```javascript
{
type: 'init-form',
body: [フォームコントロールの配列]
}
```
フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです:
```javascript
{
id: 'switch1',
type: 'switch',
label: 'Enable hoge',
value: false
}
```
`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。
### フォームの操作を受け取る
ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます:
```javascript
{
id: 'switch1',
value: true
}
```
### フォームコントロールの種類
#### スイッチ
type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。
##### プロパティ
`label` ... スイッチに表記するテキスト。
#### ラジオボタン
type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。
##### プロパティ
`items` ... ラジオボタンの選択肢。例:
```javascript
items: [{
label: '弱',
value: 1
}, {
label: '中',
value: 2
}, {
label: '強',
value: 3
}]
```
#### スライダー
type: `slider` スライダーを表示します。
##### プロパティ
`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。
#### テキストボックス
type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。
## ユーザーにメッセージを表示する
設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します:
```javascript
{
type: 'message',
body: {
text: 'メッセージ内容',
type: 'メッセージの種類'
}
}
```
メッセージの種類: `success`, `info`, `warning`, `error`
## 投了する
投了をするには、<a href="./api/endpoints/games/reversi/games/surrender">このエンドポイント</a>にリクエストします。

View file

@ -1,54 +0,0 @@
# シェアページ
`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。
## クエリ文字列一覧
### 文字
<dl>
<dt>title</dt>
<dd>タイトルです。本文の先頭に[ … ]と挿入されます。</dd>
<dt>text</dt>
<dd>本文です。</dd>
<dt>url</dt>
<dd>URLです。末尾に挿入されます。</dd>
</dl>
### リプライ情報
以下のいずれか
<dl>
<dt>replyId</dt>
<dd>リプライ先のートid</dd>
<dt>replyUri</dt>
<dd>リプライ先のUrlリモートのートオブジェクトを指定</dd>
</dl>
### Renote情報
以下のいずれか
<dl>
<dt>renoteId</dt>
<dd>Renote先のートid</dd>
<dt>renoteUri</dt>
<dd>Renote先のUrlリモートのートオブジェクトを指定</dd>
</dl>
### الظهور
※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する
<dl>
<dt>visibility</dt>
<dd>公開範囲 ['public' | 'home' | 'followers' | 'specified']</dd>
<dt>localOnly</dt>
<dd>0(false) or 1(true)</dd>
<dt>visibleUserIds</dt>
<dd>specified時のダイレクト先のユーザーid カンマ区切りで</dd>
<dt>visibleAccts</dt>
<dd>specified時のダイレクト先のacct?username[host] カンマ区切りで</dd>
</dl>
### الملفات
<dl>
<dt>fileIds</dt>
<dd>添付したいファイルのidカンマ区切りで</dd>
</dl>

View file

@ -1,350 +0,0 @@
# ストリーミングAPI
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。
## ストリームに接続する
ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。
以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例:
```
%WS_URL%/streaming?i=xxxxxxxxxxxxxxx
```
認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。
<div class="info"> 認証情報の取得については、<a href="./api">こちらのドキュメント</a>をご確認ください。</div>
---
認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例:
```
%WS_URL%/streaming
```
---
ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。
**ストリームでのやり取りはすべてJSONです。**
## القنوات
MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。
ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。
### チャンネルに接続する
チャンネルに接続するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'connect',
body: {
channel: 'xxxxxxxx',
id: 'foobar',
params: {
...
}
}
}
```
ここで、
* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。
* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。
* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。
<div class="info"> IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。</div>
### チャンネルからのメッセージを受け取る
例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。
チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。
* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。
* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。
### チャンネルに向けてメッセージを送信する
チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。
チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。
* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。
* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。
### チャンネルから切断する
チャンネルから切断するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'disconnect',
body: {
id: 'foobar'
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。
## ストリームを経由してAPIリクエストする
ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。
ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'api',
body: {
id: 'xxxxxxxxxxxxxxxx',
endpoint: 'notes/create',
data: {
text: 'yee haw!'
}
}
}
```
ここで、
* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。
* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。
* `data`には、エンドポイントのパラメータを含めます。
<div class="info"> APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。</div>
### レスポンスの受信
APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。
```json
{
type: 'api:xxxxxxxxxxxxxxxx',
body: {
...
}
}
```
ここで、
* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。
* `body`には、レスポンスが含まれています。
## 投稿のキャプチャ
Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。
例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。
しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。
この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。
### 投稿をキャプチャする
投稿をキャプチャするには、ストリームに次のようなメッセージを送信します:
```json
{
type: 'subNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャしたい投稿の`id`を設定します。
このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。
例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
ここで、
* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。
* `body`内の`type`に、イベントの種類が設定されます。
* `body`内の`body`に、イベントの詳細が設定されます。
#### イベントの種類
##### `reacted`
その投稿にリアクションがされた時に発生します。
* `reaction`に、リアクションの種類が設定されます。
* `userId`に、リアクションを行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
##### `deleted`
その投稿が削除された時に発生します。
* `deletedAt`に、削除日時が設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'deleted',
body: {
deletedAt: '2018-10-22T02:17:09.703Z'
}
}
}
```
##### `pollVoted`
その投稿に添付されたアンケートに投票された時に発生します。
* `choice`に、選択肢IDが設定されます。
* `userId`に、投票を行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'pollVoted',
body: {
choice: 2,
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
### 投稿のキャプチャを解除する
その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。
次のメッセージを送信します:
```json
{
type: 'unsubNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャを解除したい投稿の`id`を設定します。
このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。
# チャンネル一覧
## `main`
アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `renote`
自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。
#### `mention`
誰かからメンションされたときに発生するイベントです。
#### `readAllNotifications`
自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。
#### `meUpdated`
自分の情報が更新されたことを表すイベントです。
#### `follow`
自分が誰かをフォローしたときに発生するイベントです。
#### `unfollow`
自分が誰かのフォローを解除したときに発生するイベントです。
#### `followed`
自分が誰かにフォローされたときに発生するイベントです。
## `homeTimeline`
ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
タイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `localTimeline`
ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `hybridTimeline`
ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `globalTimeline`
グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。

View file

@ -1,4 +0,0 @@
# AiScript
## وظائف
デフォルトで値渡しです。

View file

@ -1,58 +0,0 @@
# Misskey API
MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
## アクセストークンの取得
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む
### 自分自身のアクセストークンを手動発行する
「設定 > API」で、自分のアクセストークンを発行できます。
[「APIの使い方」へ進む](#APIの使い方)
### アプリケーション利用者にアクセストークンの発行をリクエストする
アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。
#### Step 1
UUIDを生成する。以後これをセッションIDと呼びます。
> このセッションIDは毎回生成し、使いまわさないようにしてください。
#### Step 2
`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
* `name` ... アプリケーション名
* > 例: `MissDeck`
* `icon` ... アプリケーションのアイコン画像URL
* > 例: `https://missdeck.example.com/icon.png`
* `callback` ... 認証が終わった後にリダイレクトするURL
* > 例: `https://missdeck.example.com/callback`
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
* `permission` ... アプリケーションが要求する権限
* > 例: `write:notes,write:following,read:drive`
* 要求する権限を`,`で区切って列挙します
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
#### Step 3
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
レスポンスに含まれるプロパティ:
* `token` ... ユーザーのアクセストークン
* `user` ... ユーザーの情報
[「APIの使い方」へ進む](#APIの使い方)
## APIの使い方
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
* [APIリファレンス](/api-doc)
* [ストリーミングAPI](./stream)

View file

@ -1,74 +0,0 @@
# プラグインの作成
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## البيانات الوصفية
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
### name
プラグイン名
### author
プラグイン作者
### version
プラグインバージョン。数値を指定してください。
### description
プラグインの説明
### permissions
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
### config
プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。
#### type
設定値の種類を表す文字列。以下から選択します。 string number boolean
#### label
ユーザーに表示する設定名
#### description
設定の説明
#### default
設定のデフォルト値
## APIリファレンス
AiScript標準で組み込まれているAPIは掲載しません。
### Mk:dialog(title text type)
ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。
### Mk:confirm(title text type)
確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。
### Mk:api(endpoint params)
Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。
### Mk:save(key value)
任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。
### Mk:load(key)
Mk:saveで永続化した指定の名前の値を読み取ります。
### Plugin:register_post_form_action(title fn)
投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。
### Plugin:register_note_action(title fn)
ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。
### Plugin:register_user_action(title fn)
ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。
### Plugin:register_note_view_interruptor(fn)
UIに表示されるート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:register_note_post_interruptor(fn)
ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:open_url(url)
第一引数に渡されたURLをブラウザの新しいタブで開きます。
### Plugin:config
プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。

View file

@ -1,2 +0,0 @@
# إيموجي مخصص
カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。

View file

@ -1,18 +0,0 @@
# デッキ
デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。
## カラムの追加
デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。
## カラムの移動
カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。
## カラムの水平分割
カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。
## カラムの設定
カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。
## デッキの設定
デッキに関する設定は、[settings/deck](/settings/deck)で行えます。

View file

@ -1,4 +0,0 @@
# الهوائيات
アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。
条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。

View file

@ -1,2 +0,0 @@
# إيموجي مخصص
カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。

View file

@ -1,18 +0,0 @@
# デッキ
デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。
## カラムの追加
デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。
## カラムの移動
カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。
## カラムの水平分割
カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。
## カラムの設定
カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。
## デッキの設定
デッキに関する設定は、[settings/deck](/settings/deck)で行えます。

View file

@ -1,17 +0,0 @@
# قرص التخرين
ドライブは、Misskey上でファイルを管理できる機能です。
[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。
<div class="warn">⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。</div>
ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。
ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。
## 閲覧注意 (NSFW)
<div class="info"> この項目が閲覧注意なわけではありません</div>
閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。
このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。

View file

@ -1,4 +0,0 @@
# إضافة إلى المفضلة
[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。
ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。

View file

@ -1,2 +0,0 @@
# المتابَعون
ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。

View file

@ -1,66 +0,0 @@
# キーボードショートカット
## الشامل
これらのショートカットは基本的にどこでも使えます。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>新規投稿</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>通知を表示/隠す</td><td><b>N</b>otifications</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>البحث</td><td><b>S</b>earch</td></tr>
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr>
</tbody>
</table>
## 投稿にフォーカスされた状態
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd>, <kbd class="key">Tab</kbd></td><td>下の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">R</kbd></td><td>返信フォームを開く</td><td><b>R</b>eply</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>Renoteフォームを開く</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>即刻Renoteする(フォームを開かずに)</td><td>-</td></tr>
<tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr>
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>お気に入りに登録</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
<tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>投稿を削除</td><td><b>D</b>elete</tr>
<tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>投稿に対するメニューを開く</td><td><b>M</b>ore, <b>O</b>ther</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォーカスを外す</td><td>-</td></tr>
</tbody>
</table>
## Renoteフォーム
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">Enter</kbd></td><td>Renoteする</td><td>-</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>フォームを展開する</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォームを閉じる</td><td>-</td></tr>
</tbody>
</table>
## リアクションフォーム
デフォルトで「👍」にフォーカスが当たっている状態です。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd></td><td>下のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">H</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>左のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">L</kbd>, <kbd class="key">Tab</kbd></td><td>右のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">Enter</kbd>, <kbd class="key">Space</kbd>, <kbd class="key">+</kbd></td><td>リアクション確定</td><td>-</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションで確定</td><td>-</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>リアクションするのをやめる</td><td>-</td></tr>
</tbody>
</table>

View file

@ -1,12 +0,0 @@
# MFM
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。
## MFMが使用可能な場所の例
- ノート本文
- CW注釈
- ユーザーの名前
- ユーザーの自己紹介
## 開発者向け情報
MFMのパーサー実装はライブラリとして公開されており、簡単にクライアントにMFMを組み込むことが可能です。
- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptパーサー実装

View file

@ -1,41 +0,0 @@
# تم كتمها / تم حجبها
好みではないユーザーがいる場合は、ミュートを行うことでそのユーザーが自分から見えないようにすることができます。 また、より強力な措置として、ブロックを行うことでそのユーザーから自分のコンテンツが見えないようになるほか、自分に対して関わることができないようにすることができます。 ミュートされていることは相手は分かりませんが、ブロックされていることは相手に分かります。どちらを選ぶかはご自身の判断で行ってください。
<div class="info"> ミュートとブロックは併用できます。</div>
<div class="warn">⚠️ 利用規約に違反するような、迷惑なユーザーがいる場合は運営者に報告することも検討してください。</div>
設定>ミュートとブロック から、自分がミュートまたはブロックしているユーザー一覧を確認することができます。
## اكتم
ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります:
- タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote)
- そのユーザーからの通知
- メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴
- など
ユーザーをミュートするには、対象のユーザーのユーザーページのメニューを開き、「ミュート」ボタンを押します。
<div class="info"> ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。</div>
## احجب
ユーザーをブロックすると、そのユーザーからあなたのコンテンツが見えないようになり、またあなたに対して以下のようなアクションをすることができなくなります。
- フォローする
- ユーザーリストに追加する
- 返信する、Renoteする
- リアクションする、アンケートに投票する
- メッセージを送信する
- など
また、
- ブロックする際に既にそのユーザーからフォローされていた場合はフォローが解除されます。
- ブロックする際に既にそのユーザーがあなたをユーザーリストに入れていた場合はそのリストからあなたが削除されます。
ユーザーをブロックするには、対象のユーザーのユーザーページのメニューを開き、「ブロック」ボタンを押します。
<div class="warn">⚠️ ブロックを行ったこと自体は相手に通知されませんが、フォローを行ったりなどの上記のアクションが行えなくなるので間接的にブロックされていることは分かります。</div>
<div class="warn">⚠️ 相手から自分のコンテンツが見えなくなりますが、相手がアカウントを切り替えたりログアウト状態になれば見ることができます。あくまで簡易的、補助的なものとしてお考えください。</div>

View file

@ -1,13 +0,0 @@
# اكتم
ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります:
* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote)
* そのユーザーからの通知
* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴
ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。
ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。

View file

@ -1,54 +0,0 @@
# الملاحظات
ートは、Misskeyに投稿される、文章、ファイル、アンケートなどを含むコンテンツで、Misskeyの中心的概念です。また、そのートを作成する行為自体もートと呼ばれます。
ノートが作成されると、[タイムライン](./timeline)に追加され、自分の[フォロワー](./follow)やサーバーのユーザーが見れるようになります。
ノートには、[リアクション](./reaction)を行うことができます。また、返信や引用もできます。
ノートを[お気に入り](./favorite)登録することで、後で簡単に見返すことができます。
## ノートを作成する
ノートを作成するには、画面上にある鉛筆マークのボタンを押して、作成フォームを開きます。作成フォームに内容を入力し、「ノート」ボタンを押すことでノートが作成されます。 ノートには、画像、動画など任意のファイルや、[アンケート](./poll)を添付することができます。また、本文中には[MFM](./mfm)が使用でき、[メンション](./mention)や[ハッシュタグ](./hashtag)を含めることもできます。 他にも、CWや公開範囲といった設定も行えます(詳細は後述)。
<div class="info"> コンピューターのクリップボードに画像データがある状態で、フォーム内のテキストボックスにペーストするとその画像を添付することができます。</div>
<div class="info"> テキストボックス内で<kbd class="key">Ctrl + Enter</kbd>を押すことでも投稿できます。</div>
## أعد النشر
既にあるートを引用、もしくはそのートを新しいートとして共有する行為、またそれによって作成されたートをRenoteと呼びます。 自分がフォローしているユーザーの、気に入ったノートを自分のフォロワーに共有したい場合や、過去の自分のノートを再度共有したい場合に使います。 同じートに対して無制限にRenoteを行うことができますが、あまり連続して使用すると迷惑になる場合もあるので、注意しましょう。
<div class="warn">⚠️ 公開範囲がフォロワーやダイレクトのートはRenoteできません</div>
Renoteを削除するには、Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。
## CW
Contents Warningの略で、ートの内容を、閲覧者の操作なしには表示しないようにできる機能です。主に長大な内容を隠すためや、ネタバレ防止などに使うことができます。 設定するには、フォームの「内容を隠す」ボタン(目のアイコン)を押します。すると新しい入力エリアが表れるので、そこに内容の要約を記入します。
## الظهور
ノートごとに、そのノートが公開される範囲を設定することができます。フォームの「ノート」ボタンの左にあるアイコンを押すと公開範囲を以下から選択できます。
### للعامة
全ての人に対してノートが公開されるほか、サーバーの全てのタイムライン(ホームタイムライン、ローカルタイムライン、ソーシャルタイムライン、グローバルタイムライン)にノートが流れます。
<div class="warn">⚠️ アカウントが<a href="./silence">サイレンス</a>状態の時は、この公開範囲は使用できません。</div>
### الرئيسي
全ての人に対してノートが公開されますが、フォロワー以外のローカルタイムライン、ソーシャルタイムライン、グローバルタイムラインにはノートは流れません。
### المتابِعين
自分のフォロワーに対してのみノートを公開します。フォロワーの全てのタイムラインに流れます。
### مباشرة
指定したユーザーに対してのみノートを公開します。指定したユーザーの全てのタイムラインに流れます。
### 「ローカルのみ」オプション
このオプションを有効にすると、リモートにノートを連合しなくなります。
### 公開範囲の比較
<table>
<tr><th></th><th>للعامة</th><th>الرئيسي</th><th>المتابِعين</th><th>مباشرة</th></tr>
<tr><th>フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr>
<tr><th>非フォロワーのLTL/STL/GTL</th><td></td><td></td><td></td><td></td></tr>
</table>
## دبّسها على الصفحة الشخصية
ノートをピン留めすると、ユーザーページに常にそのノートを表示しておくことができます。 ノートのメニューを開き、「ピン留め」を選択してピン留めできます。 複数のノートをピン留めできます。
## راقب
ノートをウォッチすると、自分以外のノートへのリアクションや返信などの通知を受け取ることができます。 ノートのメニューを開き、「ウォッチ」を選択してウォッチできます。

View file

@ -1,10 +0,0 @@
# Pages
## 変数
変数を使うことで動的なページを作成できます。テキスト内で <b>{ 変数名 }</b> と書くとそこに変数の値を埋め込めます。例えば <b>Hello { thing } world!</b> というテキストで、変数(thing)の値が <b>ai</b> だった場合、テキストは <b>Hello ai world!</b> になります。
変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から <b>A、B、C</b> と3つの変数を定義したとき、<b>C</b>の中で<b>A</b><b>B</b>を参照することはできますが、<b>A</b>の中で<b>B</b><b>C</b>を参照することはできません。
ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。
関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。

View file

@ -1,11 +0,0 @@
# تفاعل
他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。
## リアクションピッカーのカスタマイズ
ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。
## リモート投稿へのリアクションについて
リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。
## リモートからのリアクションについて
リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。

View file

@ -1,6 +0,0 @@
# اكتم
サイレンスは、アカウントに設定される状態のひとつです。
アカウントがサイレンス状態になると、ノートの公開範囲をパブリックにできなくなります。 ホーム、フォロワー、ダイレクトは選択可能なため、サイレンスを受けた場合でもフォロワーやあなたのユーザーページを直接訪れた場合は投稿を閲覧できますが、GTL(連合タイムライン)やLTL(ローカルタイムライン)には投稿が流れません。
アカウントのサイレンス状態は、サーバーのモデレーターによって有効化/無効化されます。

View file

@ -1,68 +0,0 @@
# المظهر
テーマを設定して、Misskeyクライアントの見た目を変更できます。
## テーマの設定
設定 > テーマ
## テーマを作成する
テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。
``` js
{
id: '17587283-dd92-4a2c-a22c-be0637c9e22a',
name: 'Danboard',
author: 'syuilo',
base: 'light',
props: {
accent: 'rgb(218, 141, 49)',
bg: 'rgb(218, 212, 190)',
fg: 'rgb(115, 108, 92)',
panel: 'rgb(236, 232, 220)',
renote: 'rgb(100, 152, 106)',
link: 'rgb(100, 152, 106)',
mention: '@accent',
hashtag: 'rgb(100, 152, 106)',
header: 'rgba(239, 227, 213, 0.75)',
navBg: 'rgb(216, 206, 182)',
inputBorder: 'rgba(0, 0, 0, 0.1)',
},
}
```
* `id` ... テーマの一意なID。UUIDをおすすめします。
* `name` ... テーマ名
* `author` ... テーマの作者
* `desc` ... テーマの説明(オプション)
* `base` ... 明るいテーマか、暗いテーマか
* `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。
* テーマはここで設定されたベーステーマを継承します。
* `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文
* 16進数で表された色
* 例: `#00ff00`
* `rgb(r, g, b)`形式で表された色
* 例: `rgb(0, 255, 0)`
* `rgb(r, g, b, a)`形式で表された透明度を含む色
* 例: `rgba(0, 255, 0, 0.5)`
* 他のキーの値の参照
* `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。
* 例: `@panel`
* 定数(後述)の参照
* `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。
* 例: `$main`
* 関数(後述)
* `:{関数名}<{引数}<{色}`
#### 定数
「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。
#### 関数
wip

View file

@ -1,31 +0,0 @@
# الخيط الزمني
タイムラインは、[ノート](./note)が時系列で表示される機能です。 タイムラインには以下で示す種類があり、種類によって表示されるノートも異なります。 なお、タイムラインの種類によってはサーバーにより無効になっている場合があります。
## الرئيسي
自分のフォローしているユーザーの投稿が流れます。HTLと略されます。
## المحلي
全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。LTLと略されます。
## الاجتماعي
自分のフォローしているユーザーの投稿と、全てのローカルユーザーの「ホーム」指定されていない投稿が流れます。STLと略されます。
## الشامل
全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿が流れます。GTLと略されます。
## مقارنة
| ソース | | | الخيط الزمني | | |
| ------------ | ---------- | ------- | ------------ | --------- | ------ |
| المستخدمون | الظهور | الرئيسي | المحلي | الاجتماعي | الشامل |
| ローカル (フォロー) | 公開 | ✔ | ✔ | ✔ | ✔ |
| | الرئيسي | ✔ | | ✔ | |
| | المتابِعين | ✔ | ✔ | ✔ | ✔ |
| リモート (フォロー) | 公開 | ✔ | | ✔ | ✔ |
| | الرئيسي | ✔ | | ✔ | |
| | المتابِعين | ✔ | | ✔ | ✔ |
| ローカル (未フォロー) | 公開 | | ✔ | ✔ | ✔ |
| | الرئيسي | | | | |
| | المتابِعين | | | | |
| リモート (未フォロー) | 公開 | | | | ✔ |
| | الرئيسي | | | | |
| | المتابِعين | | | | |

View file

@ -1,7 +0,0 @@
# ウィジェット
ウィジェットは、MisskeyのUI上に設置できる小型の情報表示、操作が行えるパーツです。
ウィジェットを編集するには、ウィジェット編集モードに切り替えます。切り替え方法はUIによって異なります。 ウィジェット編集モードでは、ウィジェットの追加、削除、並び替え、およびそれぞれのウィジェットの設定を行えます。
## 利用可能なウィジェット一覧
todo

View file

@ -1,20 +0,0 @@
# ワードミュート
ワードミュートの設定をすると、条件に合致したノートが表示されなくなります。
ワードミュートには、ソフトワードミュートとハードワードミュートの2種類があります。それぞれについて設定の方法と挙動を説明します。
## ソフトワードミュート
ソフトワードミュートは、クライアント(アプリ)側でミュートを判断するワードミュートです。
ノートが設定した条件に合致すると、「(ユーザー名)が何かを言いました」という表示で隠れます。
クリックすると元の通りに表示されます。
## ハードワードミュート
ハードワードミュートは、アンテナのようにサーバーが新しいノートの本文に対して条件に合致するかどうか判断し、タイムラインから対象となったノートを除外します。
つまり、ハードワードミュートには、以下のような特徴があります。
* 条件設定後、新しい投稿のみがミュートの対象になります。
* 条件を変更しても、過去にハードミュートされたノートはミュートされたままになります。
* 「○○が何かを言いました」でタイムラインが埋まることがありません。
* ソフトミュートに非対応のアプリでも、ハードミュートは適用されます。

View file

@ -1,2 +0,0 @@
# المتابَعون
ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。

View file

@ -1,6 +0,0 @@
# サードパーティアプリのリスト
## العملاء
todo
## الخدمات المترابطة
todo

View file

@ -1,5 +0,0 @@
# 更新履歴
<div class="info"> このサーバーの更新履歴です。Misskeyの最新のリリースについては、<a href="https://github.com/misskey-dev/misskey/blob/master/CHANGELOG.md" target="_blank">GitHub</a>をご確認ください。</div>
<!-- For translators: Do not edit these comments. -->
<!--[CHANGELOG]-->

View file

@ -1,28 +0,0 @@
# よくある質問
ここでは利用上のよくある質問について掲載しています。 Misskeyのプロジェクト自体についてのよくある質問は[こちら](./misskey)に掲載されています。
## iOS/Androidのアプリはありますか
公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。
ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。
## Mastodonクライアントでログインできないのですが
MisskeyはMastodonのAPIと互換性がないため、一部を除きMastodonクライアントでMisskeyを利用することはできません。
## 他のサーバーのユーザーをフォローするときは?
メニューから検索を選び、ユーザー名をホスト込みで入力します。例: `@syuilo@misskey.io`
## Renoteを削除するには
Renoteの時刻表示の隣にある「...」を押し、「Renote解除」を選択します。 Renoteについては[こちら](../features/note)をご確認ください。
## URLのプレビューを表示させたくない
MFMには、そのURLのプレビューを無効にする構文があります。詳細は[MFMチートシート](/mfm-cheat-sheet)をご確認ください。
## カスタム絵文字を追加したい
運営者のみがカスタム絵文字を追加、編集、削除できます。それらを希望する場合は運営者に依頼してください。
## Botを開発したい
Misskey APIを利用してBotの開発が可能です。[こちら](../advanced/develop-bot)をご確認ください。
## ノートの翻訳機能はどのサービスを使用していますか?
[DeepL](https://www.deepl.com/)を使用しています。

View file

@ -1,89 +0,0 @@
# 用語集
Misskeyに関する用語集です。
## ActivityPub
(読み: あくてぃびてぃぱぶ) 分散型を実現するために用いられるプロトコル(仕様)。このプロトコルに則ってサーバー同士通信を行うことで、連合が行われ、Fediverseを形成しています。
## AiScript
(読み: あいすくりぷと) Misskey上で使用できるプログラミング言語です。詳細は[こちら。](../advanced/aiscript)
## API
(読み: えーぴーあい) Misskeyのサーバーが公開している、プログラムからMisskeyを扱うためのインターフェース。詳細は[こちら。](../advanced/api)
## Bot
(読み: ぼっと) プログラムによって動作しているアカウント。
## CW
(読み: こんてんつわーにんぐ) Contents Warningの略。ートの内容を、操作なしには表示しないようにできる機能。主に長大な内容を隠すためや、ネタバレ防止などに使われます。
## Fediverse
(読み: ふぇでぃばーす) Misskeyを含む様々な分散型ソフトウェアのサーバーで構成されたネットワーク。
## GTL
グローバルタイムライン(Global TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
## HTL
ホームタイムライン(Home TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
## LTL
ローカルタイムライン(Local TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
## MFM
(読み: えむえふえむ) Misskey Flavored Markdownの略で、Misskey上で使用できるマークアップ言語です。詳細は[こちら。](../features/mfm)
## NSFW
(読み: のっとせーふふぉーわーく) Not Safe For Workの略。画像を「閲覧注意」扱いにし、操作なしには表示しないようにすることができる機能。
## أعد النشر
(読み: りのーと) 既にあるノートを引用、もしくはそのノートを新しいノートとして共有する行為、またそれによって作成されたノート。詳細は[こちら。](../features/note)
## STL
ソーシャルタイムライン(Social TimeLine)の略。タイムラインの詳細は[こちら。](../features/timeline)
## 藍
(読み: あい) Misskeyの看板娘(公式キャラクター)です。
## アクティブユーザー
インスタンスにアカウントを作っているユーザーのうち、現在も実際にサービスを利用しているユーザーのこと。
## مثيل الخادم
todo
## إيموجي مخصص
サーバーで用意された絵文字。カスタム絵文字ではない通常の絵文字は「Unicode絵文字」と区別して呼ばれる。
## コントロールパネル
インスタンスの設定画面のこと。
## サーバー
todo
## اكتم
ノートをパブリックな公開範囲で投稿できなくされている状態。モデレーターの判断でユーザーごとに設定されます。詳細は[こちら。](../features/silence)
## قائمة الانتظار
アクティビティ配送などを順番に行うためのシステム。
## علِق
アカウントが使用不可に設定されている状態。
## قرص التخرين
Misskeyにアップロードしたファイルを管理する機能。詳細は[こちら。](../features/drive)
## الملاحظات
Misskeyに投稿される、文章、ファイル、アンケートなどを含めることができるコンテンツ。詳細は[こちら。](../features/note)
## ミスキスト
Misskeyを使う人のこと。
## مشرِف
スパムの凍結およびサイレンスや不適切な投稿の削除など、コミュニティ運営に関する権限を持つユーザー。
## بُعدي
他サーバーのことを指します。リモートユーザーといったように接頭辞としても使われます。ローカルの逆です。
## الفديرالية
サーバー上で作成された情報が他のサーバーに伝わること。
## المحلي
自サーバーのことを指します。ローカルユーザー、ローカルタイムラインといったように接頭辞としても使われます。リモートの逆です。

View file

@ -1,12 +0,0 @@
# リンク集
## Webサイト
- [Official Discord](https://discord.gg/Wp8gVStHW3) - Misskey公式Discordサーバー
- [Misskey Forum](https://forum.misskey.io/) - Misskeyに関する話題を扱うフォーラム
## الحسابات
- [@repo@misskey.io](https://misskey.io/@repo) - Misskeyのリポジトリの更新を投稿するbot
## ライブラリ
- [misskey-dev/misskey.js](https://github.com/misskey-dev/misskey.js) - JavaScriptのMisskey SDK
- [misskey-dev/mfm.js](https://github.com/misskey-dev/mfm.js) - JavaScriptのMFMパーサー実装

View file

@ -1,87 +0,0 @@
# عن Misskey
Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。 開発は日本でsyuiloによって2014年から開始されました。 ドライブ、リアクションなどの豊富な機能や、高いカスタマイズ性を備えたUIを持つことが特徴です。
## 歴史
開発当初は掲示板がメインのサービスでしたが、ユーザーが短文を投稿し、それを時系列で流れるタイムライン機能を追加したところ人気が高まり、徐々にそれがメインとして開発が進むようになりました。 当初は分散型ではありませんでしたが、2018年にActivityPubを実装し分散型になったことで、より多くの方に認知され利用されるサービスになり、現在に至ります。
<div class="info"> Misskeyという名前は、syuiloが当時聴いていたMay'nというアーティストの楽曲、Brain Diverの歌詞に由来します。</div>
誰でも開発に参加することができ、現在でも活発に開発が続いています。
## 分散型とは何か?
<b>分散(distributed)型</b>とは、<b>非中央集権(decentralized)</b>とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に<b>通信(連合、federation)</b>することでコンテンツ共有<b>ネットワーク(Fediverse)</b>を形成していることが特徴のサービスです。 単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。 分散型のメリットは、自分に合った運営者やテーマのサーバーを選択できることです。自分でサーバーを作成することもできます。連合するおかげで、どのサーバーを選んでも、同じコミュニティにアクセスできます。
## 常にオープンソース
Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、簡単に言うと<b>ソフトウェアのソースコード(プログラム)が公開されている</b>ことです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。 Misskeyのすべてのソースコードは[AGPL](https://github.com/misskey-dev/misskey/blob/develop/LICENSE)というオープンソースライセンスの下に[公開](https://github.com/misskey-dev)されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。 オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。 上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。 再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。
<div class="info"> 技術的に言うと、MisskeyのソースコードはGitで管理されていて、リポジトリは<a href="https://github.com/misskey-dev" target="_blank">GitHub上でホスティングされています。</a></div>
## 開発に参加する、プロジェクトを支援する
Misskeyを気に入っていただけたら、ぜひプロジェクトを支援してください。プロジェクトに貢献するには、以下で紹介するようにいろいろな方法があります。方法によっては開発のスキルは不要なので、誰でも気軽に参加し貢献することができます。いつでもお待ちしています。
### 機能を追加したり、バグを修正する
ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。 貢献についてのガイドは[こちら](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)です。
### 議論に参加する
新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。 そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。
### テキストを翻訳する
Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。 その翻訳作業に加わっていただくことでもMisskeyに貢献できます。 Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey)
### 感想を投稿する
不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。
### ミスキストを増やす
ミスキストとは、Misskeyを使用する人のことです。 知り合いに紹介するなどしてMisskeyを広めていただければ、ミスキストが増え開発のモチベーションが上がります。
### 寄付をする
Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり直接開発者への収入にはなりません) 寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。 寄付は基本的には[Patreon](https://www.patreon.com/syuilo)で受け付けています。 一定額寄付していただけると、Misskeyの[情報ページ](/about-misskey)に名前を記載することができます。
また、サーバーの運営者も、基本的には収益を得ていません。サーバーの運営にはコストがかかるので、運営者の支援をすることもご検討ください。 開発には直接関係しませんが、サーバーがあってこそのプロジェクトなので、運営が維持されるというのは開発と同じくらい重要なことです。
## クレジット
Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。
## よくある質問
### プロジェクトは何を目指していますか?
強いて言うと、漠然的になりますが広く使われる汎用的なプラットフォームになることを目指しています。 Misskeyは他のプロジェクトとは違い、何らかの思想(例えば、反中央集権)やビジョンに基づいて開発が行われているわけではなく、その点ではフラットです。 それが逆に、特定の方向性に縛られないフレキシブルさを生み出すことに繋がっていると感じています。
<!-- TODO: ここにロードマップへのリンク -->
### 企業によって開発されていますか?
いいえ。Misskeyの開発は個人で行われており、商業的でもないため、特定の企業の関りはありません。 開発メンバーも基本的にはボランティアです。 また、開発に対し企業のスポンサーがつくこともありますが、その場合でもやはり開発は個人のコミュニティが主体です。
### 誰が運営していますか?
Misskeyは分散型なため、各サーバーにそれぞれ異なった運営者がいます。従って、特定の個人や企業によって、Misskeyの全てが運営されているわけではありません。 また、開発チームが運営を行うわけでもないため、運営に関する連絡は、お使いのサーバーの運営者に行ってください。 サーバーの運営者は、[このページ](/about)で確認することができます。 あなたがサーバーを作成すれば、あなたが運営者になります。
### どのサーバーを選べばいいですか?
[サーバー一覧が公開されています。](https://join.misskey.page/ja-JP/instances) サーバーによってコミュニティのテーマ(特定のこと、ものが好き 等)が決められている場合があるので、自分に合ったテーマのサーバーがあれば、そこを選ぶと良いかもしれません。 他にも、サーバーの規模、ユーザー層、国および言語、運営者が信頼できるかどうか、などの観点があります。 なお、Misskey公式のサーバーというものはありません。自身で新しくサーバーを作成するという選択肢もあります。
基本的にどのサーバーを選んだとしても、他の全てのサーバーのユーザーと繋がることができます。
### サーバーを建てるにはどうしたらいいですか?
Misskeyサーバーの作成に興味を持っていただきありがとうございます。 2021年現在、Misskeyのホスティングサービスは存在しないため、サーバーの作成にはある程度の知識が必要です。 サーバーの作成方法については[こちら](todo)をご覧ください。
### どのような技術を使用していますか?
Misskeyは開発が進むにつれ使用する技術も大きく変わってきました。開発当初はMySQL + PHP + jQueryといった構成でしたが、現在は以下のようになっています。
- サーバーサイド: Node.js
- データベース: PostgreSQL、Redis
- UIフレームワーク: Vue.js
- プログラミング言語: TypeScript
また、MFMやAiScriptなどの、Misskeyから派生して独自の技術も開発しています。
### Mastodonのフォークですか
いいえ。MisskeyはMastodonやその他のプロジェクトとは全く別のプロジェクトです。 開発に関しても、Misskeyの方が昔から開発されています。ただし、分散型になったのはMastodonの登場より後です。 同じActivityPubという分散のためのプロトコルを実装しているという点以外、両者に特に関りがあるわけでもありません。
### iOS/Androidのアプリはありますか
公式にはそういったOSのネイティブアプリを開発していませんが、サードパーティ製のアプリがいくつかあります。 詳しくは[こちら](./apps)をご覧ください。
ただ、サードパーティ製アプリはどうしても機能への対応が遅れてしまうため、とくに拘りがなければ公式のWebクライアントの利用をおすすめします。 なお、MisskeyのWebクライアントはPWAに対応しているので、ネイティブアプリのように動作させることも可能です。 詳しくは[こちら](todo)をご覧ください。
### Misskeyのロゴ、アイコンはどこで入手できますか
(準備中)
### 時折目にする猫耳の可愛い女の子は?
Misskeyの守り神、藍ちゃんです。アイチャンカワイイヤッター!
<div class="info"> 藍ちゃんについては<a href="https://xn--931a.moe/" target="_blank">こちら</a>です。</div>

View file

@ -1,8 +0,0 @@
# 不具合の報告
不具合と思われる状況に遭遇したときは、まず[トラブルシューティング](./troubleshooting)をご一読ください。 それでも問題が解決しないときは、以下の情報を含めて[フォーラム](https://forum.misskey.io/)に投稿してください。 投稿することで、解決策が見つかったり、不具合と判断されれば開発チームによって修正が行われます。
## 含める情報
- Misskeyのバージョン([情報ページ](/about)で確認できます)
- お使いのブラウザの種類とバージョン
- お使いのOSの種類とバージョン
- 問題の再現手順

View file

@ -1,40 +0,0 @@
# トラブルシューティング
<div class="info"> <a href="./faq">よくある質問</a>も合わせてお役立てください。</div>
問題が発生したときは、まずこちらをご確認ください。 該当する項目が無い、もしくは手順を試しても効果がない場合は、サーバーの管理者に連絡するか[不具合を報告](./report-issue)してください。
## クライアントが起動しない
ほとんどの場合、お使いのブラウザまたはOSのバージョンが古いことが原因です。 ブラウザおよびOSのバージョンを最新のものに更新してから、再度試してみてください。
これは稀ですが、それでも起動しない場合は、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。
## ページが読み込めない
クライアントが起動するもののページが読み込めないというエラーが出る場合は、ネットワークに問題がないか確認してください。また、サーバーがダウンしていないか確認してください。
これは稀ですが、キャッシュが原因の場合があります。ブラウザのキャッシュをクリアして、再度試してみてください。
まだ問題がある場合は、サーバーの問題と思われるのでサーバーの管理者に連絡してください。
## クライアントの動作が遅い
以下を試してみてください:
- クライアント設定で「UIのアニメーションを減らす」を有効にする
- クライアント設定で「モーダルにぼかし効果を使用」を無効にする
- お使いのブラウザの設定でハードウェアアクセラレーションを有効にする
- お使いのデバイスのスペックを上げる
## UIの一部の表示がおかしい(背景が透明になっている等)
アップデートによりUIの改修が行われたときに、テーマのキャッシュシステムの影響でそのような表示になることがあります。 クライアントの設定の「キャッシュをクリア」すると直ります。
<div class="warn">⚠️ 「クライアントの」キャッシュクリアです。「ブラウザの」キャッシュクリアは行わないでください。</div>
## 通知やアンテナ等の点滅が消えない
点滅は、未読のコンテンツがあることを示しています。通常点滅が消えない場合は、コンテンツを遡ると未読なコンテンツが残っています。 すべて既読にしたと思われるのに、それでもなお点滅が続く場合(おそらく不具合と思われます)は設定から強制的にすべて既読扱いにすることができます。
## Renoteができない
フォロワー限定のートはRenoteすることはできません。
## UI上で特定の要素が表示されない
広告ブロッカーを使用しているとそのような不具合が発生することがあります。Misskeyではオフにしてご利用ください。
## UI上で未翻訳の部分がある
ほとんどの場合、単に翻訳が間に合っていないだけで、不具合ではありません。翻訳が終わるまでお待ちください。 [翻訳に参加](./misskey)していただくことも可能です。

View file

@ -1,68 +0,0 @@
# キーボードショートカット
## الشامل
これらのショートカットは基本的にどこでも使えます。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>新規投稿</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>通知を表示/隠す</td><td><b>N</b>otifications</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>البحث</td><td><b>S</b>earch</td></tr>
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr>
</tbody>
</table>
## 投稿にフォーカスされた状態
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd>, <kbd class="key">Tab</kbd></td><td>下の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">R</kbd></td><td>返信フォームを開く</td><td><b>R</b>eply</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>Renoteフォームを開く</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>即刻Renoteする(フォームを開かずに)</td><td>-</td></tr>
<tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr>
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>お気に入りに登録</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
<tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>投稿を削除</td><td><b>D</b>elete</tr>
<tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>投稿に対するメニューを開く</td><td><b>M</b>ore, <b>O</b>ther</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォーカスを外す</td><td>-</td></tr>
</tbody>
</table>
## Renoteフォーム
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">Enter</kbd></td><td>Renoteする</td><td>-</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>フォームを展開する</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォームを閉じる</td><td>-</td></tr>
</tbody>
</table>
## リアクションフォーム
デフォルトで「👍」にフォーカスが当たっている状態です。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd></td><td>下のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">H</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>左のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">L</kbd>, <kbd class="key">Tab</kbd></td><td>右のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">Enter</kbd>, <kbd class="key">Space</kbd>, <kbd class="key">+</kbd></td><td>リアクション確定</td><td>-</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションで確定</td><td>-</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>リアクションするのをやめる</td><td>-</td></tr>
</tbody>
</table>

View file

@ -1,2 +0,0 @@
# MFM
MFMは、Misskey Flavored Markdownの略で、Misskeyの様々な場所で使用できる専用のマークアップ言語です。 MFMで使用可能な構文は[MFMチートシート](/mfm-cheat-sheet)で確認できます。

View file

@ -1,13 +0,0 @@
# اكتم
ユーザーをミュートすると、そのユーザーに関する次のコンテンツがMisskeyに表示されなくなります:
* タイムラインや投稿の検索結果内の、そのユーザーの投稿(およびそれらの投稿に対する返信やRenote)
* そのユーザーからの通知
* メッセージ履歴一覧内の、そのユーザーとのメッセージ履歴
ユーザーをミュートするには、対象のユーザーのユーザーページに表示されている「ミュート」ボタンを押します。
ミュートを行ったことは相手に通知されず、ミュートされていることを知ることもできません。
設定>ミュート から、自分がミュートしているユーザー一覧を確認することができます。

View file

@ -1,10 +0,0 @@
# Pages
## 変数
変数を使うことで動的なページを作成できます。テキスト内で <b>{ 変数名 }</b> と書くとそこに変数の値を埋め込めます。例えば <b>Hello { thing } world!</b> というテキストで、変数(thing)の値が <b>ai</b> だった場合、テキストは <b>Hello ai world!</b> になります。
変数の評価(値を算出すること)は上から下に行われるので、ある変数の中で自分より下の変数を参照することはできません。例えば上から <b>A、B、C</b> と3つの変数を定義したとき、<b>C</b>の中で<b>A</b><b>B</b>を参照することはできますが、<b>A</b>の中で<b>B</b><b>C</b>を参照することはできません。
ユーザーからの入力を受け取るには、ページに「ユーザー入力」ブロックを設置し、「変数名」に入力を格納したい変数名を設定します(変数は自動で作成されます)。その変数を使ってユーザー入力に応じた動作を行えます。
関数を使うと、値の算出処理を再利用可能な形にまとめることができます。関数を作るには、「関数」タイプの変数を作成します。関数にはスロット(引数)を設定することができ、スロットの値は関数内で変数として利用可能です。また、関数を引数に取る関数(高階関数と呼ばれます)も存在します。関数は予め定義しておくほかに、このような高階関数のスロットに即席でセットすることもできます。

View file

@ -1,11 +0,0 @@
# تفاعل
他の人のノートに、絵文字を付けて簡単にあなたの反応を伝えられる機能です。 リアクションするには、ノートの + アイコンをクリックしてピッカーを表示し、絵文字を選択します。 リアクションには[カスタム絵文字](./custom-emoji)も使用できます。
## リアクションピッカーのカスタマイズ
ピッカーに表示される絵文字を自分好みにカスタマイズすることができます。 設定の「リアクション」で設定します。
## リモート投稿へのリアクションについて
リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。
## リモートからのリアクションについて
リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。

View file

@ -1,160 +0,0 @@
# MisskeyリバーシBotの開発
Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。
1. `games/reversi`ストリームに以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる
* イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている
3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する
4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
* `game`: `game`の`id`
5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う
6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する
7. ゲームが開始すると、`started`イベントが流れてくる
* イベントの中身にはゲーム情報が含まれている
8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述)
9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる
* `color`として石の色が含まれている
* `pos`として位置情報が含まれている
## 位置の計算法
8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています:
```
+--+--+--+--+--+--+--+--+
| 0| 1| 2| 3| 4| 5| 6| 7|
+--+--+--+--+--+--+--+--+
| 8| 9|10|11|12|13|14|15|
+--+--+--+--+--+--+--+--+
|16|17|18|19|20|21|22|23|
...
```
### X,Y座標 から インデックス に変換する
```
pos = x + (y * mapWidth)
```
`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます:
```
mapWidth = map[0].length
```
### インデックス から X,Y座標 に変換する
```
x = pos % mapWidth
y = Math.floor(pos / mapWidth)
```
## マップ情報
マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます:
* `(スペース)` ... マス無し
* `-` ... マス
* `b` ... 初期配置される黒石
* `w` ... 初期配置される白石
例えば、4*4の次のような単純なマップがあるとします:
```text
+---+---+---+---+
| | | | |
+---+---+---+---+
| | ○ | ● | |
+---+---+---+---+
| | ● | ○ | |
+---+---+---+---+
| | | | |
+---+---+---+---+
```
この場合、マップデータはこのようになります:
```javascript
['----', '-wb-', '-bw-', '----']
```
## ユーザーにフォームを提示して対話可能Botを作成する
ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。
フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します:
```javascript
{
type: 'init-form',
body: [フォームコントロールの配列]
}
```
フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです:
```javascript
{
id: 'switch1',
type: 'switch',
label: 'Enable hoge',
value: false
}
```
`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。
### フォームの操作を受け取る
ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます:
```javascript
{
id: 'switch1',
value: true
}
```
### フォームコントロールの種類
#### スイッチ
type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。
##### プロパティ
`label` ... スイッチに表記するテキスト。
#### ラジオボタン
type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。
##### プロパティ
`items` ... ラジオボタンの選択肢。例:
```javascript
items: [{
label: '弱',
value: 1
}, {
label: '中',
value: 2
}, {
label: '強',
value: 3
}]
```
#### スライダー
type: `slider` スライダーを表示します。
##### プロパティ
`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。
#### テキストボックス
type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。
## ユーザーにメッセージを表示する
設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します:
```javascript
{
type: 'message',
body: {
text: 'メッセージ内容',
type: 'メッセージの種類'
}
}
```
メッセージの種類: `success`, `info`, `warning`, `error`
## 投了する
投了をするには、<a href="./api/endpoints/games/reversi/games/surrender">このエンドポイント</a>にリクエストします。

View file

@ -1,354 +0,0 @@
# ストリーミングAPI
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。
## ストリームに接続する
ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。
以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例:
```
%WS_URL%/streaming?i=xxxxxxxxxxxxxxx
```
認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。
<div class="ui info">
<p><i class="fas fa-info-circle"></i> 認証情報の取得については、<a href="./api">こちらのドキュメント</a>をご確認ください。</p>
</div>
---
認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例:
```
%WS_URL%/streaming
```
---
ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。
**ストリームでのやり取りはすべてJSONです。**
## チャンネル
MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。
### チャンネルに接続する
チャンネルに接続するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'connect',
body: {
channel: 'xxxxxxxx',
id: 'foobar',
params: {
...
}
}
}
```
ここで、
* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。
* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。
* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。
<div class="ui info">
<p><i class="fas fa-info-circle"></i> IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。</p>
</div>
### チャンネルからのメッセージを受け取る
例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。
チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。
* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。
* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。
### チャンネルに向けてメッセージを送信する
チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。
チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。
* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。
* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。
### チャンネルから切断する
チャンネルから切断するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'disconnect',
body: {
id: 'foobar'
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。
## ストリームを経由してAPIリクエストする
ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。
ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'api',
body: {
id: 'xxxxxxxxxxxxxxxx',
endpoint: 'notes/create',
data: {
text: 'yee haw!'
}
}
}
```
ここで、
* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。
* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。
* `data`には、エンドポイントのパラメータを含めます。
<div class="ui info">
<p><i class="fas fa-info-circle"></i> APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。</p>
</div>
### レスポンスの受信
APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。
```json
{
type: 'api:xxxxxxxxxxxxxxxx',
body: {
...
}
}
```
ここで、
* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。
* `body`には、レスポンスが含まれています。
## 投稿のキャプチャ
Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。
例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。
しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。
この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。
### 投稿をキャプチャする
投稿をキャプチャするには、ストリームに次のようなメッセージを送信します:
```json
{
type: 'subNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャしたい投稿の`id`を設定します。
このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。
例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
ここで、
* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。
* `body`内の`type`に、イベントの種類が設定されます。
* `body`内の`body`に、イベントの詳細が設定されます。
#### イベントの種類
##### `reacted`
その投稿にリアクションがされた時に発生します。
* `reaction`に、リアクションの種類が設定されます。
* `userId`に、リアクションを行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
##### `deleted`
その投稿が削除された時に発生します。
* `deletedAt`に、削除日時が設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'deleted',
body: {
deletedAt: '2018-10-22T02:17:09.703Z'
}
}
}
```
##### `pollVoted`
その投稿に添付されたアンケートに投票された時に発生します。
* `choice`に、選択肢IDが設定されます。
* `userId`に、投票を行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'pollVoted',
body: {
choice: 2,
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
### 投稿のキャプチャを解除する
その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。
次のメッセージを送信します:
```json
{
type: 'unsubNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャを解除したい投稿の`id`を設定します。
このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。
# チャンネル一覧
## `main`
アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `renote`
自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。
#### `mention`
誰かからメンションされたときに発生するイベントです。
#### `readAllNotifications`
自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。
#### `meUpdated`
自分の情報が更新されたことを表すイベントです。
#### `follow`
自分が誰かをフォローしたときに発生するイベントです。
#### `unfollow`
自分が誰かのフォローを解除したときに発生するイベントです。
#### `followed`
自分が誰かにフォローされたときに発生するイベントです。
## `homeTimeline`
ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
タイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `localTimeline`
ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `hybridTimeline`
ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `globalTimeline`
グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。

View file

@ -1,68 +0,0 @@
# المظهر
テーマを設定して、Misskeyクライアントの見た目を変更できます。
## テーマの設定
設定 > テーマ
## テーマを作成する
テーマコードはJSON5で記述されたテーマオブジェクトです。 テーマは以下のようなオブジェクトです。
``` js
{
id: '17587283-dd92-4a2c-a22c-be0637c9e22a',
name: 'Danboard',
author: 'syuilo',
base: 'light',
props: {
accent: 'rgb(218, 141, 49)',
bg: 'rgb(218, 212, 190)',
fg: 'rgb(115, 108, 92)',
panel: 'rgb(236, 232, 220)',
renote: 'rgb(100, 152, 106)',
link: 'rgb(100, 152, 106)',
mention: '@accent',
hashtag: 'rgb(100, 152, 106)',
header: 'rgba(239, 227, 213, 0.75)',
navBg: 'rgb(216, 206, 182)',
inputBorder: 'rgba(0, 0, 0, 0.1)',
},
}
```
* `id` ... テーマの一意なID。UUIDをおすすめします。
* `name` ... テーマ名
* `author` ... テーマの作者
* `desc` ... テーマの説明(オプション)
* `base` ... 明るいテーマか、暗いテーマか
* `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。
* テーマはここで設定されたベーステーマを継承します。
* `props` ... テーマのスタイル定義。これから説明します。
### テーマのスタイル定義
`props`下にはテーマのスタイルを定義します。 キーがCSSの変数名になり、バリューで中身を指定します。 なお、この`props`オブジェクトはベーステーマから継承されます。 ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/misskey-dev/misskey/blob/develop/src/client/themes/_dark.json5)です。 つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。
#### バリューで使える構文
* 16進数で表された色
* 例: `#00ff00`
* `rgb(r, g, b)`形式で表された色
* 例: `rgb(0, 255, 0)`
* `rgb(r, g, b, a)`形式で表された透明度を含む色
* 例: `rgba(0, 255, 0, 0.5)`
* 他のキーの値の参照
* `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。
* 例: `@panel`
* 定数(後述)の参照
* `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。
* 例: `$main`
* 関数(後述)
* `:{関数名}<{引数}<{色}`
#### 定数
「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 キー名を`$`で始めると、そのキーはCSS変数として出力されません。
#### 関数
wip

View file

@ -1,15 +0,0 @@
# مقارنة الجدول الزمني
https://docs.google.com/spreadsheets/d/1lxQ2ugKrhz58Bg96HTDK_2F98BUritkMyIiBkOByjHA/edit?usp=sharing
## الواجهة الرئيسية
مشاركات المستخدمين الذين تتابعهم
## المحلي
جميع مشاركات المستخدمين المحليين التي لم يتم وضع علامة عليها على أنها "صفحة رئيسية فقط "
## إجتماعي
مشاركات المستخدمين الذين تتابعهم بالإضافة إلى جميع مشاركات المستخدمين المحليين التي لم يتم وضع علامة عليها كـ "الصفحة الرئيسية فقط"
## عالمي
全てのローカルユーザーの「ホーム」指定されていない投稿と、サーバーに届いた全てのリモートユーザーの「ホーム」指定されていない投稿

View file

@ -1,8 +0,0 @@
# LTL/STL/GTLの無効化
Misskeyでは、LTL/STL/GTLをそれぞれ無効化することができます。有効/無効を切り替えるには、インスタンスコントロールパネルで設定します。
LTLやSTLは、そのインスタンス全員の投稿が見れるため、新規のユーザーにとってはユーザーを探す必要がなくなり、興味のあるユーザーを見つけやすいという利点があります。 しかし同時に、フォロー機能が活用されなくなったり、不適切な投稿が目につきやすくなったり、チャットのようになることで内輪感が生じて逆に新規ユーザーが参加しにくくなるといったデメリットも持ち合わせています。 サーバーによってメリット/デメリットどちらが優勢かは異なるので、オプションとして無効にできるようになっています。 もしデメリットの方が上回っていると感じたら、それらのタイムラインを無効化することも検討してください。
<div class="warn">⚠️ 無効化を行うと、ユーザーが困惑し、短期的に見て利用者が減る可能性があります。そのため、無効化の際は影響を慎重に検討し、事前に説明してフォローを整える期間を一定程度設けることを推奨します。</div>
なお、管理者/モデレーターは、これらのタイムラインの無効化状態は適用されず、引き続き利用することが可能です。

View file

@ -1,5 +0,0 @@
# よくある質問
ここでは、サーバー管理者向けのよくある質問を掲載しています。
## デフォルトテーマを設定したい
現在、デフォルトテーマ設定機能は実装されていません。

View file

@ -1,7 +0,0 @@
# AiScript
AiScriptは、Misskeyで使用できるスクリプト言語です。
<div class="info"> AiScript実装はMisskeyとは別リポジトリで、<a href="https://github.com/syuilo/aiscript" target="_blank">オープンソースで公開されています。</a></div>
## 使い方
AiScriptの構文や組み込み関数などのドキュメントは、[こちら](https://github.com/syuilo/aiscript/tree/master/docs)で公開されています。

View file

@ -1,58 +0,0 @@
# Misskey API
MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
## アクセストークンの取得
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む
### 自分自身のアクセストークンを手動発行する
「設定 > API」で、自分のアクセストークンを発行できます。
[「APIの使い方」へ進む](#APIの使い方)
### アプリケーション利用者にアクセストークンの発行をリクエストする
アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。
#### Step 1
UUIDを生成する。以後これをセッションIDと呼びます。
> このセッションIDは毎回生成し、使いまわさないようにしてください。
#### Step 2
`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
* `name` ... アプリケーション名
* > 例: `MissDeck`
* `icon` ... アプリケーションのアイコン画像URL
* > 例: `https://missdeck.example.com/icon.png`
* `callback` ... 認証が終わった後にリダイレクトするURL
* > 例: `https://missdeck.example.com/callback`
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
* `permission` ... アプリケーションが要求する権限
* > 例: `write:notes,write:following,read:drive`
* 要求する権限を`,`で区切って列挙します
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
#### Step 3
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
レスポンスに含まれるプロパティ:
* `token` ... ユーザーのアクセストークン
* `user` ... ユーザーの情報
[「APIの使い方」へ進む](#APIの使い方)
## APIの使い方
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
* [APIリファレンス](/api-doc)
* [ストリーミングAPI](./stream)

View file

@ -1,74 +0,0 @@
# プラグインの作成
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## Metadata
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
### name
プラグイン名
### author
プラグイン作者
### version
プラグインバージョン。数値を指定してください。
### description
プラグインの説明
### permissions
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
### config
プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。
#### type
設定値の種類を表す文字列。以下から選択します。 string number boolean
#### label
ユーザーに表示する設定名
#### description
設定の説明
#### default
設定のデフォルト値
## APIリファレンス
AiScript標準で組み込まれているAPIは掲載しません。
### Mk:dialog(title text type)
ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。
### Mk:confirm(title text type)
確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。
### Mk:api(endpoint params)
Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。
### Mk:save(key value)
任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。
### Mk:load(key)
Mk:saveで永続化した指定の名前の値を読み取ります。
### Plugin:register_post_form_action(title fn)
投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。
### Plugin:register_note_action(title fn)
ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。
### Plugin:register_user_action(title fn)
ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。
### Plugin:register_note_view_interruptor(fn)
UIに表示されるート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:register_note_post_interruptor(fn)
ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:open_url(url)
第一引数に渡されたURLをブラウザの新しいタブで開きます。
### Plugin:config
プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。

View file

@ -1,6 +0,0 @@
# Botの作成
[Misskey API](./api)を利用してBotの開発が可能です。 また、いくつかのBot実装が公開されているため、ぜひ参考にしてください。
- [syuilo/ai](https://github.com/syuilo/ai) ... Node.js上で動く、TypeScript製Bot実装
Botを作成したときは、プロフィール設定からBotフラグをオンにしておくことを強くおすすめします。

View file

@ -1,160 +0,0 @@
# MisskeyリバーシBotの開発
Misskeyのリバーシ機能に対応したBotの開発方法をここに記します。
1. `games/reversi`ストリームに以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
2. 対局への招待が来たら、ストリームから`invited`イベントが流れてくる
* イベントの中身に、`parent`という名前で対局へ誘ってきたユーザーの情報が含まれている
3. `games/reversi/match`へ、`user_id`として`parent`の`id`が含まれたリクエストを送信する
4. 上手くいくとゲーム情報が返ってくるので、`games/reversi-game`ストリームへ、以下のパラメータを付けて接続する:
* `i`: botアカウントのAPIキー
* `game`: `game`の`id`
5. この間、相手がゲームの設定を変更するとその都度`update-settings`イベントが流れてくるので、必要であれば何かしらの処理を行う
6. 設定に満足したら、`{ type: 'accept' }`メッセージをストリームに送信する
7. ゲームが開始すると、`started`イベントが流れてくる
* イベントの中身にはゲーム情報が含まれている
8. 石を打つには、ストリームに`{ type: 'set', pos: <位置> }`を送信する(位置の計算方法は後述)
9. 相手または自分が石を打つと、ストリームから`set`イベントが流れてくる
* `color`として石の色が含まれている
* `pos`として位置情報が含まれている
## 位置の計算法
8x8のマップを考える場合、各マスの位置(インデックスと呼びます)は次のようになっています:
```
+--+--+--+--+--+--+--+--+
| 0| 1| 2| 3| 4| 5| 6| 7|
+--+--+--+--+--+--+--+--+
| 8| 9|10|11|12|13|14|15|
+--+--+--+--+--+--+--+--+
|16|17|18|19|20|21|22|23|
...
```
### X,Y座標 から インデックス に変換する
```
pos = x + (y * mapWidth)
```
`mapWidth`は、ゲーム情報の`map`から、次のようにして計算できます:
```
mapWidth = map[0].length
```
### インデックス から X,Y座標 に変換する
```
x = pos % mapWidth
y = Math.floor(pos / mapWidth)
```
## マップ情報
マップ情報は、ゲーム情報の`map`に入っています。 文字列の配列になっており、ひとつひとつの文字がマス情報を表しています。 それをもとにマップのデザインを知る事が出来ます:
* `(スペース)` ... マス無し
* `-` ... マス
* `b` ... 初期配置される黒石
* `w` ... 初期配置される白石
例えば、4*4の次のような単純なマップがあるとします:
```text
+---+---+---+---+
| | | | |
+---+---+---+---+
| | ○ | ● | |
+---+---+---+---+
| | ● | ○ | |
+---+---+---+---+
| | | | |
+---+---+---+---+
```
この場合、マップデータはこのようになります:
```javascript
['----', '-wb-', '-bw-', '----']
```
## ユーザーにフォームを提示して対話可能Botを作成する
ユーザーとのコミュニケーションを行うため、ゲームの設定画面でユーザーにフォームを提示することができます。 例えば、Botの強さをユーザーが設定できるようにする、といったシナリオが考えられます。
フォームを提示するには、`reversi-game`ストリームに次のメッセージを送信します:
```javascript
{
type: 'init-form',
body: [フォームコントロールの配列]
}
```
フォームコントロールの配列については今から説明します。 フォームコントロールは、次のようなオブジェクトです:
```javascript
{
id: 'switch1',
type: 'switch',
label: 'Enable hoge',
value: false
}
```
`id` ... コントロールのID。 `type` ... コントロールの種類。後述します。 `label` ... コントロールと一緒に表記するテキスト。 `value` ... コントロールのデフォルト値。
### フォームの操作を受け取る
ユーザーがフォームを操作すると、ストリームから`update-form`イベントが流れてきます。 イベントの中身には、コントロールのIDと、ユーザーが設定した値が含まれています。 例えば、上で示したスイッチをユーザーがオンにしたとすると、次のイベントが流れてきます:
```javascript
{
id: 'switch1',
value: true
}
```
### フォームコントロールの種類
#### スイッチ
type: `switch` スイッチを表示します。何かの機能をオン/オフさせたい場合に有用です。
##### プロパティ
`label` ... スイッチに表記するテキスト。
#### ラジオボタン
type: `radio` ラジオボタンを表示します。選択肢を提示するのに有用です。例えば、Botの強さを設定させるなどです。
##### プロパティ
`items` ... ラジオボタンの選択肢。例:
```javascript
items: [{
label: '弱',
value: 1
}, {
label: '中',
value: 2
}, {
label: '強',
value: 3
}]
```
#### スライダー
type: `slider` スライダーを表示します。
##### プロパティ
`min` ... スライダーの下限。 `max` ... スライダーの上限。 `step` ... 入力欄で刻むステップ値。
#### テキストボックス
type: `textbox` テキストボックスを表示します。ユーザーになにか入力させる一般的な用途に利用できます。
## ユーザーにメッセージを表示する
設定画面でユーザーと対話する、フォーム以外のもうひとつの方法がこれです。ユーザーになにかメッセージを表示することができます。 例えば、ユーザーがBotの対応していないモードやマップを選択したとき、警告を表示するなどです。 メッセージを表示するには、次のメッセージをストリームに送信します:
```javascript
{
type: 'message',
body: {
text: 'メッセージ内容',
type: 'メッセージの種類'
}
}
```
メッセージの種類: `success`, `info`, `warning`, `error`
## 投了する
投了をするには、<a href="./api/endpoints/games/reversi/games/surrender">このエンドポイント</a>にリクエストします。

View file

@ -1,54 +0,0 @@
# シェアページ
`/share`を開くと、共有用の投稿フォームを開くことができます。 ここではシェアページで利用できるクエリ文字列の一覧を示します。
## クエリ文字列一覧
### 文字
<dl>
<dt>title</dt>
<dd>タイトルです。本文の先頭に[ … ]と挿入されます。</dd>
<dt>text</dt>
<dd>本文です。</dd>
<dt>url</dt>
<dd>URLです。末尾に挿入されます。</dd>
</dl>
### リプライ情報
以下のいずれか
<dl>
<dt>replyId</dt>
<dd>リプライ先のートid</dd>
<dt>replyUri</dt>
<dd>リプライ先のUrlリモートのートオブジェクトを指定</dd>
</dl>
### Renote情報
以下のいずれか
<dl>
<dt>renoteId</dt>
<dd>Renote先のートid</dd>
<dt>renoteUri</dt>
<dd>Renote先のUrlリモートのートオブジェクトを指定</dd>
</dl>
### 公開範囲
※specifiedに相当する値はvisibility=specifiedとvisibleAccts/visibleUserIdsで指定する
<dl>
<dt>visibility</dt>
<dd>公開範囲 ['public' | 'home' | 'followers' | 'specified']</dd>
<dt>localOnly</dt>
<dd>0(false) or 1(true)</dd>
<dt>visibleUserIds</dt>
<dd>specified時のダイレクト先のユーザーid カンマ区切りで</dd>
<dt>visibleAccts</dt>
<dd>specified時のダイレクト先のacct?username[host] カンマ区切りで</dd>
</dl>
### Soubor(ů)
<dl>
<dt>fileIds</dt>
<dd>添付したいファイルのidカンマ区切りで</dd>
</dl>

View file

@ -1,350 +0,0 @@
# ストリーミングAPI
ストリーミングAPIを使うと、リアルタイムで様々な情報(例えばタイムラインに新しい投稿が流れてきた、メッセージが届いた、フォローされた、など)を受け取ったり、様々な操作を行ったりすることができます。
## ストリームに接続する
ストリーミングAPIを利用するには、まずMisskeyサーバーに**websocket**接続する必要があります。
以下のURLに、`i`というパラメータ名で認証情報を含めて、websocket接続してください。例:
```
%WS_URL%/streaming?i=xxxxxxxxxxxxxxx
```
認証情報は、自分のAPIキーや、アプリケーションからストリームに接続する際はユーザーのアクセストークンのことを指します。
<div class="info"> 認証情報の取得については、<a href="./api">こちらのドキュメント</a>をご確認ください。</div>
---
認証情報は省略することもできますが、その場合非ログインでの利用ということになり、受信できる情報や可能な操作は限られます。例:
```
%WS_URL%/streaming
```
---
ストリームに接続すると、後述するAPI操作や、投稿の購読を行ったりすることができます。 しかしまだこの段階では、例えばタイムラインへの新しい投稿を受信したりすることはできません。 それを行うには、ストリーム上で、後述する**チャンネル**に接続する必要があります。
**ストリームでのやり取りはすべてJSONです。**
## チャンネル
MisskeyのストリーミングAPIにはチャンネルという概念があります。これは、送受信する情報を分離するための仕組みです。 Misskeyのストリームに接続しただけでは、まだリアルタイムでタイムラインの投稿を受信したりはできません。 ストリーム上でチャンネルに接続することで、様々な情報を受け取ったり情報を送信したりすることができるようになります。
ひとつのストリーム上で、同時に複数のチャンネルに接続することができます。
### チャンネルに接続する
チャンネルに接続するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'connect',
body: {
channel: 'xxxxxxxx',
id: 'foobar',
params: {
...
}
}
}
```
ここで、
* `channel`には接続したいチャンネル名を設定します。チャンネルの種類については後述します。
* `id`にはそのチャンネルとやり取りするための任意のIDを設定します。ストリームでは様々なメッセージが流れるので、そのメッセージがどのチャンネルからのものなのか識別する必要があるからです。このIDは、UUIDや、乱数のようなもので構いません。
* `params`はチャンネルに接続する際のパラメータです。チャンネルによって接続時に必要とされるパラメータは異なります。パラメータ不要のチャンネルに接続する際は、このプロパティは省略可能です。
<div class="info"> IDはチャンネルごとではなく「チャンネルの接続ごと」です。なぜなら、同じチャンネルに異なるパラメータで複数接続するケースもあるからです。</div>
### チャンネルからのメッセージを受け取る
例えばタイムラインのチャンネルなら、新しい投稿があった時にメッセージを発します。そのメッセージを受け取ることで、タイムラインに新しい投稿がされたことをリアルタイムで知ることができます。
チャンネルがメッセージを発すると、次のようなデータがJSONでストリームに流れてきます:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDが設定されています。これで、このメッセージがどのチャンネルからのものなのか知ることができます。
* `type`にはメッセージの種類が設定されます。チャンネルによって、どのような種類のメッセージが流れてくるかは異なります。
* `body`にはメッセージの内容が設定されます。チャンネルによって、どのような内容のメッセージが流れてくるかは異なります。
### チャンネルに向けてメッセージを送信する
チャンネルによっては、メッセージを受け取るだけでなく、こちらから何かメッセージを送信し、何らかの操作を行える場合があります。
チャンネルにメッセージを送信するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'channel',
body: {
id: 'foobar',
type: 'something',
body: {
some: 'thing'
}
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。これで、このメッセージがどのチャンネルに向けたものなのか識別させることができます。
* `type`にはメッセージの種類を設定します。チャンネルによって、どのような種類のメッセージを受け付けるかは異なります。
* `body`にはメッセージの内容を設定します。チャンネルによって、どのような内容のメッセージを受け付けるかは異なります。
### チャンネルから切断する
チャンネルから切断するには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'disconnect',
body: {
id: 'foobar'
}
}
```
ここで、
* `id`には前述したそのチャンネルに接続する際に設定したIDを設定します。
## ストリームを経由してAPIリクエストする
ストリームを経由してAPIリクエストすると、HTTPリクエストを発生させずにAPIを利用できます。そのため、コードを簡潔にできたり、パフォーマンスの向上を見込めるかもしれません。
ストリームを経由してAPIリクエストするには、次のようなデータをJSONでストリームに送信します:
```json
{
type: 'api',
body: {
id: 'xxxxxxxxxxxxxxxx',
endpoint: 'notes/create',
data: {
text: 'yee haw!'
}
}
}
```
ここで、
* `id`には、APIのレスポンスを識別するための、APIリクエストごとの一意なIDを設定する必要があります。UUIDや、簡単な乱数のようなもので構いません。
* `endpoint`には、あなたがリクエストしたいAPIのエンドポイントを指定します。
* `data`には、エンドポイントのパラメータを含めます。
<div class="info"> APIのエンドポイントやパラメータについてはAPIリファレンスをご確認ください。</div>
### レスポンスの受信
APIへリクエストすると、レスポンスがストリームから次のような形式で流れてきます。
```json
{
type: 'api:xxxxxxxxxxxxxxxx',
body: {
...
}
}
```
ここで、
* `xxxxxxxxxxxxxxxx`の部分には、リクエストの際に設定された`id`が含まれています。これにより、どのリクエストに対するレスポンスなのか判別することができます。
* `body`には、レスポンスが含まれています。
## 投稿のキャプチャ
Misskeyは投稿のキャプチャと呼ばれる仕組みを提供しています。これは、指定した投稿のイベントをストリームで受け取る機能です。
例えばタイムラインを取得してユーザーに表示したとします。ここで誰かがそのタイムラインに含まれるどれかの投稿に対してリアクションしたとします。
しかし、クライアントからするとある投稿にリアクションが付いたことなどは知る由がないため、リアルタイムでリアクションをタイムライン上の投稿に反映して表示するといったことができません。
この問題を解決するために、Misskeyは投稿のキャプチャ機構を用意しています。投稿をキャプチャすると、その投稿に関するイベントを受け取ることができるため、リアルタイムでリアクションを反映させたりすることが可能になります。
### 投稿をキャプチャする
投稿をキャプチャするには、ストリームに次のようなメッセージを送信します:
```json
{
type: 'subNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャしたい投稿の`id`を設定します。
このメッセージを送信すると、Misskeyにキャプチャを要請したことになり、以後、その投稿に関するイベントが流れてくるようになります。
例えば投稿にリアクションが付いたとすると、次のようなメッセージが流れてきます:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
ここで、
* `body`内の`id`に、イベントを発生させた投稿のIDが設定されます。
* `body`内の`type`に、イベントの種類が設定されます。
* `body`内の`body`に、イベントの詳細が設定されます。
#### イベントの種類
##### `reacted`
その投稿にリアクションがされた時に発生します。
* `reaction`に、リアクションの種類が設定されます。
* `userId`に、リアクションを行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'reacted',
body: {
reaction: 'like',
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
##### `deleted`
その投稿が削除された時に発生します。
* `deletedAt`に、削除日時が設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'deleted',
body: {
deletedAt: '2018-10-22T02:17:09.703Z'
}
}
}
```
##### `pollVoted`
その投稿に添付されたアンケートに投票された時に発生します。
* `choice`に、選択肢IDが設定されます。
* `userId`に、投票を行ったユーザーのIDが設定されます。
例:
```json
{
type: 'noteUpdated',
body: {
id: 'xxxxxxxxxxxxxxxx',
type: 'pollVoted',
body: {
choice: 2,
userId: 'yyyyyyyyyyyyyyyy'
}
}
}
```
### 投稿のキャプチャを解除する
その投稿がもう画面に表示されなくなったりして、その投稿に関するイベントをもう受け取る必要がなくなったときは、キャプチャの解除を申請してください。
次のメッセージを送信します:
```json
{
type: 'unsubNote',
body: {
id: 'xxxxxxxxxxxxxxxx'
}
}
```
ここで、
* `id`にキャプチャを解除したい投稿の`id`を設定します。
このメッセージを送信すると、以後、その投稿に関するイベントは流れてこないようになります。
# チャンネル一覧
## `main`
アカウントに関する基本的な情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `renote`
自分の投稿がRenoteされた時に発生するイベントです。自分自身の投稿をRenoteしたときは発生しません。
#### `mention`
誰かからメンションされたときに発生するイベントです。
#### `readAllNotifications`
自分宛ての通知がすべて既読になったことを表すイベントです。このイベントを利用して、「通知があることを示すアイコン」のようなものをオフにしたりする等のケースが想定されます。
#### `meUpdated`
自分の情報が更新されたことを表すイベントです。
#### `follow`
自分が誰かをフォローしたときに発生するイベントです。
#### `unfollow`
自分が誰かのフォローを解除したときに発生するイベントです。
#### `followed`
自分が誰かにフォローされたときに発生するイベントです。
## `homeTimeline`
ホームタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
タイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `localTimeline`
ローカルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ローカルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `hybridTimeline`
ソーシャルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
ソーシャルタイムラインに新しい投稿が流れてきたときに発生するイベントです。
## `globalTimeline`
グローバルタイムラインの投稿情報が流れてきます。このチャンネルにパラメータはありません。
### 流れてくるイベント一覧
#### `note`
グローバルタイムラインに新しい投稿が流れてきたときに発生するイベントです。

View file

@ -1,4 +0,0 @@
# AiScript
## Funkce
デフォルトで値渡しです。

View file

@ -1,58 +0,0 @@
# Misskey API
MisskeyAPIを使ってMisskeyクライアント、Misskey連携Webサービス、Bot等(以下「アプリケーション」と呼びます)を開発できます。 ストリーミングAPIもあるので、リアルタイム性のあるアプリケーションを作ることも可能です。
APIを使い始めるには、まずアクセストークンを取得する必要があります。 このドキュメントでは、アクセストークンを取得する手順を説明した後、基本的なAPIの使い方を説明します。
## アクセストークンの取得
基本的に、APIはリクエストにはアクセストークンが必要となります。 APIにリクエストするのが自分自身なのか、不特定の利用者に使ってもらうアプリケーションなのかによって取得手順は異なります。
* 前者の場合: [「自分自身のアクセストークンを手動発行する」](#自分自身のアクセストークンを手動発行する)に進む
* 後者の場合: [「アプリケーション利用者にアクセストークンの発行をリクエストする」](#アプリケーション利用者にアクセストークンの発行をリクエストする)に進む
### 自分自身のアクセストークンを手動発行する
「設定 > API」で、自分のアクセストークンを発行できます。
[「APIの使い方」へ進む](#APIの使い方)
### アプリケーション利用者にアクセストークンの発行をリクエストする
アプリケーション利用者のアクセストークンを取得するには、以下の手順で発行をリクエストします。
#### Step 1
UUIDを生成する。以後これをセッションIDと呼びます。
> このセッションIDは毎回生成し、使いまわさないようにしてください。
#### Step 2
`{_URL_}/miauth/{session}`をユーザーのブラウザで表示させる。`{session}`の部分は、セッションIDに置き換えてください。
> 例: `{_URL_}/miauth/c1f6d42b-468b-4fd2-8274-e58abdedef6f`
表示する際、URLにクエリパラメータとしていくつかのオプションを設定できます:
* `name` ... アプリケーション名
* > 例: `MissDeck`
* `icon` ... アプリケーションのアイコン画像URL
* > 例: `https://missdeck.example.com/icon.png`
* `callback` ... 認証が終わった後にリダイレクトするURL
* > 例: `https://missdeck.example.com/callback`
* リダイレクト時には、`session`というクエリパラメータでセッションIDが付きます
* `permission` ... アプリケーションが要求する権限
* > 例: `write:notes,write:following,read:drive`
* 要求する権限を`,`で区切って列挙します
* どのような権限があるかは[APIリファレンス](/api-doc)で確認できます
#### Step 3
ユーザーが発行を許可した後、`{_URL_}/api/miauth/{session}/check`にPOSTリクエストすると、レスポンスとしてアクセストークンを含むJSONが返ります。
レスポンスに含まれるプロパティ:
* `token` ... ユーザーのアクセストークン
* `user` ... ユーザーの情報
[「APIの使い方」へ進む](#APIの使い方)
## APIの使い方
**APIはすべてPOSTで、リクエスト/レスポンスともにJSON形式です。RESTではありません。** アクセストークンは、`i`というパラメータ名でリクエストに含めます。
* [APIリファレンス](/api-doc)
* [ストリーミングAPI](./stream)

View file

@ -1,74 +0,0 @@
# プラグインの作成
Misskey Webクライアントのプラグイン機能を使うと、クライアントを拡張し、様々な機能を追加できます。 ここではプラグインの作成にあたってのメタデータ定義や、AiScript APIリファレンスを掲載します。
## Metadata
プラグインは、AiScriptのメタデータ埋め込み機能を使って、デフォルトとしてプラグインのメタデータを定義する必要があります。 メタデータは次のプロパティを含むオブジェクトです。
### name
プラグイン名
### author
プラグイン作者
### version
プラグインバージョン。数値を指定してください。
### description
プラグインの説明
### permissions
プラグインが要求する権限。MisskeyAPIにリクエストする際に用いられます。
### config
プラグインの設定情報を表すオブジェクト。 キーに設定名、値に以下のプロパティを含めます。
#### type
設定値の種類を表す文字列。以下から選択します。 string number boolean
#### label
ユーザーに表示する設定名
#### description
設定の説明
#### default
設定のデフォルト値
## APIリファレンス
AiScript標準で組み込まれているAPIは掲載しません。
### Mk:dialog(title text type)
ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると info になります。
### Mk:confirm(title text type)
確認ダイアログを表示します。typeには以下の値が設定できます。 info success warn error question 省略すると question になります。 ユーザーが"OK"を選択した場合は true を、"キャンセル"を選択した場合は false が返ります。
### Mk:api(endpoint params)
Misskey APIにリクエストします。第一引数にエンドポイント名、第二引数にパラメータオブジェクトを渡します。
### Mk:save(key value)
任意の値に任意の名前を付けて永続化します。永続化した値は、AiScriptコンテキストが終了しても残り、Mk:loadで読み取ることができます。
### Mk:load(key)
Mk:saveで永続化した指定の名前の値を読み取ります。
### Plugin:register_post_form_action(title fn)
投稿フォームにアクションを追加します。第一引数にアクション名、第二引数にアクションが選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に投稿フォームオブジェクトが渡されます。
### Plugin:register_note_action(title fn)
ノートメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。
### Plugin:register_user_action(title fn)
ユーザーメニューに項目を追加します。第一引数に項目名、第二引数に項目が選択された際のコールバック関数を渡します。 コールバック関数には、第一引数に対象のユーザーオブジェクトが渡されます。
### Plugin:register_note_view_interruptor(fn)
UIに表示されるート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:register_note_post_interruptor(fn)
ノート投稿時にノート情報を書き換えます。 コールバック関数には、第一引数に対象のノートオブジェクトが渡されます。 コールバック関数の返り値でノートが書き換えられます。
### Plugin:open_url(url)
第一引数に渡されたURLをブラウザの新しいタブで開きます。
### Plugin:config
プラグインの設定が格納されるオブジェクト。プラグイン定義のconfigで設定したキーで値が入ります。

View file

@ -1,2 +0,0 @@
# Vlastní emoji
カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。

View file

@ -1,18 +0,0 @@
# デッキ
デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。
## カラムの追加
デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。
## カラムの移動
カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。
## カラムの水平分割
カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。
## カラムの設定
カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。
## デッキの設定
デッキに関する設定は、[settings/deck](/settings/deck)で行えます。

View file

@ -1,4 +0,0 @@
# Antény
アンテナは、自由に条件を設定して、合致するノートを自動で収集することができる機能です。
条件を設定したアンテナが作成された状態で、条件に合致するノートが投稿されると、リアルタイムでそのアンテナのタイムラインにノートが追加されます。

View file

@ -1,2 +0,0 @@
# Vlastní emoji
カスタム絵文字は、インスタンスで用意された画像を絵文字のように使える機能です。 ノート、リアクション、チャット、自己紹介、名前などの場所で使うことができます。 カスタム絵文字をそれらの場所で使うには、絵文字ピッカーボタン(ある場合)を押すか、`:`を入力して絵文字サジェストを表示します。 テキスト内に`:foo:`のような形式の文字列が見つかると、`foo`の部分がカスタム絵文字名と解釈され、表示時には対応したカスタム絵文字に置き換わります。

View file

@ -1,18 +0,0 @@
# デッキ
デッキは利用可能なUIのひとつです。「カラム」と呼ばれるビューを複数並べて表示させることで、カスタマイズ性が高く、情報量の多いUIが構築できることが特徴です。
## カラムの追加
デッキの背景を右クリックし、「カラムを追加」して任意のカラムを追加できます。
## カラムの移動
カラムは、ドラッグアンドドロップで他のカラムと位置を入れ替えることが出来るほか、カラムメニュー(カラムのヘッダー右クリック)から位置を移動させることもできます。
## カラムの水平分割
カラムは左右だけでなく、上下に並べることもできます。 カラムメニューを開き、「左に重ねる」を選択すると、左のカラムの下に現在のカラムが移動します。 上下分割を解除するには、カラムメニューの「右に出す」を選択します。
## カラムの設定
カラムメニューの「編集」を選択するとカラムの設定を編集できます。カラムの名前を変えたり、幅を変えたりできます。
## デッキの設定
デッキに関する設定は、[settings/deck](/settings/deck)で行えます。

View file

@ -1,17 +0,0 @@
# Úložiště
ドライブは、Misskey上でファイルを管理できる機能です。
[ドライブのページ](/my/drive)から任意のファイルをアップロードできるほか、アバターに設定した画像や、ノートに添付したファイルなどもすべてドライブにアップロードされます。
<div class="warn">⚠️ ドライブからファイルを削除すると、そのファイルが添付されたノートも消えます。</div>
ドライブにアップロードされたファイルは、いつでもダウンロードすることができるほか、ノート作成時に「ドライブからファイルを添付」することでファイルを再利用することもできます。
ドライブ内にフォルダを作り、複数のファイルをまとめて整理することもできます。
## 閲覧注意 (NSFW)
<div class="info"> この項目が閲覧注意なわけではありません</div>
閲覧注意またはNSFW (Not safe for work) は、ドライブのファイルに設定することができるフラグです。 閲覧注意フラグを設定されたファイルは、表示される際に閲覧者の操作なしには表示されなくなります。 このフラグは、例えば職場や公共の場で閲覧するのに適切でないと思われる画像などに設定し、そのような画像が突然表示されてしまうことを防ぐ目的で使われます。
このフラグは手動でオンオフを切り替えられるほか、モデレーターの判断で設定される場合もあります。

View file

@ -1,4 +0,0 @@
# Oblíbené
[ノート](./node)をお気に入りとして登録できる機能です。 お気に入り登録したノートは、[お気に入りページ](./my/favorites)で一覧することができます。 お気に入りに登録したことは相手に通知されず、お気に入りは自分しか見ることができません。
ノートをお気に入り登録するには、ノートメニューの「お気に入り」を押します。お気に入り解除するには、ノートメニューの「お気に入り解除」を押します。

View file

@ -1,2 +0,0 @@
# Sledovaní
ユーザーをフォローすると、タイムラインにそのユーザーの投稿が表示されるようになります。ただし、他のユーザーに対する返信は含まれません。 ユーザーをフォローするには、ユーザーページの「フォロー」ボタンをクリックします。フォローを解除するには、もう一度クリックします。

View file

@ -1,66 +0,0 @@
# キーボードショートカット
## グローバル
これらのショートカットは基本的にどこでも使えます。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">P</kbd>, <kbd class="key">N</kbd></td><td>新規投稿</td><td><b>P</b>ost, <b>N</b>ew, <b>N</b>ote</td></tr>
<tr><td><kbd class="key">T</kbd></td><td>タイムラインの最も新しい投稿にフォーカス</td><td><b>T</b>imeline, <b>T</b>op</td></tr>
<tr><td><kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">N</kbd></kbd></td><td>通知を表示/隠す</td><td><b>N</b>otifications</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>Vyhledávání</td><td><b>S</b>earch</td></tr>
<tr><td><kbd class="key">H</kbd>, <kbd class="key">?</kbd></td><td>ヘルプを表示</td><td><b>H</b>elp</td></tr>
</tbody>
</table>
## 投稿にフォーカスされた状態
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>上の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd>, <kbd class="key">Tab</kbd></td><td>下の投稿にフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">R</kbd></td><td>返信フォームを開く</td><td><b>R</b>eply</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>Renoteフォームを開く</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">Q</kbd></kbd></td><td>即刻Renoteする(フォームを開かずに)</td><td>-</td></tr>
<tr><td><kbd class="key">E</kbd>, <kbd class="key">A</kbd>, <kbd class="key">+</kbd></td><td>リアクションフォームを開く</td><td><b>E</b>mote, re<b>A</b>ction</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションをする(対応については後述)</td><td>-</td></tr>
<tr><td><kbd class="key">F</kbd>, <kbd class="key">B</kbd></td><td>お気に入りに登録</td><td><b>F</b>avorite, <b>B</b>ookmark</td></tr>
<tr><td><kbd class="key">Del</kbd>, <kbd class="group"><kbd class="key">Ctrl</kbd> + <kbd class="key">D</kbd></kbd></td><td>投稿を削除</td><td><b>D</b>elete</tr>
<tr><td><kbd class="key">M</kbd>, <kbd class="key">O</kbd></td><td>投稿に対するメニューを開く</td><td><b>M</b>ore, <b>O</b>ther</td></tr>
<tr><td><kbd class="key">S</kbd></td><td>CWで隠された部分を表示 or 隠す</td><td><b>S</b>how, <b>S</b>ee</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォーカスを外す</td><td>-</td></tr>
</tbody>
</table>
## Renoteフォーム
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key">Enter</kbd></td><td>Renoteする</td><td>-</td></tr>
<tr><td><kbd class="key">Q</kbd></td><td>フォームを展開する</td><td><b>Q</b>uote</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>フォームを閉じる</td><td>-</td></tr>
</tbody>
</table>
## リアクションフォーム
デフォルトで「👍」にフォーカスが当たっている状態です。
<table>
<thead>
<tr><th>ショートカット</th><th>効果</th><th>由来</th></tr>
</thead>
<tbody>
<tr><td><kbd class="key"></kbd>, <kbd class="key">K</kbd></td><td>上のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">J</kbd></td><td>下のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">H</kbd>, <kbd class="group"><kbd class="key">Shift</kbd> + <kbd class="key">Tab</kbd></kbd></td><td>左のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key"></kbd>, <kbd class="key">L</kbd>, <kbd class="key">Tab</kbd></td><td>右のリアクションにフォーカスを移動</td><td>-</td></tr>
<tr><td><kbd class="key">Enter</kbd>, <kbd class="key">Space</kbd>, <kbd class="key">+</kbd></td><td>リアクション確定</td><td>-</td></tr>
<tr><td><kbd class="key">0</kbd>~<kbd class="key">9</kbd></td><td>数字に対応したリアクションで確定</td><td>-</td></tr>
<tr><td><kbd class="key">Esc</kbd></td><td>リアクションするのをやめる</td><td>-</td></tr>
</tbody>
</table>

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