Compare commits

..

24 Commits

Author SHA1 Message Date
9d29a2e85a 10.38.8 2018-11-05 13:47:57 +09:00
c62a225542 oops 2018-11-05 13:46:46 +09:00
d5d995a3e6 Refactor 2018-11-05 13:38:50 +09:00
cbba03b376 [Client] Fix bug 2018-11-05 13:23:30 +09:00
f84e9c7dc8 絵文字サジェストでスペースを挿入しないように 2018-11-05 12:35:50 +09:00
a22ddb1fb9 ✌️ 2018-11-05 11:58:41 +09:00
0d23ce3d45 Make /api/v1/instance and /api/v1/custom_emojis better (#3118)
* Separate commits

From commit dca110ebaa.

* Re-separate commits

From commit 9719387bee.
2018-11-05 11:57:17 +09:00
712802e682 10.38.7 2018-11-05 11:11:23 +09:00
abe99c3c73 Update locales/ja-JP.yml 2018-11-05 11:10:02 +09:00
d7a3b71028 投稿の最大文字数情報を設定ファイルではなくDBに保存するように 2018-11-05 11:09:05 +09:00
10c434f24a Remove Travis
Closes #3109
2018-11-05 10:52:07 +09:00
fe46c53ea6 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2018-11-05 10:48:51 +09:00
cdd123dfd3 [doc] specify node version 2018-11-05 10:48:40 +09:00
a1a3ee44b5 Implement /api/v1/custom_emojis (#3116) 2018-11-05 10:45:57 +09:00
a86c419f95 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2018-11-05 10:40:15 +09:00
e3ec0ad97e [Client] Improve admin panel usability 2018-11-05 10:40:01 +09:00
75791981ce Fix #3115 2018-11-05 10:34:53 +09:00
e813fe16b9 [API] Better validation of admin/emoji/add 2018-11-05 10:33:49 +09:00
42ac7b954d Improve admin panel usability 2018-11-05 10:32:45 +09:00
c1bbf5dab6 [Client] Fix error 2018-11-05 10:29:57 +09:00
e16dc2a910 Update README.md (#3112) 2018-11-05 01:57:08 +09:00
e236c05d79 10.38.6 2018-11-05 01:43:31 +09:00
454c1e3faf [API] Fix bug 2018-11-05 01:42:41 +09:00
43daf814df [Client] 絵文字登録フォームに便利情報を表示 2018-11-05 01:33:06 +09:00
26 changed files with 204 additions and 107 deletions

View File

@ -167,6 +167,3 @@ drive:
# external: true # external: true
# engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}} # engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}
# timeout: 300000 # timeout: 300000
# Max allowed note text length in charactors
maxNoteTextLength: 1000

View File

@ -1,41 +0,0 @@
# travis file
# https://docs.travis-ci.com/user/customizing-the-build
notifications:
email: false
branches:
except:
- l10n_master
language: node_js
node_js:
- 11.0.0
env:
- CXX=g++-4.8 NODE_ENV=production
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
cache:
directories:
- node_modules
services:
- mongodb
- redis-server
before_script:
- npm install
# 設定ファイルを配置
- cp ./.ci/default.yml ./.config
- cp ./.ci/test.yml ./.config
- travis_wait npm run build

View File

@ -23,5 +23,5 @@ Please use [Crowdin](https://crowdin.com/project/misskey) for localization.
* Test codes are located in `/test`. * Test codes are located in `/test`.
## Continuous integration ## Continuous integration
Misskey uses Travis for automated test. Misskey uses CircleCI for automated test.
Configuration files are located in `/.travis`. Configuration files are located in `/.circleci`.

View File

@ -4,7 +4,6 @@
================================================================ ================================================================
[![CircleCI](https://circleci.com/gh/syuilo/misskey.svg?style=svg)](https://circleci.com/gh/syuilo/misskey) [![CircleCI](https://circleci.com/gh/syuilo/misskey.svg?style=svg)](https://circleci.com/gh/syuilo/misskey)
[![][travis-badge]][travis-link]
[![][dependencies-badge]][dependencies-link] [![][dependencies-badge]][dependencies-link]
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
@ -44,7 +43,7 @@ Easiest way to tell your emotions. Misskey allows you to add various type of rea
<h3 align="left">Interface</h3> <h3 align="left">Interface</h3>
<p align="left"> <p align="left">
No UI fits for everyone. Therefore, Misskey has a highly customizable UI for your taste. You can edit layouts of your timeline, place selectable widgets you can easily move and create your unique home as this place will be your home. Highly customizable UI for your taste. We understand no UI fits for everyone. You can edit layouts of your timeline, place selectable widgets you can easily move and create your unique home as this place will be your home.
</p> </p>
--- ---
@ -124,8 +123,6 @@ Misskey is an open-source software licensed under the [GNU AGPLv3](LICENSE).
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html [agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.en.html
[agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square [agpl-3.0-badge]: https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square
[travis-link]: https://travis-ci.org/syuilo/misskey
[travis-badge]: http://img.shields.io/travis/syuilo/misskey/master.svg?style=flat-square
[dependencies-link]: https://david-dm.org/syuilo/misskey [dependencies-link]: https://david-dm.org/syuilo/misskey
[dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square [dependencies-badge]: https://img.shields.io/david/syuilo/misskey.svg?style=flat-square

View File

@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
Please install and setup these softwares: Please install and setup these softwares:
#### Dependencies :package: #### Dependencies :package:
* **[Node.js](https://nodejs.org/en/)** * **[Node.js](https://nodejs.org/en/)** >= 10.0.0
* **[MongoDB](https://www.mongodb.com/)** >= 3.6 * **[MongoDB](https://www.mongodb.com/)** >= 3.6
##### Optional ##### Optional

View File

@ -22,7 +22,7 @@ adduser --disabled-password --disabled-login misskey
これらのソフトウェアをインストール・設定してください: これらのソフトウェアをインストール・設定してください:
#### 依存関係 :package: #### 依存関係 :package:
* **[Node.js](https://nodejs.org/en/)** * **[Node.js](https://nodejs.org/en/)** (10.0.0以上)
* **[MongoDB](https://www.mongodb.com/)** (3.6以上) * **[MongoDB](https://www.mongodb.com/)** (3.6以上)
##### オプション ##### オプション

View File

@ -1077,10 +1077,12 @@ admin/views/instance.vue:
instance-name: "インスタンス名" instance-name: "インスタンス名"
instance-description: "インスタンスの紹介" instance-description: "インスタンスの紹介"
banner-url: "バナー画像URL" banner-url: "バナー画像URL"
disableRegistration: "ユーザー登録の受付を停止する" max-note-text-length: "投稿の最大文字数"
disableLocalTimeline: "ローカルタイムラインを無効にする" disable-registration: "ユーザー登録の受付を停止する"
disable-local-timeline: "ローカルタイムラインを無効にする"
invite: "招待" invite: "招待"
save: "保存" save: "保存"
saved: "保存しました"
admin/views/charts.vue: admin/views/charts.vue:
title: "チャート" title: "チャート"
@ -1131,10 +1133,16 @@ admin/views/emoji.vue:
aliases-desc: "スペースで区切って複数設定できます。" aliases-desc: "スペースで区切って複数設定できます。"
url: "絵文字画像URL" url: "絵文字画像URL"
add: "追加" add: "追加"
info: "50KB以下のPNG画像をおすすめします。"
added: "絵文字を登録しました"
emojis: emojis:
title: "絵文字一覧" title: "絵文字一覧"
update: "更新" update: "更新"
remove: "削除" remove: "削除"
updated: "更新しました"
remove-emoji:
are-you-sure: "「$1」を削除しますか"
removed: "削除しました"
admin/views/announcements.vue: admin/views/announcements.vue:
announcements: "お知らせ" announcements: "お知らせ"
@ -1143,6 +1151,10 @@ admin/views/announcements.vue:
add: "追加" add: "追加"
title: "タイトル" title: "タイトル"
text: "内容" text: "内容"
saved: "保存しました"
_remove:
are-you-sure: "「$1」を削除しますか"
removed: "削除しました"
admin/views/hashtags.vue: admin/views/hashtags.vue:
hided-tags: "Hidden Tags" hided-tags: "Hidden Tags"

View File

@ -1,8 +1,8 @@
{ {
"name": "misskey", "name": "misskey",
"author": "syuilo <i@syuilo.com>", "author": "syuilo <i@syuilo.com>",
"version": "10.38.5", "version": "10.38.8",
"clientVersion": "1.0.11513", "clientVersion": "1.0.11537",
"codename": "nighthike", "codename": "nighthike",
"main": "./built/index.js", "main": "./built/index.js",
"private": true, "private": true,

View File

@ -10,7 +10,7 @@
<span>%i18n:@text%</span> <span>%i18n:@text%</span>
</ui-textarea> </ui-textarea>
<ui-horizon-group> <ui-horizon-group>
<ui-button @click="save">%fa:save R% %i18n:@save%</ui-button> <ui-button @click="save()">%fa:save R% %i18n:@save%</ui-button>
<ui-button @click="remove(i)">%fa:trash-alt R% %i18n:@remove%</ui-button> <ui-button @click="remove(i)">%fa:trash-alt R% %i18n:@remove%</ui-button>
</ui-horizon-group> </ui-horizon-group>
</section> </section>
@ -46,17 +46,36 @@ export default Vue.extend({
}, },
remove(i) { remove(i) {
this.announcements = this.announcements.filter((_, j) => j !== i); this.$swal({
this.save(); type: 'warning',
text: '%i18n:@_remove.are-you-sure%'.replace('$1', this.announcements.find((_, j) => j == i).title),
showCancelButton: true
}).then(res => {
if (!res.value) return;
this.announcements = this.announcements.filter((_, j) => j !== i);
this.save(true);
this.$swal({
type: 'success',
text: '%i18n:@_remove.removed%'
});
});
}, },
save() { save(silent) {
(this as any).api('admin/update-meta', { (this as any).api('admin/update-meta', {
broadcasts: this.announcements broadcasts: this.announcements
}).then(() => { }).then(() => {
//(this as any).os.apis.dialog({ text: `Saved` }); if (!silent) {
this.$swal({
type: 'success',
text: '%i18n:@saved%'
});
}
}).catch(e => { }).catch(e => {
//(this as any).os.apis.dialog({ text: `Failed ${e}` }); this.$swal({
type: 'error',
text: e
});
}); });
} }
} }

View File

@ -16,6 +16,7 @@
<ui-input v-model="url"> <ui-input v-model="url">
<span>%i18n:@add-emoji.url%</span> <span>%i18n:@add-emoji.url%</span>
</ui-input> </ui-input>
<ui-info>%i18n:@add-emoji.info%</ui-info>
<ui-button @click="add">%i18n:@add-emoji.add%</ui-button> <ui-button @click="add">%i18n:@add-emoji.add%</ui-button>
</section> </section>
</ui-card> </ui-card>
@ -66,17 +67,24 @@ export default Vue.extend({
(this as any).api('admin/emoji/add', { (this as any).api('admin/emoji/add', {
name: this.name, name: this.name,
url: this.url, url: this.url,
aliases: this.aliases.split(' ') aliases: this.aliases.split(' ').filter(x => x.length > 0)
}).then(() => { }).then(() => {
//(this as any).os.apis.dialog({ text: `Added` }); this.$swal({
type: 'success',
text: '%i18n:@add-emoji.added%'
});
this.fetchEmojis(); this.fetchEmojis();
}).catch(e => { }).catch(e => {
//(this as any).os.apis.dialog({ text: `Failed ${e}` }); this.$swal({
type: 'error',
text: e
});
}); });
}, },
fetchEmojis() { fetchEmojis() {
(this as any).api('admin/emoji/list').then(emojis => { (this as any).api('admin/emoji/list').then(emojis => {
emojis.reverse();
emojis.forEach(e => e.aliases = (e.aliases || []).join(' ')); emojis.forEach(e => e.aliases = (e.aliases || []).join(' '));
this.emojis = emojis; this.emojis = emojis;
}); });
@ -87,22 +95,42 @@ export default Vue.extend({
id: emoji.id, id: emoji.id,
name: emoji.name, name: emoji.name,
url: emoji.url, url: emoji.url,
aliases: emoji.aliases.split(' ') aliases: emoji.aliases.split(' ').filter(x => x.length > 0)
}).then(() => { }).then(() => {
//(this as any).os.apis.dialog({ text: `Updated` }); this.$swal({
type: 'success',
text: '%i18n:@updated%'
});
}).catch(e => { }).catch(e => {
//(this as any).os.apis.dialog({ text: `Failed ${e}` }); this.$swal({
type: 'error',
text: e
});
}); });
}, },
removeEmoji(emoji) { removeEmoji(emoji) {
(this as any).api('admin/emoji/remove', { this.$swal({
id: emoji.id type: 'warning',
}).then(() => { text: '%i18n:@remove-emoji.are-you-sure%'.replace('$1', emoji.name),
//(this as any).os.apis.dialog({ text: `Removed` }); showCancelButton: true
this.fetchEmojis(); }).then(res => {
}).catch(e => { if (!res.value) return;
//(this as any).os.apis.dialog({ text: `Failed ${e}` });
(this as any).api('admin/emoji/remove', {
id: emoji.id
}).then(() => {
this.$swal({
type: 'success',
text: '%i18n:@remove-emoji.removed%'
});
this.fetchEmojis();
}).catch(e => {
this.$swal({
type: 'error',
text: e
});
});
}); });
} }
} }

