Improve docs

This commit is contained in:
syuilo 2021-08-05 00:15:51 +09:00
parent d2da459dd8
commit e044d11782
21 changed files with 170 additions and 15 deletions

View file

@ -766,6 +766,12 @@ customCssWarn: "この設定は必ず知識のある方が行ってください
global: "グローバル" global: "グローバル"
squareAvatars: "アイコンを四角形で表示" squareAvatars: "アイコンを四角形で表示"
_docs:
continueReading: "続きを読む"
features: "機能"
generalTopics: "一般的なトピック"
advancedTopics: "高度なトピック"
_ad: _ad:
back: "戻る" back: "戻る"
reduceFrequencyOfThisAd: "この広告の表示頻度を下げる" reduceFrequencyOfThisAd: "この広告の表示頻度を下げる"

View file

@ -107,6 +107,7 @@ export default defineComponent({
padding: 32px; padding: 32px;
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
background: var(--panel);
&.max-width_500px { &.max-width_500px {
padding: 16px; padding: 16px;

View file

@ -1,14 +1,38 @@
<template> <template>
<div> <div class="vtaihdtm">
<main class="_section"> <div class="search">
<div class="_content"> <MkInput v-model:value="query" :debounce="true" type="search"><template #icon><i class="fas fa-search"></i></template><span>{{ $ts.search }}</span></MkInput>
<ul>
<li v-for="doc in docs" :key="doc.path">
<MkA :to="`/docs/${doc.path}`">{{ doc.title }}</MkA>
</li>
</ul>
</div> </div>
</main> <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>
</div> </div>
</template> </template>
@ -16,8 +40,15 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { url, lang } from '@client/config'; import { url, lang } from '@client/config';
import * as symbols from '@client/symbols'; import * as symbols from '@client/symbols';
import MkFolder from '@client/components/ui/folder.vue';
import MkInput from '@client/components/ui/input.vue';
export default defineComponent({ export default defineComponent({
components: {
MkFolder,
MkInput,
},
data() { data() {
return { return {
[symbols.PAGE_INFO]: { [symbols.PAGE_INFO]: {
@ -25,6 +56,15 @@ export default defineComponent({
icon: 'fas fa-question-circle' icon: 'fas fa-question-circle'
}, },
docs: [], docs: [],
query: null,
}
},
watch: {
query() {
fetch(`${url}/docs.json?lang=${lang}&q=${this.query}`).then(res => res.json()).then(docs => {
this.docs = docs;
});
} }
}, },
@ -35,3 +75,48 @@ export default defineComponent({
}, },
}); });
</script> </script>
<style lang="scss" scoped>
.vtaihdtm {
background: var(--panel);
> .search {
padding: 8px;
}
.docs {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
grid-gap: 12px;
margin: var(--margin);
> .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

@ -31,7 +31,7 @@ export const router = createRouter({
{ path: '/docs', component: page('docs') }, { 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: '/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: '/search', component: page('search') }, { path: '/search', component: page('search') },

View file

@ -9,7 +9,6 @@
## リモート投稿へのリアクションについて ## リモート投稿へのリアクションについて
リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。 リアクションはMisskeyオリジナルの機能であるため、リモートインスタンスがMisskeyでない限りは、ほとんどの場合「Like」としてアクティビティが送信されます。一般的にはLikeは「お気に入り」として実装されているようです。
また、相手がMisskeyであったとしても、カスタム絵文字リアクションは伝わらず、自動的に「👍」等にフォールバックされます。
## リモートからのリアクションについて ## リモートからのリアクションについて
リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。 リモートから「Like」アクティビティを受信したとき、Misskeyでは「👍」のリアクションとして解釈されます。

View file

@ -0,0 +1,43 @@
# Misskeyについて
Misskeyはオープンソースの分散型マイクロブログプラットフォームプロジェクトです。
開発はsyuiloによって2014年から開始されました。
## 分散型とは何か?
分散(distributed)型とは、非中央集権(decentralized)とも呼ばれ、コミュニティが多数のサーバーに分散して存在し、それらが相互に通信することでコンテンツ共有ネットワークを形成していることが特徴のサービスです。
単一のサーバーしか存在しない、もしくは複数存在しても互いに独立している場合は中央集権なサービスと言われ、例えばTwitterやFacebookなどほとんどのサービスがそれに該当します。
## 常にオープンソース
Misskeyはこれまでもこれからも、オープンソースであり続けます。オープンソースとは、ソフトウェアのソースコード(プログラム)が公開されていることです。ソースコードの修正や再配布が可能であることを定義に含めることもあります。
Misskeyのすべてのソースコードは公開されていて、誰でも自由に閲覧、使用、修正、改変、再配布をすることができます。
オープンソースは、自分で好きなように変えたり、有害な処理が含まれていないことを確認することができたり、誰でも開発に参加できるなどの、様々なメリットがあります。
上述の分散型を実現するためにも、オープンソースであるということは必要不可欠な要素です。
再び引き合いに出しますが、TwitterやFacebookなどの利益を得ているほとんどのサービスはオープンソースではありません。
Misskeyのソースコードは、[GitHub上で公開されています。](https://github.com/misskey-dev)
## 開発に参加する、開発を支援する
Misskeyの開発に貢献するにはいろいろな方法があります。
### 機能を追加したり、バグを修正する
ソフトウェアエンジニアのスキルをお持ちの方であれば、ソースコードを編集する形でプロジェクトに貢献することができます。
### 議論に参加する
新しい機能、または既存の機能について意見を述べたり、不具合を報告したりすることでも貢献できます。
そのようなディスカッションは[GitHub](https://github.com/misskey-dev)上か、[フォーラム](https://forum.misskey.io/)等で行われます。
### テキストを翻訳する
Misskeyは様々な言語に対応しています(i18n -internationalizationの略- と呼ばれます)。元の言語は基本的に日本語ですが、有志によって他の言語へと翻訳されています。
その翻訳作業に加わっていただくことでもMisskeyに貢献できます。
Misskeyは[Crowdinというサービスを使用して翻訳の管理を行っています。](https://crowdin.com/project/misskey)
### 感想を投稿する
不具合報告等だけではなく、Misskeyの良い点、楽しい点といったポジティブな意見もぜひ共有してください。開発の励みになり、それは間接的ですがプロジェクトへの貢献です。
### 寄付をする
Misskeyはビジネスではなく、利用は無料であるため、収益は皆様からの寄付のみです。(インスタンスによっては広告収入を得ているような場合もありますが、それは運営者の収入であり開発者への収入にはなりません)
寄付をしていただければ、今後も開発を続けることが可能になり、プロジェクトへの貢献になります。
寄付は[Patreon](https://www.patreon.com/syuilo)で受け付けています。
## クレジット
Misskeyの開発者や、Misskeyに寄付をしてくださった方の一覧は[こちら](/about-misskey)で見ることができます。

View file

@ -121,14 +121,22 @@ router.get('/api.json', async ctx => {
router.get('/docs.json', async ctx => { router.get('/docs.json', async ctx => {
const lang = ctx.query.lang; const lang = ctx.query.lang;
const query = ctx.query.q;
if (!Object.keys(locales).includes(lang)) { if (!Object.keys(locales).includes(lang)) {
ctx.body = []; ctx.body = [];
return; return;
} }
const paths = glob.sync(__dirname + `/../../../src/docs/${lang}/*.md`); const dirPath = `${__dirname}/../../../src/docs/${lang}`.replace(/\\/g, '/');
const docs: { path: string; title: string; }[] = []; const paths = glob.sync(`${dirPath}/**/*.md`);
const docs: { path: string; title: string; summary: string; }[] = [];
for (const path of paths) { for (const path of paths) {
const md = fs.readFileSync(path, { encoding: 'utf8' }); const md = fs.readFileSync(path, { encoding: 'utf8' });
if (query && query.length > 0) {
// TODO: カタカナをひらがなにして比較するなどしたい
if (!md.includes(query)) continue;
}
const parsed = markdown.parse(md, {}); const parsed = markdown.parse(md, {});
if (parsed.length === 0) return; if (parsed.length === 0) return;
@ -147,9 +155,22 @@ router.get('/docs.json', async ctx => {
} }
} }
const firstParagrapfTokens = [];
while (buf[0].type !== 'paragraph_open') {
buf.shift();
}
buf.shift();
while (buf[0].type as string !== 'paragraph_close') {
const token = buf.shift();
if (token) {
firstParagrapfTokens.push(token);
}
}
docs.push({ docs.push({
path: path.split('/').pop()!.split('.')[0], path: path.replace(`${dirPath}/`, '').split('.')[0],
title: markdown.renderer.render(headingTokens, {}, {}) title: markdown.renderer.render(headingTokens, {}, {}),
summary: markdown.renderer.render(firstParagrapfTokens, {}, {}),
}); });
} }