This commit is contained in:
syuilo 2018-04-29 04:30:51 +09:00
parent 34786130b7
commit ec4ed8fb2d
4 changed files with 74 additions and 7 deletions

View File

@ -22,11 +22,11 @@
<span>自分のフォロワーにのみ公開</span> <span>自分のフォロワーにのみ公開</span>
</div> </div>
</div> </div>
<div @click="choose('mentioned')" :class="{ active: v == 'mentioned' }"> <div @click="choose('specified')" :class="{ active: v == 'specified' }">
<div>%fa:envelope%</div> <div>%fa:envelope%</div>
<div> <div>
<span>メンション</span> <span>ダイレクト</span>
<span>言及したユーザーにのみ公開</span> <span>指定したユーザーにのみ公開</span>
</div> </div>
</div> </div>
<div @click="choose('private')" :class="{ active: v == 'private' }"> <div @click="choose('private')" :class="{ active: v == 'private' }">

View File

@ -12,6 +12,7 @@ import NoteWatching, { deleteNoteWatching } from './note-watching';
import NoteReaction from './note-reaction'; import NoteReaction from './note-reaction';
import Favorite, { deleteFavorite } from './favorite'; import Favorite, { deleteFavorite } from './favorite';
import Notification, { deleteNotification } from './notification'; import Notification, { deleteNotification } from './notification';
import Following from './following';
const Note = db.get<INote>('notes'); const Note = db.get<INote>('notes');
@ -51,10 +52,12 @@ export type INote = {
* public ... * public ...
* home ... () * home ... ()
* followers ... * followers ...
* mentioned ... * specified ... visibleUserIds
* private ... * private ...
*/ */
visibility: 'public' | 'home' | 'followers' | 'mentioned' | 'private'; visibility: 'public' | 'home' | 'followers' | 'specified' | 'private';
visibleUserIds: mongo.ObjectID[];
geo: { geo: {
coordinates: number[]; coordinates: number[];
@ -190,6 +193,52 @@ export const pack = async (
if (!_note) throw `invalid note arg ${note}`; 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; const id = _note._id;
// Rename _id to id // Rename _id to id

View File

@ -3,7 +3,7 @@
*/ */
import $ from 'cafy'; import ID from '../../../../cafy-id'; import $ from 'cafy'; import ID from '../../../../cafy-id';
import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note'; 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 Channel, { IChannel } from '../../../../models/channel';
import DriveFile from '../../../../models/drive-file'; import DriveFile from '../../../../models/drive-file';
import create from '../../../../services/note/create'; 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) => { module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
// Get 'visibility' parameter // 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'); 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 // Get 'text' parameter
const [text = null, textErr] = $(params.text).optional.nullable.string().pipe(isValidText).get(); const [text = null, textErr] = $(params.text).optional.nullable.string().pipe(isValidText).get();
if (textErr) return rej('invalid text'); if (textErr) return rej('invalid text');
@ -191,6 +202,7 @@ module.exports = (params, user: ILocalUser, app: IApp) => new Promise(async (res
app, app,
viaMobile, viaMobile,
visibility, visibility,
visibleUsers,
geo geo
}); });

View File

@ -30,6 +30,7 @@ export default async (user: IUser, data: {
tags?: string[]; tags?: string[];
cw?: string; cw?: string;
visibility?: string; visibility?: string;
visibleUsers?: IUser[];
uri?: string; uri?: string;
app?: IApp; app?: IApp;
}, silent = false) => new Promise<INote>(async (res, rej) => { }, 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 = { const insert: any = {
createdAt: data.createdAt, createdAt: data.createdAt,
mediaIds: data.media ? data.media.map(file => file._id) : [], mediaIds: data.media ? data.media.map(file => file._id) : [],
@ -71,6 +76,7 @@ export default async (user: IUser, data: {
geo: data.geo || null, geo: data.geo || null,
appId: data.app ? data.app._id : null, appId: data.app ? data.app._id : null,
visibility: data.visibility, visibility: data.visibility,
visibleUserIds: data.visibleUsers ? data.visibleUsers.map(u => u._id) : [],
// 以下非正規化データ // 以下非正規化データ
_reply: data.reply ? { userId: data.reply.userId } : null, _reply: data.reply ? { userId: data.reply.userId } : null,