View File

@ -6,6 +6,7 @@
<ui-input v-model="name">%i18n:@instance-name%</ui-input> <ui-input v-model="name">%i18n:@instance-name%</ui-input>
<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea> <ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
<ui-input v-model="bannerUrl">%i18n:@banner-url%</ui-input> <ui-input v-model="bannerUrl">%i18n:@banner-url%</ui-input>
<ui-input v-model="maxNoteTextLength">%i18n:@max-note-text-length%</ui-input>
<ui-button @click="updateMeta">%i18n:@save%</ui-button> <ui-button @click="updateMeta">%i18n:@save%</ui-button>
</section> </section>
</ui-card> </ui-card>
@ -39,6 +40,7 @@ export default Vue.extend({
bannerUrl: null, bannerUrl: null,
name: null, name: null,
description: null, description: null,
maxNoteTextLength: null,
inviteCode: null, inviteCode: null,
}; };
}, },
@ -48,6 +50,7 @@ export default Vue.extend({
this.bannerUrl = meta.bannerUrl; this.bannerUrl = meta.bannerUrl;
this.name = meta.name; this.name = meta.name;
this.description = meta.description; this.description = meta.description;
this.maxNoteTextLength = meta.maxNoteTextLength;
}); });
}, },
@ -56,7 +59,10 @@ export default Vue.extend({
(this as any).api('admin/invite').then(x => { (this as any).api('admin/invite').then(x => {
this.inviteCode = x.code; this.inviteCode = x.code;
}).catch(e => { }).catch(e => {
//(this as any).os.apis.dialog({ text: `Failed ${e}` }); this.$swal({
type: 'error',
text: e
});
}); });
}, },
@ -66,11 +72,18 @@ export default Vue.extend({
disableLocalTimeline: this.disableLocalTimeline, disableLocalTimeline: this.disableLocalTimeline,
bannerUrl: this.bannerUrl, bannerUrl: this.bannerUrl,
name: this.name, name: this.name,
description: this.description description: this.description,
maxNoteTextLength: parseInt(this.maxNoteTextLength, 10)
}).then(() => { }).then(() => {
//(this as any).os.apis.dialog({ text: `Saved` }); this.$swal({
type: 'success',
text: '%i18n:@saved%'
});
}).catch(e => { }).catch(e => {
//(this as any).os.apis.dialog({ text: `Failed ${e}` }); this.$swal({
type: 'error',
text: e
});
}); });
} }
} }

