Merge branch 'develop'

This commit is contained in:
syuilo 2022-02-11 21:40:15 +09:00
commit 6d8ae51d51
6 changed files with 43 additions and 29 deletions

View file

@ -10,6 +10,13 @@
You should also include the user name that made the change. You should also include the user name that made the change.
--> -->
## 12.106.2 (2022/02/11)
### Bugfixes
- クライアント: 削除したノートがタイムラインから自動で消えない問題を修正 @syuilo
- クライアント: リアクション数が正しくないことがある問題を修正 @syuilo
- 一部環境でマイグレーションが動作しない問題を修正 @syuilo
## 12.106.1 (2022/02/11) ## 12.106.1 (2022/02/11)
### Bugfixes ### Bugfixes

View file

@ -831,6 +831,8 @@ smartphone: "智能手机"
tablet: "平板" tablet: "平板"
auto: "自动" auto: "自动"
themeColor: "主题颜色" themeColor: "主题颜色"
size: "大小"
numberOfColumn: "列数"
_emailUnavailable: _emailUnavailable:
used: "已经被使用过" used: "已经被使用过"
format: "无效的格式" format: "无效的格式"
@ -958,7 +960,7 @@ _mfm:
rotateDescription: "旋转指定的角度。" rotateDescription: "旋转指定的角度。"
_instanceTicker: _instanceTicker:
none: "不显示" none: "不显示"
remote: "显示远程用户" remote: "显示远程用户"
always: "始终显示" always: "始终显示"
_serverDisconnectedBehavior: _serverDisconnectedBehavior:
reload: "自动重载" reload: "自动重载"

