Compare commits

..

26 Commits

Author SHA1 Message Date
syuilo
2b3687b3cb 10.36.1 2018-11-01 09:35:24 +09:00
syuilo
5d61c7c691 Refactor and use original image for banner 2018-11-01 09:30:51 +09:00
syuilo
1bb266e7c7 Update package-lock.json 2018-11-01 09:19:31 +09:00
syuilo
1fca8d322c Clean up 2018-11-01 09:19:22 +09:00
syuilo
325cd03a59 Improve performance 2018-11-01 09:08:00 +09:00
syuilo
2f7e6baa05 Clean up 2018-11-01 09:02:54 +09:00
syuilo
d252e066fe Improve performance 2018-11-01 09:00:18 +09:00
dependabot[bot]
fe7bd9ab3c Bump typescript-eslint-parser from 20.0.0 to 20.1.1 (#3057)
Bumps [typescript-eslint-parser](https://github.com/eslint/typescript-eslint-parser) from 20.0.0 to 20.1.1.
- [Release notes](https://github.com/eslint/typescript-eslint-parser/releases)
- [Changelog](https://github.com/eslint/typescript-eslint-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/typescript-eslint-parser/compare/v20.0.0...v20.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-01 08:24:13 +09:00
dependabot[bot]
84e3f41305 Bump ts-loader from 5.2.2 to 5.3.0 (#3055)
Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 5.2.2 to 5.3.0.
- [Release notes](https://github.com/TypeStrong/ts-loader/releases)
- [Changelog](https://github.com/TypeStrong/ts-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/ts-loader/compare/v5.2.2...v5.3.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-01 08:24:05 +09:00
dependabot[bot]
3e8cccad0d Bump jsdom from 12.2.0 to 13.0.0 (#3058)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 12.2.0 to 13.0.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/12.2.0...13.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-01 08:23:38 +09:00
Acid Chicken (硫酸鶏)
a2b94d67f7 Update README.md [AUTOGEN] (#3060) 2018-11-01 08:23:11 +09:00
dependabot[bot]
6ab61e73b0 Bump apexcharts from 2.1.6 to 2.1.9 (#3056)
Bumps [apexcharts](https://github.com/apexcharts/apexcharts.js) from 2.1.6 to 2.1.9.
- [Release notes](https://github.com/apexcharts/apexcharts.js/releases)
- [Changelog](https://github.com/apexcharts/apexcharts.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/apexcharts/apexcharts.js/compare/v2.1.6...v2.1.9)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-01 08:22:53 +09:00
Acid Chicken (硫酸鶏)
051c6973af Update README.md [AUTOGEN] (#3059) 2018-11-01 08:20:56 +09:00
syuilo
806a49ec3d 10.36.0 2018-11-01 00:12:13 +09:00
syuilo
3829fe128a Update src/server/api/endpoints/users/relation.ts 2018-11-01 00:11:52 +09:00
syuilo
649177985d [API] Implement users/relation 2018-11-01 00:11:21 +09:00
syuilo
c15148b23c [API] Include detailed user information for block/mute response 2018-10-31 23:34:35 +09:00
syuilo
261a3f5d91 Better rate limitting 2018-10-31 23:03:14 +09:00
syuilo
256ba78ba5 Fix 2018-10-31 22:55:17 +09:00
syuilo
04aff8866e [MFM] Better hashtag detection 2018-10-31 22:38:05 +09:00
syuilo
1a51b98700 Refactor 2018-10-31 22:35:02 +09:00
syuilo
f64100226d Revert "Clean up"
This reverts commit 8948a0d3a4.
2018-10-31 22:10:25 +09:00
syuilo
b7805e48a6 Merge branch 'develop' of https://github.com/syuilo/misskey into develop 2018-10-31 22:08:27 +09:00
syuilo
0d9556620d Update package-lock.json 2018-10-31 22:08:19 +09:00
Acid Chicken (硫酸鶏)
a51828a7a2 Update test.yml (#3052) 2018-10-31 22:07:26 +09:00
Acid Chicken (硫酸鶏)
7e2009f408 Update config.yml (#3051) 2018-10-31 22:00:21 +09:00
22 changed files with 293 additions and 407 deletions

View File

@@ -9,6 +9,7 @@ mongodb:
db: test-misskey
user: admin
pass: ''
# __REDIS__
redis:
host: localhost
port: 6379

View File

@@ -97,14 +97,22 @@ jobs:
- run:
name: Build
command: |
docker build .
docker build . | tee docker.log
tail -n 1 docker.log | read __Successfully __built tag
- when:
condition: <<parameters.with_deploy>>
steps:
- run:
name: Deploy
command: |
docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD && docker push misskey/misskey
if [ "$DOCKERHUB_USERNAME$DOCKERHUB_PASSWORD" ]
then
docker tag $tag misskey/misskey
docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
docker push misskey/misskey
else
echo -e '\033[0;33mAborted deploying to Docker Hub\033[0;39m'
fi
workflows:
version: 2

View File

@@ -88,7 +88,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
</tr></table>
<table><tr>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/2?token-time=2145916800&token-hash=zElv7ZcPL3viGsXbNG_KWiKrbV0vvw1gk0panx8DJoo%3D" alt="Naoki Kosaka"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3?token-time=2145916800&token-hash=qsdn0-e6yLaLI6hUX9JAkyTR6a5UdnSp7T1foniBvGQ%3D" alt="YUKIMOCHI"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/2?token-time=2145916800&token-hash=iUXOQzRyJDv3PJxwS7Mjwg1459dzh2trOq6NFtXu_OM%3D" alt="Acid Chicken"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=UERBN4OyP7Nh5XwwdDg0N0IE5cD6_qUQMO81Z5Wizso%3D" alt="Hiratake"></td>
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/10789744/97175095d8f04c0f86225ff47cb98d40/1?token-time=2145916800&token-hash=P4BIzCX2I1CkEP66ottfhsC8Wr6BUSamjA-vq3pLqFI%3D" alt="Naoki Hirayama"></td>
@@ -98,7 +98,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=tMosUojzUYJCH_3t--tvYA-SMCyrS__hzSndyaRSnbo%3D" alt="Takashi Shibuya"></td>
</tr><tr>
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
<td><a href="https://www.patreon.com/user?u=5881381">Naoki Kosaka</a></td>
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
<td><a href="https://www.patreon.com/acid_chicken">Acid Chicken</a></td>
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
<td><a href="https://www.patreon.com/spinlock">Naoki Hirayama</a></td>
@@ -111,7 +111,7 @@ Please see [Contribution guide](./CONTRIBUTING.md).
</tr><tr>
</tr></table>
**Last updated:** Sat, 27 Oct 2018 04:36:06 UTC
**Last updated:** Wed, 31 Oct 2018 23:21:06 UTC
<!-- PATREON_END -->
:four_leaf_clover: Copyright

405
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
{
"name": "misskey",
"author": "syuilo <i@syuilo.com>",
"version": "10.35.1",
"clientVersion": "1.0.11285",
"version": "10.36.1",
"clientVersion": "1.0.11311",
"codename": "nighthike",
"main": "./built/index.js",
"private": true,
@@ -84,7 +84,7 @@
"@types/websocket": "0.0.40",
"@types/ws": "6.0.1",
"animejs": "2.2.0",
"apexcharts": "2.1.6",
"apexcharts": "2.1.9",
"autobind-decorator": "2.1.0",
"autosize": "4.0.2",
"autwh": "0.1.0",
@@ -135,7 +135,7 @@
"is-root": "2.0.0",
"is-url": "1.2.4",
"js-yaml": "3.12.0",
"jsdom": "12.2.0",
"jsdom": "13.0.0",
"json5": "2.1.0",
"json5-loader": "1.0.1",
"koa": "2.6.1",
@@ -201,11 +201,11 @@
"textarea-caret": "3.1.0",
"tinycolor2": "1.4.1",
"tmp": "0.0.33",
"ts-loader": "5.2.2",
"ts-loader": "5.3.0",
"ts-node": "7.0.1",
"tslint": "5.10.0",
"typescript": "3.1.4",
"typescript-eslint-parser": "20.0.0",
"typescript-eslint-parser": "20.1.1",
"uglify-es": "3.3.9",
"url-loader": "1.1.2",
"uuid": "3.3.2",

View File

@@ -9,9 +9,9 @@ export type TextElementHashtag = {
};
export default function(text: string, i: number) {
if (!(/^\s#[^\s\.,!\?]+/.test(text) || (i == 0 && /^#[^\s\.,!\?]+/.test(text)))) return null;
if (!(/^\s#[^\s\.,!\?#]+/.test(text) || (i == 0 && /^#[^\s\.,!\?#]+/.test(text)))) return null;
const isHead = text.startsWith('#');
const hashtag = text.match(/^\s?#[^\s\.,!\?]+/)[0];
const hashtag = text.match(/^\s?#[^\s\.,!\?#]+/)[0];
const res: any[] = !isHead ? [{
type: 'text',
content: text[0]

View File

@@ -0,0 +1,20 @@
import { IDriveFile } from '../models/drive-file';
import config from '../config';
export default function(file: IDriveFile, thumbnail = false): string {
if (file == null) return null;
if (file.metadata.withoutChunks) {
if (thumbnail) {
return file.metadata.thumbnailUrl || file.metadata.url;
} else {
return file.metadata.url;
}
} else {
if (thumbnail) {
return `${config.drive_url}/${file._id}?thumbnail`;
} else {
return `${config.drive_url}/${file._id}`;
}
}
}

View File

@@ -22,27 +22,28 @@ export type IApp = {
/**
* Pack an app for API response
*
* @param {any} app
* @param {any} me?
* @param {any} options?
* @return {Promise<any>}
*/
export const pack = (
app: any,
me?: any,
options?: {
detail?: boolean,
includeSecret?: boolean,
includeProfileImageIds?: boolean
}
) => new Promise<any>(async (resolve, reject) => {
const opts = options || {
const opts = Object.assign({
detail: false,
includeSecret: false,
includeProfileImageIds: false
};
}, options);
let _app: any;
const fields = opts.detail ? {} : {
name: true
};
// Populate the app if 'app' is ID
if (isObjectId(app)) {
_app = await App.findOne({
@@ -51,7 +52,7 @@ export const pack = (
} else if (typeof app === 'string') {
_app = await App.findOne({
_id: new mongo.ObjectID(app)
});
}, { fields });
} else {
_app = deepcopy(app);
}

View File

@@ -48,7 +48,9 @@ export const pack = (
delete _blocking._id;
// Populate blockee
_blocking.blockee = await packUser(_blocking.blockeeId, me);
_blocking.blockee = await packUser(_blocking.blockeeId, me, {
detail: true
});
resolve(_blocking);
});

View File

@@ -1,9 +1,9 @@
import * as mongo from 'mongodb';
const deepcopy = require('deepcopy');
import { pack as packFolder } from './drive-folder';
import config from '../config';
import monkDb, { nativeDbConn } from '../db/mongodb';
import isObjectId from '../misc/is-objectid';
import getDriveFileUrl from '../misc/get-drive-file-url';
const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
DriveFile.createIndex('md5');
@@ -33,7 +33,14 @@ export type IMetadata = {
thumbnailUrl?: string;
src?: string;
deletedAt?: Date;
/**
* このファイルの中身データがMongoDB内に保存されているのか否か
* オブジェクトストレージを利用している or リモートサーバーへの直リンクである
* な場合は false になります
*/
withoutChunks?: boolean;
storage?: string;
storageProps?: any;
isSensitive?: boolean;
@@ -128,8 +135,8 @@ export const pack = (
_target = Object.assign(_target, _file.metadata);
_target.url = _file.metadata.url ? _file.metadata.url : `${config.drive_url}/${_target.id}/${encodeURIComponent(_target.name)}`;
_target.thumbnailUrl = _file.metadata.thumbnailUrl ? _file.metadata.thumbnailUrl : _file.metadata.url ? _file.metadata.url : `${config.drive_url}/${_target.id}/${encodeURIComponent(_target.name)}?thumbnail`;
_target.url = getDriveFileUrl(_file);
_target.thumbnailUrl = getDriveFileUrl(_file, true);
_target.isRemote = _file.metadata.isRemote;
if (_target.properties == null) _target.properties = {};
@@ -156,6 +163,7 @@ export const pack = (
delete _target.storage;
delete _target.storageProps;
delete _target.isRemote;
delete _target._user;
resolve(_target);
});

View File

@@ -48,7 +48,9 @@ export const pack = (
delete _mute._id;
// Populate mutee
_mute.mutee = await packUser(_mute.muteeId, me);
_mute.mutee = await packUser(_mute.muteeId, me, {
detail: true
});
resolve(_mute);
});

View File

@@ -155,6 +155,50 @@ export function isValidBirthday(birthday: string): boolean {
}
//#endregion
export async function getRelation(me: mongo.ObjectId, target: mongo.ObjectId) {
const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([
Following.findOne({
followerId: me,
followeeId: target
}),
Following.findOne({
followerId: target,
followeeId: me
}),
FollowRequest.findOne({
followerId: me,
followeeId: target
}),
FollowRequest.findOne({
followerId: target,
followeeId: me
}),
Blocking.findOne({
blockerId: me,
blockeeId: target
}),
Blocking.findOne({
blockerId: target,
blockeeId: me
}),
Mute.findOne({
muterId: me,
muteeId: target
})
]);
return {
isFollowing: following1 !== null,
isStalking: following1 && following1.stalk,
hasPendingFollowRequestFromYou: followReq1 !== null,
hasPendingFollowRequestToYou: followReq2 !== null,
isFollowed: following2 !== null,
isBlocking: toBlocking !== null,
isBlocked: fromBlocked !== null,
isMuted: mute !== null
};
}
/**
* Pack a user for API response
*
@@ -179,24 +223,16 @@ export const pack = (
let _user: any;
const fields = opts.detail ? {
} : {
bannerColor: false,
bannerUrl: false,
description: false,
notesCount: false,
followersCount: false,
followingCount: false,
lastUsedAt: false,
settings: false,
clientSettings: false,
profile: false,
keywords: false,
domains: false,
pinnedNoteIds: false,
wallpaperColor: false,
wallpaperId: false,
wallpaperUrl: false
const fields = opts.detail ? {} : {
name: true,
username: true,
host: true,
avatarColor: true,
avatarUrl: true,
isCat: true,
isBot: true,
isAdmin: true,
isVerified: true
};
// Populate the user if 'user' is ID
@@ -231,6 +267,8 @@ export const pack = (
_user.id = _user._id;
delete _user._id;
delete _user.usernameLower;
if (_user.host == null) {
// Remove private properties
delete _user.keypair;
@@ -238,7 +276,6 @@ export const pack = (
delete _user.token;
delete _user.twoFactorTempSecret;
delete _user.twoFactorSecret;
delete _user.usernameLower;
if (_user.twitter) {
delete _user.twitter.accessToken;
delete _user.twitter.accessTokenSecret;
@@ -271,55 +308,16 @@ export const pack = (
}
if (meId && !meId.equals(_user.id) && opts.detail) {
const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([
Following.findOne({
followerId: meId,
followeeId: _user.id
}),
Following.findOne({
followerId: _user.id,
followeeId: meId
}),
FollowRequest.findOne({
followerId: meId,
followeeId: _user.id
}),
FollowRequest.findOne({
followerId: _user.id,
followeeId: meId
}),
Blocking.findOne({
blockerId: meId,
blockeeId: _user.id
}),
Blocking.findOne({
blockerId: _user.id,
blockeeId: meId
}),
Mute.findOne({
muterId: meId,
muteeId: _user.id
})
]);
const relation = await getRelation(meId, _user.id);
// Whether the user is following
_user.isFollowing = following1 !== null;
_user.isStalking = following1 && following1.stalk;
_user.hasPendingFollowRequestFromYou = followReq1 !== null;
_user.hasPendingFollowRequestToYou = followReq2 !== null;
// Whether the user is followed
_user.isFollowed = following2 !== null;
// Whether the user is blocking
_user.isBlocking = toBlocking !== null;
// Whether the user is blocked
_user.isBlocked = fromBlocked !== null;
// Whether the user is muted
_user.isMuted = mute !== null;
_user.isFollowing = relation.isFollowing;
_user.isFollowed = relation.isFollowed;
_user.isStalking = relation.isStalking;
_user.hasPendingFollowRequestFromYou = relation.hasPendingFollowRequestFromYou;
_user.hasPendingFollowRequestToYou = relation.hasPendingFollowRequestToYou;
_user.isBlocking = relation.isBlocking;
_user.isBlocked = relation.isBlocked;
_user.isMuted = relation.isMuted;
}
if (opts.detail) {

View File

@@ -15,6 +15,7 @@ import { URL } from 'url';
import { resolveNote } from './note';
import registerInstance from '../../../services/register-instance';
import Instance from '../../../models/instance';
import getDriveFileUrl from '../../../misc/get-drive-file-url';
const log = debug('misskey:activitypub');
@@ -209,8 +210,8 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<IU
const avatarId = avatar ? avatar._id : null;
const bannerId = banner ? banner._id : null;
const avatarUrl = (avatar && avatar.metadata.thumbnailUrl) ? avatar.metadata.thumbnailUrl : (avatar && avatar.metadata.url) ? avatar.metadata.url : null;
const bannerUrl = (banner && banner.metadata.url) ? banner.metadata.url : null;
const avatarUrl = getDriveFileUrl(avatar, true);
const bannerUrl = getDriveFileUrl(banner, false);
await User.update({ _id: user._id }, {
$set: {
@@ -303,8 +304,8 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
featured: person.featured,
avatarId: avatar ? avatar._id : null,
bannerId: banner ? banner._id : null,
avatarUrl: (avatar && avatar.metadata.thumbnailUrl) ? avatar.metadata.thumbnailUrl : (avatar && avatar.metadata.url) ? avatar.metadata.url : null,
bannerUrl: banner && banner.metadata.url ? banner.metadata.url : null,
avatarUrl: getDriveFileUrl(avatar, true),
bannerUrl: getDriveFileUrl(banner, false),
description: htmlToMFM(person.summary),
followersCount,
followingCount,

View File

@@ -1,8 +1,8 @@
import config from '../../../config';
import { IDriveFile } from '../../../models/drive-file';
import getDriveFileUrl from '../../../misc/get-drive-file-url';
export default (file: IDriveFile) => ({
type: 'Document',
mediaType: file.contentType,
url: file.metadata.url || `${config.drive_url}/${file._id}`
url: getDriveFileUrl(file)
});

View File

@@ -1,8 +1,8 @@
import config from '../../../config';
import { IDriveFile } from '../../../models/drive-file';
import getDriveFileUrl from '../../../misc/get-drive-file-url';
export default (file: IDriveFile) => ({
type: 'Image',
url: file.metadata.url || `${config.drive_url}/${file._id}`,
url: getDriveFileUrl(file),
sensitive: file.metadata.isSensitive
});

View File

@@ -44,6 +44,7 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
// Response
res(await pack(app, null, {
detail: true,
includeSecret: true
}));
});

View File

@@ -21,6 +21,7 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
// Send response
res(await pack(ap, user, {
detail: true,
includeSecret: isSecure && ap.userId.equals(user._id)
}));
});

View File

@@ -16,7 +16,7 @@ export const meta = {
limit: {
duration: ms('1hour'),
max: 100
max: 120
},
requireFile: true,

View File

@@ -34,6 +34,7 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
});
// Serialize
res(await Promise.all(tokens.map(async token =>
await pack(token.appId))));
res(await Promise.all(tokens.map(token => pack(token.appId, user, {
detail: true
}))));
});

View File

@@ -4,9 +4,9 @@ import { publishMainStream } from '../../../../stream';
import DriveFile from '../../../../models/drive-file';
import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
import { IApp } from '../../../../models/app';
import config from '../../../../config';
import { publishToFollowers } from '../../../../services/i/update';
import getParams from '../../get-params';
import getDriveFileUrl from '../../../../misc/get-drive-file-url';
export const meta = {
desc: {
@@ -129,7 +129,7 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
if (avatar == null) return rej('avatar not found');
if (!avatar.contentType.startsWith('image/')) return rej('avatar not an image');
updates.avatarUrl = avatar.metadata.thumbnailUrl || avatar.metadata.url || `${config.drive_url}/${avatar._id}`;
updates.avatarUrl = getDriveFileUrl(avatar, true);
if (avatar.metadata.properties.avgColor) {
updates.avatarColor = avatar.metadata.properties.avgColor;
@@ -144,7 +144,7 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
if (banner == null) return rej('banner not found');
if (!banner.contentType.startsWith('image/')) return rej('banner not an image');
updates.bannerUrl = banner.metadata.url || `${config.drive_url}/${banner._id}`;
updates.bannerUrl = getDriveFileUrl(banner, false);
if (banner.metadata.properties.avgColor) {
updates.bannerColor = banner.metadata.properties.avgColor;
@@ -162,7 +162,7 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
if (wallpaper == null) return rej('wallpaper not found');
updates.wallpaperUrl = wallpaper.metadata.url || `${config.drive_url}/${wallpaper._id}`;
updates.wallpaperUrl = getDriveFileUrl(wallpaper);
if (wallpaper.metadata.properties.avgColor) {
updates.wallpaperColor = wallpaper.metadata.properties.avgColor;

View File

@@ -35,6 +35,7 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
});
// Reply
res(await Promise.all(apps.map(async app =>
await pack(app))));
res(await Promise.all(apps.map(app => pack(app, user, {
detail: true
}))));
});

View File

@@ -0,0 +1,30 @@
import $ from 'cafy'; import ID from '../../../../misc/cafy-id';
import { ILocalUser, getRelation } from '../../../../models/user';
import getParams from '../../get-params';
export const meta = {
desc: {
'ja-JP': 'ユーザー間のリレーションを取得します。'
},
requireCredential: true,
params: {
userId: $.or($.type(ID), $.arr($.type(ID)).unique()).note({
desc: {
'ja-JP': 'ユーザーID (配列でも可)'
}
})
}
};
export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
const [ps, psErr] = getParams(meta, params);
if (psErr) return rej(psErr);
const ids = Array.isArray(ps.userId) ? ps.userId : [ps.userId];
const relations = await Promise.all(ids.map(id => getRelation(me._id, id)));
res(Array.isArray(ps.userId) ? relations : relations[0]);
});