Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
182ca5d434 | ||
![]() |
facde9a75d | ||
![]() |
41385640b9 | ||
![]() |
7bad9db32e | ||
![]() |
af66f0a497 | ||
![]() |
95e1b80f41 | ||
![]() |
556e2eba95 | ||
![]() |
efe530cb17 | ||
![]() |
34e7c99283 | ||
![]() |
4157ea8bc3 | ||
![]() |
550517bbf3 | ||
![]() |
eb910cd8a1 | ||
![]() |
75131c4e8a | ||
![]() |
ee29ab95be |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -5,6 +5,16 @@ If you encounter any problems with updating, please try the following:
|
||||
1. `npm run clean` or `npm run cleanall`
|
||||
2. Retry update (Don't forget `npm i`)
|
||||
|
||||
10.96.0
|
||||
----------
|
||||
* 連合ユーザーの投稿に対してActivityPubオブジェクトを要求されたら元のインスタンスにリダイレクトするように
|
||||
* updatePersonを試行した時点でもlastFetchedAtを更新するように
|
||||
* 管理画面でリモートインスタンスの登録日時を表示
|
||||
* ユーザーサジェストが機能しなくなっていた問題を修正
|
||||
* 最近使ったハッシュタグ表示が機能していない問題を修正
|
||||
* バグ修正
|
||||
* デザインの調整
|
||||
|
||||
10.95.0
|
||||
----------
|
||||
* ジョブを一覧できるように
|
||||
|
@@ -46,6 +46,9 @@ Convert な(na) to にゃ(nya)
|
||||
Revert Nyaize
|
||||
|
||||
## Code style
|
||||
### Use semicolon
|
||||
To avoid ASI Hazard
|
||||
|
||||
### Don't use `export default`
|
||||
Bad:
|
||||
``` ts
|
||||
|
@@ -1408,12 +1408,13 @@ admin/views/hashtags.vue:
|
||||
hided-tags: "Hidden Tags"
|
||||
|
||||
admin/views/federation.vue:
|
||||
federation: "連合"
|
||||
instance: "インスタンス"
|
||||
host: "ホスト"
|
||||
notes: "投稿"
|
||||
users: "ユーザー"
|
||||
following: "フォロー中"
|
||||
followers: "フォロワー"
|
||||
caught-at: "登録日時"
|
||||
status: "ステータス"
|
||||
latest-request-sent-at: "直近のリクエスト送信"
|
||||
latest-request-received-at: "直近のリクエスト受信"
|
||||
@@ -1422,7 +1423,7 @@ admin/views/federation.vue:
|
||||
block: "ブロック"
|
||||
marked-as-closed: "閉鎖されているとマーク"
|
||||
lookup: "照会"
|
||||
instances: "インスタンス"
|
||||
instances: "連合"
|
||||
instance-not-registered: "そのインスタンスは登録されていません"
|
||||
sort: "ソート"
|
||||
sorts:
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "misskey",
|
||||
"author": "syuilo <i@syuilo.com>",
|
||||
"version": "10.95.0",
|
||||
"version": "10.96.0",
|
||||
"codename": "nighthike",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@@ -1,43 +1,58 @@
|
||||
<template>
|
||||
<div>
|
||||
<ui-card>
|
||||
<template #title><fa :icon="faTerminal"/> {{ $t('federation') }}</template>
|
||||
<template #title><fa :icon="faTerminal"/> {{ $t('instance') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-input class="target" v-model="target" type="text" @enter="showInstance()">
|
||||
<span>{{ $t('host') }}</span>
|
||||
<template #prefix><fa :icon="faServer"/></template>
|
||||
</ui-input>
|
||||
<ui-button @click="showInstance()"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
|
||||
|
||||
<div class="instance" v-if="instance">
|
||||
<ui-input :value="instance.host" type="text" readonly>
|
||||
<span>{{ $t('host') }}</span>
|
||||
</ui-input>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input :value="instance.host" type="text" readonly>
|
||||
<span>{{ $t('host') }}</span>
|
||||
<template #prefix><fa :icon="faServer"/></template>
|
||||
</ui-input>
|
||||
<ui-input :value="instance.caughtAt | date" type="text" readonly>
|
||||
<span>{{ $t('caught-at') }}</span>
|
||||
<template #prefix><fa :icon="faCrosshairs"/></template>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input :value="instance.notesCount | number" type="text" readonly>
|
||||
<span>{{ $t('notes') }}</span>
|
||||
<template #prefix><fa :icon="faEnvelopeOpenText"/></template>
|
||||
</ui-input>
|
||||
<ui-input :value="instance.usersCount | number" type="text" readonly>
|
||||
<span>{{ $t('users') }}</span>
|
||||
<template #prefix><fa :icon="faUsers"/></template>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input :value="instance.followingCount | number" type="text" readonly>
|
||||
<span>{{ $t('following') }}</span>
|
||||
<template #prefix><fa :icon="faCaretDown"/></template>
|
||||
</ui-input>
|
||||
<ui-input :value="instance.followersCount | number" type="text" readonly>
|
||||
<span>{{ $t('followers') }}</span>
|
||||
<template #prefix><fa :icon="faCaretUp"/></template>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input :value="instance.latestRequestSentAt" type="text" readonly>
|
||||
<ui-input :value="instance.latestRequestSentAt | date" type="text" readonly>
|
||||
<span>{{ $t('latest-request-sent-at') }}</span>
|
||||
<template #prefix><fa :icon="faPaperPlane"/></template>
|
||||
</ui-input>
|
||||
<ui-input :value="instance.latestStatus" type="text" readonly>
|
||||
<span>{{ $t('status') }}</span>
|
||||
<template #prefix><fa :icon="faTrafficLight"/></template>
|
||||
</ui-input>
|
||||
</ui-horizon-group>
|
||||
<ui-input :value="instance.latestRequestReceivedAt" type="text" readonly>
|
||||
<ui-input :value="instance.latestRequestReceivedAt | date" type="text" readonly>
|
||||
<span>{{ $t('latest-request-received-at') }}</span>
|
||||
<template #prefix><fa :icon="faInbox"/></template>
|
||||
</ui-input>
|
||||
<ui-switch v-model="instance.isBlocked" @change="updateInstance()">{{ $t('block') }}</ui-switch>
|
||||
<ui-switch v-model="instance.isMarkedAsClosed" @change="updateInstance()">{{ $t('marked-as-closed') }}</ui-switch>
|
||||
@@ -133,7 +148,8 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import i18n from '../../i18n';
|
||||
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||
import { faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faTrafficLight, faInbox } from '@fortawesome/free-solid-svg-icons';
|
||||
import ApexCharts from 'apexcharts';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
|
||||
@@ -144,19 +160,23 @@ const negate = arr => arr.map(x => -x);
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/federation.vue'),
|
||||
|
||||
filters: {
|
||||
date: v => v ? new Date(v).toLocaleString() : 'N/A'
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
instance: null,
|
||||
target: null,
|
||||
sort: '+lastCommunicatedAt',
|
||||
state: 'all',
|
||||
limit: 50,
|
||||
limit: 100,
|
||||
instances: [],
|
||||
chart: null,
|
||||
chartSrc: 'requests',
|
||||
chartSpan: 'hour',
|
||||
chartInstance: null,
|
||||
faGlobe, faTerminal, faSearch, faMinusCircle, faServer
|
||||
faGlobe, faTerminal, faSearch, faMinusCircle, faServer, faCrosshairs, faEnvelopeOpenText, faUsers, faCaretDown, faCaretUp, faPaperPlane, faTrafficLight, faInbox
|
||||
};
|
||||
},
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<template #title><fa :icon="faStream"/> {{ $t('logs') }}</template>
|
||||
<section class="fit-top">
|
||||
<ui-horizon-group inputs>
|
||||
<ui-input v-model="domain" debounce>
|
||||
<ui-input v-model="domain" :debounce="true">
|
||||
<span>{{ $t('domain') }}</span>
|
||||
</ui-input>
|
||||
<ui-select v-model="level">
|
||||
|
@@ -100,7 +100,7 @@ import * as tinycolor from 'tinycolor2';
|
||||
import { faTasks, faInbox, faStopwatch, faPlayCircle as fasPlayCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faPaperPlane, faStopCircle, faPlayCircle as farPlayCircle, faChartBar } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
const limit = 150;
|
||||
const limit = 200;
|
||||
|
||||
export default Vue.extend({
|
||||
i18n: i18n('admin/views/queue.vue'),
|
||||
|
@@ -480,7 +480,7 @@ export default Vue.extend({
|
||||
});
|
||||
|
||||
if (this.text && this.text != '') {
|
||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
||||
const hashtags = parse(this.text).filter(x => x.node.type === 'hashtag').map(x => x.node.props.hashtag);
|
||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||
}
|
||||
|
@@ -367,7 +367,7 @@ export default Vue.extend({
|
||||
});
|
||||
|
||||
if (this.text && this.text != '') {
|
||||
const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
|
||||
const hashtags = parse(this.text).filter(x => x.node.type === 'hashtag').map(x => x.node.props.hashtag);
|
||||
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
|
||||
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import { deliverQueue, inboxQueue } from '../queue';
|
||||
|
||||
const ev = new Xev();
|
||||
|
||||
const interval = 2000;
|
||||
const interval = 3000;
|
||||
|
||||
/**
|
||||
* Report queue stats regularly
|
||||
|
@@ -294,6 +294,13 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// 繋がらないインスタンスに何回も試行するのを防ぐ, 後続の同様処理の連続試行を防ぐ ため 試行前にも更新する
|
||||
await User.update({ _id: exist._id }, {
|
||||
$set: {
|
||||
lastFetchedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
if (resolver == null) resolver = new Resolver();
|
||||
|
||||
const object = hint || await resolver.resolve(uri) as any;
|
||||
|
@@ -17,6 +17,7 @@ import Following from './activitypub/following';
|
||||
import Featured from './activitypub/featured';
|
||||
import renderQuestion from '../remote/activitypub/renderer/question';
|
||||
import { inbox as processInbox } from '../queue';
|
||||
import { isSelfHost } from '../misc/convert-host';
|
||||
|
||||
// Init router
|
||||
const router = new Router();
|
||||
@@ -79,6 +80,16 @@ router.get('/notes/:note', async (ctx, next) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// リモートだったらリダイレクト
|
||||
if (note._user.host != null) {
|
||||
if (note.uri == null || isSelfHost(note._user.host)) {
|
||||
ctx.status = 500;
|
||||
return;
|
||||
}
|
||||
ctx.redirect(note.uri);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.body = renderActivity(await renderNote(note, false));
|
||||
ctx.set('Cache-Control', 'public, max-age=180');
|
||||
setResponseType(ctx);
|
||||
@@ -93,6 +104,7 @@ router.get('/notes/:note/activity', async ctx => {
|
||||
|
||||
const note = await Note.findOne({
|
||||
_id: new ObjectID(ctx.params.note),
|
||||
'_user.host': null,
|
||||
visibility: { $in: ['public', 'home'] },
|
||||
localOnly: { $ne: true }
|
||||
});
|
||||
@@ -116,6 +128,7 @@ router.get('/questions/:question', async (ctx, next) => {
|
||||
|
||||
const poll = await Note.findOne({
|
||||
_id: new ObjectID(ctx.params.question),
|
||||
'_user.host': null,
|
||||
visibility: { $in: ['public', 'home'] },
|
||||
localOnly: { $ne: true },
|
||||
poll: {
|
||||
|
@@ -71,7 +71,7 @@ export default define(meta, async (ps, me) => {
|
||||
.find({
|
||||
host: null,
|
||||
usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase())),
|
||||
isSuspended: false
|
||||
isSuspended: { $ne: true }
|
||||
}, {
|
||||
limit: ps.limit,
|
||||
skip: ps.offset
|
||||
@@ -82,7 +82,7 @@ export default define(meta, async (ps, me) => {
|
||||
.find({
|
||||
host: { $ne: null },
|
||||
usernameLower: new RegExp('^' + escapeRegexp(ps.query.replace('@', '').toLowerCase())),
|
||||
isSuspended: false
|
||||
isSuspended: { $ne: true }
|
||||
}, {
|
||||
limit: ps.limit - users.length
|
||||
});
|
||||
|
@@ -31,3 +31,5 @@ block meta
|
||||
|
||||
if !user.host
|
||||
link(rel='alternate' href=url type='application/activity+json')
|
||||
if note.uri
|
||||
link(rel='alternate' href=note.uri type='application/activity+json')
|
||||
|
Reference in New Issue
Block a user