View file

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "12.106.1", "version": "12.106.2",
"codename": "indigo", "codename": "indigo",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -5,10 +5,11 @@ module.exports = class convertHardMutes1644010796173 {
name = 'convertHardMutes1644010796173' name = 'convertHardMutes1644010796173'
async up(queryRunner) { async up(queryRunner) {
let entries = await queryRunner.query(`SELECT "userId", "mutedWords" FROM "user_profile"`); let entries = await queryRunner.query(`SELECT "userId", "mutedWords" FROM "user_profile" WHERE "userHost" IS NULL`);
for(let i = 0; i < entries.length; i++) { for(let i = 0; i < entries.length; i++) {
let words = entries[i].mutedWords let words = entries[i].mutedWords
.map(line => { .map(line => {
if (typeof line === 'string') return [];
const regexp = line.join(" ").match(/^\/(.+)\/(.*)$/); const regexp = line.join(" ").match(/^\/(.+)\/(.*)$/);
if (regexp) { if (regexp) {
// convert regexp's // convert regexp's

View file

@ -138,11 +138,13 @@ const props = defineProps<{
const inChannel = inject('inChannel', null); const inChannel = inject('inChannel', null);
const note = $ref(JSON.parse(JSON.stringify(props.note)));
const isRenote = ( const isRenote = (
props.note.renote != null && note.renote != null &&
props.note.text == null && note.text == null &&
props.note.fileIds.length === 0 && note.fileIds.length === 0 &&
props.note.poll == null note.poll == null
); );
const el = ref<HTMLElement>(); const el = ref<HTMLElement>();
@ -150,8 +152,8 @@ const menuButton = ref<HTMLElement>();
const renoteButton = ref<InstanceType<typeof XRenoteButton>>(); const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
const renoteTime = ref<HTMLElement>(); const renoteTime = ref<HTMLElement>();
const reactButton = ref<HTMLElement>(); const reactButton = ref<HTMLElement>();
let appearNote = $ref(isRenote ? props.note.renote as misskey.entities.Note : props.note); let appearNote = $ref(isRenote ? note.renote as misskey.entities.Note : note);
const isMyRenote = $i && ($i.id === props.note.userId); const isMyRenote = $i && ($i.id === note.userId);
const showContent = ref(false); const showContent = ref(false);
const collapsed = ref(appearNote.cw == null && appearNote.text != null && ( const collapsed = ref(appearNote.cw == null && appearNote.text != null && (
(appearNote.text.split('\n').length > 9) || (appearNote.text.split('\n').length > 9) ||
@ -176,8 +178,9 @@ const keymap = {
}; };
useNoteCapture({ useNoteCapture({
appearNote: $$(appearNote),
rootEl: el, rootEl: el,
note: $$(appearNote),
isDeletedRef: $$(isDeleted),
}); });
function reply(viaKeyboard = false): void { function reply(viaKeyboard = false): void {
@ -225,12 +228,12 @@ function onContextmenu(ev: MouseEvent): void {
ev.preventDefault(); ev.preventDefault();
react(); react();
} else { } else {
os.contextMenu(getNoteMenu({ note: props.note, translating, translation, menuButton }), ev).then(focus); os.contextMenu(getNoteMenu({ note: note, translating, translation, menuButton }), ev).then(focus);
} }
} }
function menu(viaKeyboard = false): void { function menu(viaKeyboard = false): void {
os.popupMenu(getNoteMenu({ note: props.note, translating, translation, menuButton }), menuButton.value, { os.popupMenu(getNoteMenu({ note: note, translating, translation, menuButton }), menuButton.value, {
viaKeyboard viaKeyboard
}).then(focus); }).then(focus);
} }
@ -243,7 +246,7 @@ function showRenoteMenu(viaKeyboard = false): void {
danger: true, danger: true,
action: () => { action: () => {
os.api('notes/delete', { os.api('notes/delete', {
noteId: props.note.id noteId: note.id
}); });
isDeleted.value = true; isDeleted.value = true;
} }

View file

@ -5,34 +5,35 @@ import { $i } from '@/account';
export function useNoteCapture(props: { export function useNoteCapture(props: {
rootEl: Ref<HTMLElement>; rootEl: Ref<HTMLElement>;
appearNote: Ref<misskey.entities.Note>; note: Ref<misskey.entities.Note>;
isDeletedRef: Ref<boolean>;
}) { }) {
const appearNote = props.appearNote; const note = props.note;
const connection = $i ? stream : null; const connection = $i ? stream : null;
function onStreamNoteUpdated(data): void { function onStreamNoteUpdated(data): void {
const { type, id, body } = data; const { type, id, body } = data;
if (id !== appearNote.value.id) return; if (id !== note.value.id) return;
switch (type) { switch (type) {
case 'reacted': { case 'reacted': {
const reaction = body.reaction; const reaction = body.reaction;
if (body.emoji) { if (body.emoji) {
const emojis = appearNote.value.emojis || []; const emojis = note.value.emojis || [];
if (!emojis.includes(body.emoji)) { if (!emojis.includes(body.emoji)) {
appearNote.value.emojis = [...emojis, body.emoji]; note.value.emojis = [...emojis, body.emoji];
} }
} }
// TODO: reactionsプロパティがない場合ってあったっけ なければ || {} は消せる // TODO: reactionsプロパティがない場合ってあったっけ なければ || {} は消せる
const currentCount = (appearNote.value.reactions || {})[reaction] || 0; const currentCount = (note.value.reactions || {})[reaction] || 0;
appearNote.value.reactions[reaction] = currentCount + 1; note.value.reactions[reaction] = currentCount + 1;
if ($i && (body.userId === $i.id)) { if ($i && (body.userId === $i.id)) {
appearNote.value.myReaction = reaction; note.value.myReaction = reaction;
} }
break; break;
} }
@ -41,12 +42,12 @@ export function useNoteCapture(props: {
const reaction = body.reaction; const reaction = body.reaction;
// TODO: reactionsプロパティがない場合ってあったっけ なければ || {} は消せる // TODO: reactionsプロパティがない場合ってあったっけ なければ || {} は消せる
const currentCount = (appearNote.value.reactions || {})[reaction] || 0; const currentCount = (note.value.reactions || {})[reaction] || 0;
appearNote.value.reactions[reaction] = Math.max(0, currentCount - 1); note.value.reactions[reaction] = Math.max(0, currentCount - 1);
if ($i && (body.userId === $i.id)) { if ($i && (body.userId === $i.id)) {
appearNote.value.myReaction = null; note.value.myReaction = null;
} }
break; break;
} }
@ -54,7 +55,7 @@ export function useNoteCapture(props: {
case 'pollVoted': { case 'pollVoted': {
const choice = body.choice; const choice = body.choice;
const choices = [...appearNote.value.poll.choices]; const choices = [...note.value.poll.choices];
choices[choice] = { choices[choice] = {
...choices[choice], ...choices[choice],
votes: choices[choice].votes + 1, votes: choices[choice].votes + 1,
@ -63,12 +64,12 @@ export function useNoteCapture(props: {
} : {}) } : {})
}; };
appearNote.value.poll.choices = choices; note.value.poll.choices = choices;
break; break;
} }
case 'deleted': { case 'deleted': {
appearNote.value.deletedAt = new Date(); props.isDeletedRef.value = true;
break; break;
} }
} }
@ -77,7 +78,7 @@ export function useNoteCapture(props: {
function capture(withHandler = false): void { function capture(withHandler = false): void {
if (connection) { if (connection) {
// TODO: このノートがストリーミング経由で流れてきた場合のみ sr する // TODO: このノートがストリーミング経由で流れてきた場合のみ sr する
connection.send(document.body.contains(props.rootEl.value) ? 'sr' : 's', { id: appearNote.value.id }); connection.send(document.body.contains(props.rootEl.value) ? 'sr' : 's', { id: note.value.id });
if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated); if (withHandler) connection.on('noteUpdated', onStreamNoteUpdated);
} }
} }
@ -85,7 +86,7 @@ export function useNoteCapture(props: {
function decapture(withHandler = false): void { function decapture(withHandler = false): void {
if (connection) { if (connection) {
connection.send('un', { connection.send('un', {
id: appearNote.value.id, id: note.value.id,
}); });
if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated); if (withHandler) connection.off('noteUpdated', onStreamNoteUpdated);
} }