View File

@ -12,7 +12,11 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
export default Vue.extend({ export default Vue.extend({
inject: ['horizonGrouped'], inject: {
horizonGrouped: {
default: false
}
},
props: { props: {
type: { type: {
type: String, type: String,

View File

@ -41,7 +41,11 @@ import Vue from 'vue';
const getPasswordStrength = require('syuilo-password-strength'); const getPasswordStrength = require('syuilo-password-strength');
export default Vue.extend({ export default Vue.extend({
inject: ['horizonGrouped'], inject: {
horizonGrouped: {
default: false
}
},
props: { props: {
value: { value: {
required: false required: false

View File

@ -222,8 +222,6 @@ class Autocomplete {
const trimmedBefore = before.substring(0, before.lastIndexOf(':')); const trimmedBefore = before.substring(0, before.lastIndexOf(':'));
const after = source.substr(caret); const after = source.substr(caret);
if (value.startsWith(':')) value = value + ' ';
// 挿入 // 挿入
this.text = trimmedBefore + value + after; this.text = trimmedBefore + value + after;

View File

@ -49,8 +49,6 @@ export default function load() {
if (config.localDriveCapacityMb == null) config.localDriveCapacityMb = 256; if (config.localDriveCapacityMb == null) config.localDriveCapacityMb = 256;
if (config.remoteDriveCapacityMb == null) config.remoteDriveCapacityMb = 8; if (config.remoteDriveCapacityMb == null) config.remoteDriveCapacityMb = 8;
if (config.maxNoteTextLength == null) config.maxNoteTextLength = 1000;
return Object.assign(config, mixin); return Object.assign(config, mixin);
} }

View File

@ -107,8 +107,6 @@ export type Source = {
engine: string; engine: string;
timeout: number; timeout: number;
}; };
maxNoteTextLength?: number;
}; };
/** /**

View File

@ -43,4 +43,9 @@ export type IMeta = {
disableLocalTimeline?: boolean; disableLocalTimeline?: boolean;
hidedTags?: string[]; hidedTags?: string[];
bannerUrl?: string; bannerUrl?: string;
/**
* Max allowed note text length in charactors
*/
maxNoteTextLength?: number;
}; };

View File

@ -11,7 +11,6 @@ import Reaction from './note-reaction';
import { packMany as packFileMany, IDriveFile } from './drive-file'; import { packMany as packFileMany, IDriveFile } from './drive-file';
import Favorite from './favorite'; import Favorite from './favorite';
import Following from './following'; import Following from './following';
import config from '../config';
import Emoji from './emoji'; import Emoji from './emoji';
const Note = db.get<INote>('notes'); const Note = db.get<INote>('notes');
@ -27,10 +26,6 @@ Note.createIndex({ createdAt: -1 });
Note.createIndex({ score: -1 }, { sparse: true }); Note.createIndex({ score: -1 }, { sparse: true });
export default Note; export default Note;
export function isValidText(text: string): boolean {
return length(text.trim()) <= config.maxNoteTextLength && text.trim() != '';
}
export function isValidCw(text: string): boolean { export function isValidCw(text: string): boolean {
return length(text.trim()) <= 100; return length(text.trim()) <= 100;
} }

View File

@ -12,15 +12,15 @@ export const meta = {
params: { params: {
name: { name: {
validator: $.str validator: $.str.min(1)
}, },
url: { url: {
validator: $.str validator: $.str.min(1)
}, },
aliases: { aliases: {
validator: $.arr($.str).optional, validator: $.arr($.str.min(1)).optional,
default: [] as string[] default: [] as string[]
} }
} }

View File

@ -59,6 +59,13 @@ export const meta = {
'ja-JP': 'インスタンスの紹介文' 'ja-JP': 'インスタンスの紹介文'
} }
}, },
maxNoteTextLength: {
validator: $.num.optional.min(1),
desc: {
'ja-JP': '投稿の最大文字数'
}
}
} }
}; };
@ -93,6 +100,10 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
set.description = ps.description; set.description = ps.description;
} }
if (ps.maxNoteTextLength) {
set.maxNoteTextLength = ps.maxNoteTextLength;
}
await Meta.update({}, { await Meta.update({}, {
$set: set $set: set
}, { upsert: true }); }, { upsert: true });

View File

@ -26,7 +26,7 @@ export const meta = {
export default define(meta, (ps, user) => new Promise(async (res, rej) => { export default define(meta, (ps, user) => new Promise(async (res, rej) => {
const folders = await DriveFolder const folders = await DriveFolder
.find({ .find({
name: name, name: ps.name,
userId: user._id, userId: user._id,
parentId: ps.parentId parentId: ps.parentId
}); });

View File

@ -62,7 +62,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
swPublickey: config.sw ? config.sw.public_key : null, swPublickey: config.sw ? config.sw.public_key : null,
hidedTags: (me && me.isAdmin) ? met.hidedTags : undefined, hidedTags: (me && me.isAdmin) ? met.hidedTags : undefined,
bannerUrl: met.bannerUrl, bannerUrl: met.bannerUrl,
maxNoteTextLength: config.maxNoteTextLength, maxNoteTextLength: met.maxNoteTextLength || 1000,
emojis: emojis, emojis: emojis,

View File

@ -1,10 +1,20 @@
import $ from 'cafy'; import ID, { transform, transformMany } from '../../../../misc/cafy-id'; import $ from 'cafy'; import ID, { transform, transformMany } from '../../../../misc/cafy-id';
const ms = require('ms'); const ms = require('ms');
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note'; import { length } from 'stringz';
import Note, { INote, isValidCw, pack } from '../../../../models/note';
import User, { IUser } from '../../../../models/user'; import User, { IUser } from '../../../../models/user';
import DriveFile, { IDriveFile } from '../../../../models/drive-file'; import DriveFile, { IDriveFile } from '../../../../models/drive-file';
import create from '../../../../services/note/create'; import create from '../../../../services/note/create';
import define from '../../define'; import define from '../../define';
import Meta from '../../../../models/meta';
let maxNoteTextLength = 1000;
setInterval(() => {
Meta.findOne({}).then(m => {
if (m.maxNoteTextLength) maxNoteTextLength = m.maxNoteTextLength;
});
}, 3000);
export const meta = { export const meta = {
stability: 'stable', stability: 'stable',
@ -40,7 +50,9 @@ export const meta = {
}, },
text: { text: {
validator: $.str.optional.nullable.pipe(isValidText), validator: $.str.optional.nullable.pipe(text =>
length(text.trim()) <= maxNoteTextLength && text.trim() != ''
),
default: null as any, default: null as any,
desc: { desc: {
'ja-JP': '投稿内容' 'ja-JP': '投稿内容'

View File

@ -0,0 +1,35 @@
export type IMastodonEmoji = {
shortcode: string,
url: string,
static_url: string,
visible_in_picker: boolean
};
export async function toMastodonEmojis(emoji: any): Promise<IMastodonEmoji[]> {
return [{
shortcode: emoji.name,
url: emoji.url,
static_url: emoji.url, // TODO: Implement ensuring static emoji
visible_in_picker: true
}, ...(emoji.aliases as string[] || []).map(x => ({
shortcode: x,
url: emoji.url,
static_url: emoji.url,
visible_in_picker: true
}))];
}
export function toMisskeyEmojiSync(emoji: IMastodonEmoji) {
return {
name: emoji.shortcode,
url: emoji.url
};
}
export function toMisskeyEmojiWithAliasesSync(emoji: IMastodonEmoji, ...aliases: string[]) {
return {
name: emoji.shortcode,
aliases,
url: emoji.url
};
}

View File

@ -1,15 +1,22 @@
import * as Router from 'koa-router'; import * as Router from 'koa-router';
import User from '../../models/user'; import User from '../../../models/user';
import { toASCII } from 'punycode'; import { toASCII } from 'punycode';
import config from '../../config'; import config from '../../../config';
import Meta from '../../models/meta'; import Meta from '../../../models/meta';
import { ObjectID } from 'bson'; import { ObjectID } from 'bson';
const pkg = require('../../../package.json'); import Emoji from '../../../models/emoji';
import { toMastodonEmojis } from './emoji';
const pkg = require('../../../../package.json');
// Init router // Init router
const router = new Router(); const router = new Router();
router.get('/v1/custom_emojis', async ctx => ctx.body = {}); router.get('/v1/custom_emojis', async ctx => ctx.body =
(await Emoji.find({ host: null }, {
fields: {
_id: false
}
})).map(x => toMastodonEmojis(x)));
router.get('/v1/instance', async ctx => { // TODO: This is a temporary implementation. Consider creating helper methods! router.get('/v1/instance', async ctx => { // TODO: This is a temporary implementation. Consider creating helper methods!
const meta = await Meta.findOne() || {}; const meta = await Meta.findOne() || {};
@ -34,6 +41,11 @@ router.get('/v1/instance', async ctx => { // TODO: This is a temporary implement
notesCount: 0 notesCount: 0
}; };
const acct = maintainer.host ? `${maintainer.username}@${maintainer.host}` : maintainer.username; const acct = maintainer.host ? `${maintainer.username}@${maintainer.host}` : maintainer.username;
const emojis = (await Emoji.find({ host: null }, {
fields: {
_id: false
}
})).map(toMastodonEmojis);
ctx.body = { ctx.body = {
uri: config.hostname, uri: config.hostname,
@ -73,7 +85,7 @@ router.get('/v1/instance', async ctx => { // TODO: This is a temporary implement
followers_count: maintainer.followersCount, followers_count: maintainer.followersCount,
following_count: maintainer.followingCount, following_count: maintainer.followingCount,
statuses_count: maintainer.notesCount, statuses_count: maintainer.notesCount,
emojis: [], emojis: emojis,
moved: null, moved: null,
fields: null fields: null
} }

View File

@ -109,7 +109,7 @@ if (!config.github || !redis) {
} }
const params = { const params = {
redirect_uri: `${config.url}:8089/api/gh/cb`, redirect_uri: `${config.url}/api/gh/cb`,
scope: ['read:user'], scope: ['read:user'],
state: uuid() state: uuid()
}; };
@ -122,7 +122,7 @@ if (!config.github || !redis) {
const sessid = uuid(); const sessid = uuid();
const params = { const params = {
redirect_uri: `${config.url}:8089/api/gh/cb`, redirect_uri: `${config.url}/api/gh/cb`,
scope: ['read:user'], scope: ['read:user'],
state: uuid() state: uuid()
}; };