summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-04-29 04:30:51 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-04-29 04:30:51 +0900
commitec4ed8fb2d87f02ff67cfbf6b9f8e2975bc49e4f (patch)
treebaa6c0515bf06bc1f7f766bbb3c0afb9a2ebb409 /src
parent:v: (diff)
downloadsharkey-ec4ed8fb2d87f02ff67cfbf6b9f8e2975bc49e4f.tar.gz
sharkey-ec4ed8fb2d87f02ff67cfbf6b9f8e2975bc49e4f.tar.bz2
sharkey-ec4ed8fb2d87f02ff67cfbf6b9f8e2975bc49e4f.zip
wip
Diffstat (limited to 'src')
-rw-r--r--src/client/app/common/views/components/visibility-chooser.vue6
-rw-r--r--src/models/note.ts53
-rw-r--r--src/server/api/endpoints/notes/create.ts16
-rw-r--r--src/services/note/create.ts6
4 files changed, 74 insertions, 7 deletions
diff --git a/src/client/app/common/views/components/visibility-chooser.vue b/src/client/app/common/views/components/visibility-chooser.vue
index b6a8e9b661..dd36d32e74 100644
--- a/src/client/app/common/views/components/visibility-chooser.vue
+++ b/src/client/app/common/views/components/visibility-chooser.vue
@@ -22,11 +22,11 @@
<span>自分のフォロワーにのみ公開</span>
</div>
</div>
- <div @click="choose('mentioned')" :class="{ active: v == 'mentioned' }">
+ <div @click="choose('specified')" :class="{ active: v == 'specified' }">
<div>%fa:envelope%</div>
<div>
- <span>メンション</span>
- <span>言及したユーザーにのみ公開</span>
+ <span>ダイレクト</span>
+ <span>指定したユーザーにのみ公開</span>
</div>
</div>
<div @click="choose('private')" :class="{ active: v == 'private' }">
diff --git a/src/models/note.ts b/src/models/note.ts
index 2f95cbfd65..5c4ac86353 100644
--- a/src/models/note.ts
+++ b/src/models/note.ts
@@ -12,6 +12,7 @@ import NoteWatching, { deleteNoteWatching } from './note-watching';
import NoteReaction from './note-reaction';
import Favorite, { deleteFavorite } from './favorite';
import Notification, { deleteNotification } from './notification';
+import Following from './following';
const Note = db.get<INote>('notes');
@@ -51,10 +52,12 @@ export type INote = {
* public ... 公開
* home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す
* followers ... フォロワーのみ
- * mentioned ... 言及したユーザーのみ
+ * specified ... visibleUserIds で指定したユーザーのみ
* private ... 自分のみ
*/
- visibility: 'public' | 'home' | 'followers' | 'mentioned' | 'private';
+ visibility: 'public' | 'home' | 'followers' | 'specified' | 'private';
+
+ visibleUserIds: mongo.ObjectID[];
geo: {
coordinates: number[];
@@ -190,6 +193,52 @@ export const pack = async (
if (!_note) throw `invalid note arg ${note}`;
+ let hide = false;
+
+ // visibility が private かつ投稿者のIDが自分のIDではなかったら非表示
+ if (_note.visibility == 'private' && (meId == null || !meId.equals(_note.userId))) {
+ hide = true;
+ }
+
+ // visibility が specified かつ自分が指定されていなかったら非表示
+ if (_note.visibility == 'specified') {
+ if (meId == null) {
+ hide = true;
+ } else if (meId.equals(_note.userId)) {
+ hide = false;
+ } else {
+ // 指定されているかどうか
+ const specified = _note.visibleUserIds.test(id => id.equals(meId));
+
+ if (specified) {
+ hide = false;
+ } else {
+ hide = true;
+ }
+ }
+ }
+
+ // visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示
+ if (_note.visibility == 'followers') {
+ if (meId == null) {
+ hide = true;
+ } else if (meId.equals(_note.userId)) {
+ hide = false;
+ } else {
+ // フォロワーかどうか
+ const following = await Following.findOne({
+ followeeId: _note.userId,
+ followerId: meId
+ });
+
+ if (following == null) {
+ hide = true;
+ } else {
+ hide = false;
+ }
+ }
+ }
+
const id = _note._id;
// Rename _id to id
diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts
index af4f365226..52c6068fd0 100644
--- a/src/server/api/endpoints/notes/create.ts
+++ b/src/server/api/endpoints/notes/create.ts
@@ -3,7 +3,7 @@
*/
import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
+import User, { ILocalUser } from '../../../../models/user';
import Channel, { IChannel } from '../../../../models/channel';
import DriveFile from '../../../../models/drive-file';
import create from '../../../../services/note/create';
@@ -14,9 +14,20 @@ import { IApp } from '../../../../models/app';
*/
module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'visibility' parameter
- const [visibility = 'public', visibilityErr] = $(params.visibility).optional.string().or(['public', 'unlisted', 'private', 'direct']).get();
+ const [visibility = 'public', visibilityErr] = $(params.visibility).optional.string().or(['public', 'home', 'followers', 'specified', 'private']).get();
if (visibilityErr) return rej('invalid visibility');
+ // Get 'visibleUserIds' parameter
+ const [visibleUserIds, visibleUserIdsErr] = $(params.visibleUserIds).optional.array($().type(ID)).unique().min(1).get();
+ if (visibleUserIdsErr) return rej('invalid visibleUserIds');
+
+ let visibleUsers = [];
+ if (visibleUserIds !== undefined) {
+ visibleUsers = await Promise.all(visibleUserIds.map(id => User.findOne({
+ _id: id
+ })));
+ }
+
// Get 'text' parameter
const [text = null, textErr] = $(params.text).optional.nullable.string().pipe(isValidText).get();
if (textErr) return rej('invalid text');
@@ -191,6 +202,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
app,
viaMobile,
visibility,
+ visibleUsers,
geo
});
diff --git a/src/services/note/create.ts b/src/services/note/create.ts
index 4808edfda4..e8070595cd 100644
--- a/src/services/note/create.ts
+++ b/src/services/note/create.ts
@@ -30,6 +30,7 @@ export default async (user: IUser, data: {
tags?: string[];
cw?: string;
visibility?: string;
+ visibleUsers?: IUser[];
uri?: string;
app?: IApp;
}, silent = false) => new Promise<INote>(async (res, rej) => {
@@ -57,6 +58,10 @@ export default async (user: IUser, data: {
});
}
+ if (data.visibleUsers) {
+ data.visibleUsers = data.visibleUsers.filter(x => x != null);
+ }
+
const insert: any = {
createdAt: data.createdAt,
mediaIds: data.media ? data.media.map(file => file._id) : [],
@@ -71,6 +76,7 @@ export default async (user: IUser, data: {
geo: data.geo || null,
appId: data.app ? data.app._id : null,
visibility: data.visibility,
+ visibleUserIds: data.visibleUsers ? data.visibleUsers.map(u => u._id) : [],
// 以下非正規化データ
_reply: data.reply ? { userId: data.reply.userId } : null,