Compare commits

..

11 Commits

9 changed files with 76 additions and 11 deletions

View File

@ -15,7 +15,8 @@ jobs:
executor: docker
steps:
- checkout
- setup_remote_docker
- setup_remote_docker:
version: 19.03.13
- run:
name: Build
command: |

View File

@ -609,6 +609,8 @@ desktop: "デスクトップ"
clip: "クリップ"
createNew: "新規作成"
optional: "任意"
createNewClip: "新しいクリップを作成"
public: "パブリック"
_mfm:
cheatSheet: "MFMチートシート"

View File

@ -1,7 +1,7 @@
{
"name": "misskey",
"author": "syuilo <syuilotan@yahoo.co.jp>",
"version": "12.57.0",
"version": "12.57.4",
"codename": "indigo",
"repository": {
"type": "git",

View File

@ -786,7 +786,8 @@ export default defineComponent({
},
isPublic: {
type: 'boolean',
label: this.$t('public')
label: this.$t('public'),
default: false
}
});
if (canceled) return;

View File

@ -60,7 +60,8 @@ export default defineComponent({
},
isPublic: {
type: 'boolean',
label: this.$t('public')
label: this.$t('public'),
default: false
}
});
if (canceled) return;

View File

@ -10,7 +10,7 @@ import { ApiError } from '../../error';
export const meta = {
tags: ['account', 'notes', 'clips'],
requireCredential: true as const,
requireCredential: false as const,
kind: 'read:account',
@ -45,13 +45,16 @@ export const meta = {
export default define(meta, async (ps, user) => {
const clip = await Clips.findOne({
id: ps.clipId,
userId: user.id
});
if (clip == null) {
throw new ApiError(meta.errors.noSuchClip);
}
if (!clip.isPublic && (user == null || (clip.userId !== user.id))) {
throw new ApiError(meta.errors.noSuchClip);
}
const clipQuery = ClipNotes.createQueryBuilder('joining')
.select('joining.noteId')
.where('joining.clipId = :clipId', { clipId: clip.id });
@ -61,8 +64,10 @@ export default define(meta, async (ps, user) => {
.leftJoinAndSelect('note.user', 'user')
.setParameters(clipQuery.getParameters());
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
if (user) {
generateVisibilityQuery(query, user);
generateMutedUserQuery(query, user);
}
const notes = await query
.take(ps.limit!)

View File

@ -7,7 +7,7 @@ import { Clips } from '../../../../models';
export const meta = {
tags: ['clips', 'account'],
requireCredential: true as const,
requireCredential: false as const,
kind: 'read:account',
@ -30,12 +30,15 @@ export default define(meta, async (ps, me) => {
// Fetch the clip
const clip = await Clips.findOne({
id: ps.clipId,
userId: me.id,
});
if (clip == null) {
throw new ApiError(meta.errors.noSuchClip);
}
if (!clip.isPublic && (me == null || (clip.userId !== me.id))) {
throw new ApiError(meta.errors.noSuchClip);
}
return await Clips.pack(clip);
});

View File

@ -17,7 +17,7 @@ import packFeed from './feed';
import { fetchMeta } from '../../misc/fetch-meta';
import { genOpenapiSpec } from '../api/openapi/gen-spec';
import config from '../../config';
import { Users, Notes, Emojis, UserProfiles, Pages, Channels } from '../../models';
import { Users, Notes, Emojis, UserProfiles, Pages, Channels, Clips } from '../../models';
import parseAcct from '../../misc/acct/parse';
import getNoteSummary from '../../misc/get-note-summary';
import { ensure } from '../../prelude/ensure';
@ -298,6 +298,28 @@ router.get('/@:user/pages/:page', async ctx => {
ctx.status = 404;
});
// Clip
router.get('/clips/:clip', async ctx => {
const clip = await Clips.findOne({
id: ctx.params.clip,
});
if (clip) {
const _clip = await Clips.pack(clip);
const meta = await fetchMeta();
await ctx.render('clip', {
clip: _clip,
instanceName: meta.name || 'Misskey'
});
ctx.set('Cache-Control', 'public, max-age=180');
return;
}
ctx.status = 404;
});
// Channel
router.get('/channels/:channel', async ctx => {
const channel = await Channels.findOne({

View File

@ -0,0 +1,30 @@
extends ./base
block vars
- const user = clip.user;
- const title = clip.name;
- const url = `${config.url}/clips/${clip.id}`;
block title
= `${title} | ${instanceName}`
block desc
meta(name='description' content= clip.description)
block og
meta(property='og:type' content='article')
meta(property='og:title' content= title)
meta(property='og:description' content= clip.description)
meta(property='og:url' content= url)
meta(property='og:image' content= user.avatarUrl)
block meta
meta(name='misskey:user-username' content=user.username)
meta(name='misskey:user-id' content=user.id)
meta(name='misskey:clip-id' content=clip.id)
meta(name='twitter:card' content='summary')
// todo
if user.twitter
meta(name='twitter:creator' content=`@${user.twitter.screenName}`)