feat: note edit
This commit is contained in:
parent
a388e25f3e
commit
c106db89e1
16 changed files with 162 additions and 3 deletions
|
@ -15,6 +15,8 @@
|
||||||
## next
|
## next
|
||||||
|
|
||||||
### General
|
### General
|
||||||
|
- Feat: ノートの編集をできるように
|
||||||
|
- ロールで編集可否を設定可能
|
||||||
- Enhance: タイムラインからRenoteを除外するオプションを追加
|
- Enhance: タイムラインからRenoteを除外するオプションを追加
|
||||||
- Enhance: ユーザーページのノート一覧でRenoteを除外できるように
|
- Enhance: ユーザーページのノート一覧でRenoteを除外できるように
|
||||||
|
|
||||||
|
|
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
|
@ -1538,6 +1538,7 @@ export interface Locale {
|
||||||
"gtlAvailable": string;
|
"gtlAvailable": string;
|
||||||
"ltlAvailable": string;
|
"ltlAvailable": string;
|
||||||
"canPublicNote": string;
|
"canPublicNote": string;
|
||||||
|
"canEditNote": string;
|
||||||
"canInvite": string;
|
"canInvite": string;
|
||||||
"inviteLimit": string;
|
"inviteLimit": string;
|
||||||
"inviteLimitCycle": string;
|
"inviteLimitCycle": string;
|
||||||
|
|
|
@ -1459,6 +1459,7 @@ _role:
|
||||||
gtlAvailable: "グローバルタイムラインの閲覧"
|
gtlAvailable: "グローバルタイムラインの閲覧"
|
||||||
ltlAvailable: "ローカルタイムラインの閲覧"
|
ltlAvailable: "ローカルタイムラインの閲覧"
|
||||||
canPublicNote: "パブリック投稿の許可"
|
canPublicNote: "パブリック投稿の許可"
|
||||||
|
canEditNote: "ノートの編集"
|
||||||
canInvite: "サーバー招待コードの発行"
|
canInvite: "サーバー招待コードの発行"
|
||||||
inviteLimit: "招待コードの作成可能数"
|
inviteLimit: "招待コードの作成可能数"
|
||||||
inviteLimitCycle: "招待コードの発行間隔"
|
inviteLimitCycle: "招待コードの発行間隔"
|
||||||
|
|
|
@ -26,6 +26,7 @@ export type RolePolicies = {
|
||||||
gtlAvailable: boolean;
|
gtlAvailable: boolean;
|
||||||
ltlAvailable: boolean;
|
ltlAvailable: boolean;
|
||||||
canPublicNote: boolean;
|
canPublicNote: boolean;
|
||||||
|
canEditNote: boolean;
|
||||||
canInvite: boolean;
|
canInvite: boolean;
|
||||||
inviteLimit: number;
|
inviteLimit: number;
|
||||||
inviteLimitCycle: number;
|
inviteLimitCycle: number;
|
||||||
|
@ -50,6 +51,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
||||||
gtlAvailable: true,
|
gtlAvailable: true,
|
||||||
ltlAvailable: true,
|
ltlAvailable: true,
|
||||||
canPublicNote: true,
|
canPublicNote: true,
|
||||||
|
canEditNote: true,
|
||||||
canInvite: false,
|
canInvite: false,
|
||||||
inviteLimit: 0,
|
inviteLimit: 0,
|
||||||
inviteLimitCycle: 60 * 24 * 7,
|
inviteLimitCycle: 60 * 24 * 7,
|
||||||
|
@ -294,6 +296,7 @@ export class RoleService implements OnApplicationShutdown {
|
||||||
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
|
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
|
||||||
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
|
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
|
||||||
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
|
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
|
||||||
|
canEditNote: calc('canEditNote', vs => vs.some(v => v === true)),
|
||||||
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
|
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
|
||||||
inviteLimit: calc('inviteLimit', vs => Math.max(...vs)),
|
inviteLimit: calc('inviteLimit', vs => Math.max(...vs)),
|
||||||
inviteLimitCycle: calc('inviteLimitCycle', vs => Math.max(...vs)),
|
inviteLimitCycle: calc('inviteLimitCycle', vs => Math.max(...vs)),
|
||||||
|
|
|
@ -258,6 +258,7 @@ import * as ep___notes_clips from './endpoints/notes/clips.js';
|
||||||
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
|
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
|
||||||
import * as ep___notes_create from './endpoints/notes/create.js';
|
import * as ep___notes_create from './endpoints/notes/create.js';
|
||||||
import * as ep___notes_delete from './endpoints/notes/delete.js';
|
import * as ep___notes_delete from './endpoints/notes/delete.js';
|
||||||
|
import * as ep___notes_update from './endpoints/notes/update.js';
|
||||||
import * as ep___notes_favorites_create from './endpoints/notes/favorites/create.js';
|
import * as ep___notes_favorites_create from './endpoints/notes/favorites/create.js';
|
||||||
import * as ep___notes_favorites_delete from './endpoints/notes/favorites/delete.js';
|
import * as ep___notes_favorites_delete from './endpoints/notes/favorites/delete.js';
|
||||||
import * as ep___notes_featured from './endpoints/notes/featured.js';
|
import * as ep___notes_featured from './endpoints/notes/featured.js';
|
||||||
|
@ -606,6 +607,7 @@ const $notes_clips: Provider = { provide: 'ep:notes/clips', useClass: ep___notes
|
||||||
const $notes_conversation: Provider = { provide: 'ep:notes/conversation', useClass: ep___notes_conversation.default };
|
const $notes_conversation: Provider = { provide: 'ep:notes/conversation', useClass: ep___notes_conversation.default };
|
||||||
const $notes_create: Provider = { provide: 'ep:notes/create', useClass: ep___notes_create.default };
|
const $notes_create: Provider = { provide: 'ep:notes/create', useClass: ep___notes_create.default };
|
||||||
const $notes_delete: Provider = { provide: 'ep:notes/delete', useClass: ep___notes_delete.default };
|
const $notes_delete: Provider = { provide: 'ep:notes/delete', useClass: ep___notes_delete.default };
|
||||||
|
const $notes_update: Provider = { provide: 'ep:notes/update', useClass: ep___notes_update.default };
|
||||||
const $notes_favorites_create: Provider = { provide: 'ep:notes/favorites/create', useClass: ep___notes_favorites_create.default };
|
const $notes_favorites_create: Provider = { provide: 'ep:notes/favorites/create', useClass: ep___notes_favorites_create.default };
|
||||||
const $notes_favorites_delete: Provider = { provide: 'ep:notes/favorites/delete', useClass: ep___notes_favorites_delete.default };
|
const $notes_favorites_delete: Provider = { provide: 'ep:notes/favorites/delete', useClass: ep___notes_favorites_delete.default };
|
||||||
const $notes_featured: Provider = { provide: 'ep:notes/featured', useClass: ep___notes_featured.default };
|
const $notes_featured: Provider = { provide: 'ep:notes/featured', useClass: ep___notes_featured.default };
|
||||||
|
@ -958,6 +960,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
||||||
$notes_conversation,
|
$notes_conversation,
|
||||||
$notes_create,
|
$notes_create,
|
||||||
$notes_delete,
|
$notes_delete,
|
||||||
|
$notes_update,
|
||||||
$notes_favorites_create,
|
$notes_favorites_create,
|
||||||
$notes_favorites_delete,
|
$notes_favorites_delete,
|
||||||
$notes_featured,
|
$notes_featured,
|
||||||
|
@ -1304,6 +1307,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
||||||
$notes_conversation,
|
$notes_conversation,
|
||||||
$notes_create,
|
$notes_create,
|
||||||
$notes_delete,
|
$notes_delete,
|
||||||
|
$notes_update,
|
||||||
$notes_favorites_create,
|
$notes_favorites_create,
|
||||||
$notes_favorites_delete,
|
$notes_favorites_delete,
|
||||||
$notes_featured,
|
$notes_featured,
|
||||||
|
|
|
@ -258,6 +258,7 @@ import * as ep___notes_clips from './endpoints/notes/clips.js';
|
||||||
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
|
import * as ep___notes_conversation from './endpoints/notes/conversation.js';
|
||||||
import * as ep___notes_create from './endpoints/notes/create.js';
|
import * as ep___notes_create from './endpoints/notes/create.js';
|
||||||
import * as ep___notes_delete from './endpoints/notes/delete.js';
|
import * as ep___notes_delete from './endpoints/notes/delete.js';
|
||||||
|
import * as ep___notes_update from './endpoints/notes/update.js';
|
||||||
import * as ep___notes_favorites_create from './endpoints/notes/favorites/create.js';
|
import * as ep___notes_favorites_create from './endpoints/notes/favorites/create.js';
|
||||||
import * as ep___notes_favorites_delete from './endpoints/notes/favorites/delete.js';
|
import * as ep___notes_favorites_delete from './endpoints/notes/favorites/delete.js';
|
||||||
import * as ep___notes_featured from './endpoints/notes/featured.js';
|
import * as ep___notes_featured from './endpoints/notes/featured.js';
|
||||||
|
@ -604,6 +605,7 @@ const eps = [
|
||||||
['notes/conversation', ep___notes_conversation],
|
['notes/conversation', ep___notes_conversation],
|
||||||
['notes/create', ep___notes_create],
|
['notes/create', ep___notes_create],
|
||||||
['notes/delete', ep___notes_delete],
|
['notes/delete', ep___notes_delete],
|
||||||
|
['notes/update', ep___notes_update],
|
||||||
['notes/favorites/create', ep___notes_favorites_create],
|
['notes/favorites/create', ep___notes_favorites_create],
|
||||||
['notes/favorites/delete', ep___notes_favorites_delete],
|
['notes/favorites/delete', ep___notes_favorites_delete],
|
||||||
['notes/featured', ep___notes_featured],
|
['notes/featured', ep___notes_featured],
|
||||||
|
|
88
packages/backend/src/server/api/endpoints/notes/update.ts
Normal file
88
packages/backend/src/server/api/endpoints/notes/update.ts
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ms from 'ms';
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import type { UsersRepository, NotesRepository } from '@/models/_.js';
|
||||||
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
|
import { NoteDeleteService } from '@/core/NoteDeleteService.js';
|
||||||
|
import { DI } from '@/di-symbols.js';
|
||||||
|
import { GetterService } from '@/server/api/GetterService.js';
|
||||||
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
|
import { MAX_NOTE_TEXT_LENGTH } from '@/const.js';
|
||||||
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
|
export const meta = {
|
||||||
|
tags: ['notes'],
|
||||||
|
|
||||||
|
requireCredential: true,
|
||||||
|
requireRolePolicy: 'canEditNote',
|
||||||
|
|
||||||
|
kind: 'write:notes',
|
||||||
|
|
||||||
|
limit: {
|
||||||
|
duration: ms('1hour'),
|
||||||
|
max: 10,
|
||||||
|
minInterval: ms('1sec'),
|
||||||
|
},
|
||||||
|
|
||||||
|
errors: {
|
||||||
|
noSuchNote: {
|
||||||
|
message: 'No such note.',
|
||||||
|
code: 'NO_SUCH_NOTE',
|
||||||
|
id: 'a6584e14-6e01-4ad3-b566-851e7bf0d474',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const paramDef = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
noteId: { type: 'string', format: 'misskey:id' },
|
||||||
|
text: {
|
||||||
|
type: 'string',
|
||||||
|
minLength: 1,
|
||||||
|
maxLength: MAX_NOTE_TEXT_LENGTH,
|
||||||
|
nullable: false,
|
||||||
|
},
|
||||||
|
cw: { type: 'string', nullable: true, maxLength: 100 },
|
||||||
|
},
|
||||||
|
required: ['noteId', 'text', 'cw'],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||||
|
constructor(
|
||||||
|
@Inject(DI.usersRepository)
|
||||||
|
private usersRepository: UsersRepository,
|
||||||
|
|
||||||
|
@Inject(DI.notesRepository)
|
||||||
|
private notesRepository: NotesRepository,
|
||||||
|
|
||||||
|
private getterService: GetterService,
|
||||||
|
private globalEventService: GlobalEventService,
|
||||||
|
) {
|
||||||
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const note = await this.getterService.getNote(ps.noteId).catch(err => {
|
||||||
|
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (note.userId !== me.id) {
|
||||||
|
throw new ApiError(meta.errors.noSuchNote);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.notesRepository.update({ id: note.id }, {
|
||||||
|
cw: ps.cw,
|
||||||
|
text: ps.text,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.globalEventService.publishNoteStream(note.id, 'updated', {
|
||||||
|
cw: ps.cw,
|
||||||
|
text: ps.text,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -130,6 +130,10 @@ export interface NoteStreamTypes {
|
||||||
deleted: {
|
deleted: {
|
||||||
deletedAt: Date;
|
deletedAt: Date;
|
||||||
};
|
};
|
||||||
|
updated: {
|
||||||
|
cw: string | null;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
reacted: {
|
reacted: {
|
||||||
reaction: string;
|
reaction: string;
|
||||||
emoji?: {
|
emoji?: {
|
||||||
|
|
|
@ -143,6 +143,7 @@ const props = withDefaults(defineProps<{
|
||||||
fixed?: boolean;
|
fixed?: boolean;
|
||||||
autofocus?: boolean;
|
autofocus?: boolean;
|
||||||
freezeAfterPosted?: boolean;
|
freezeAfterPosted?: boolean;
|
||||||
|
updateMode?: boolean;
|
||||||
}>(), {
|
}>(), {
|
||||||
initialVisibleUsers: () => [],
|
initialVisibleUsers: () => [],
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
|
@ -698,17 +699,18 @@ async function post(ev?: MouseEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let postData = {
|
let postData = {
|
||||||
text: text === '' ? undefined : text,
|
text: text === '' ? null : text,
|
||||||
fileIds: files.length > 0 ? files.map(f => f.id) : undefined,
|
fileIds: files.length > 0 ? files.map(f => f.id) : undefined,
|
||||||
replyId: props.reply ? props.reply.id : undefined,
|
replyId: props.reply ? props.reply.id : undefined,
|
||||||
renoteId: props.renote ? props.renote.id : quoteId ? quoteId : undefined,
|
renoteId: props.renote ? props.renote.id : quoteId ? quoteId : undefined,
|
||||||
channelId: props.channel ? props.channel.id : undefined,
|
channelId: props.channel ? props.channel.id : undefined,
|
||||||
poll: poll,
|
poll: poll,
|
||||||
cw: useCw ? cw ?? '' : undefined,
|
cw: useCw ? cw ?? '' : null,
|
||||||
localOnly: localOnly,
|
localOnly: localOnly,
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
visibleUserIds: visibility === 'specified' ? visibleUsers.map(u => u.id) : undefined,
|
visibleUserIds: visibility === 'specified' ? visibleUsers.map(u => u.id) : undefined,
|
||||||
reactionAcceptance,
|
reactionAcceptance,
|
||||||
|
noteId: props.updateMode ? props.initialNote?.id : undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (withHashtags && hashtags && hashtags.trim() !== '') {
|
if (withHashtags && hashtags && hashtags.trim() !== '') {
|
||||||
|
@ -731,7 +733,7 @@ async function post(ev?: MouseEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
posting = true;
|
posting = true;
|
||||||
os.api('notes/create', postData, token).then(() => {
|
os.api(props.updateMode ? 'notes/update' : 'notes/create', postData, token).then(() => {
|
||||||
if (props.freezeAfterPosted) {
|
if (props.freezeAfterPosted) {
|
||||||
posted = true;
|
posted = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -30,6 +30,7 @@ const props = defineProps<{
|
||||||
instant?: boolean;
|
instant?: boolean;
|
||||||
fixed?: boolean;
|
fixed?: boolean;
|
||||||
autofocus?: boolean;
|
autofocus?: boolean;
|
||||||
|
updateMode?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|
|
@ -61,6 +61,7 @@ export const ROLE_POLICIES = [
|
||||||
'gtlAvailable',
|
'gtlAvailable',
|
||||||
'ltlAvailable',
|
'ltlAvailable',
|
||||||
'canPublicNote',
|
'canPublicNote',
|
||||||
|
'canEditNote',
|
||||||
'canInvite',
|
'canInvite',
|
||||||
'inviteLimit',
|
'inviteLimit',
|
||||||
'inviteLimitCycle',
|
'inviteLimitCycle',
|
||||||
|
|
|
@ -160,6 +160,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.canEditNote, 'canEditNote'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.canEditNote }}</template>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="role.policies.canEditNote.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||||
|
<span v-else>{{ role.policies.canEditNote.value ? i18n.ts.yes : i18n.ts.no }}</span>
|
||||||
|
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canEditNote)"></i></span>
|
||||||
|
</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="role.policies.canEditNote.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="role.policies.canEditNote.value" :disabled="role.policies.canEditNote.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkRange v-model="role.policies.canEditNote.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
|
||||||
|
<template #label>{{ i18n.ts._role.priority }}</template>
|
||||||
|
</MkRange>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
|
||||||
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
|
|
|
@ -48,6 +48,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.canEditNote, 'canEditNote'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.canEditNote }}</template>
|
||||||
|
<template #suffix>{{ policies.canEditNote ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
<MkSwitch v-model="policies.canEditNote">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.canInvite, 'canInvite'])">
|
||||||
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
||||||
<template #suffix>{{ policies.canInvite ? i18n.ts.yes : i18n.ts.no }}</template>
|
<template #suffix>{{ policies.canInvite ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
|
|
@ -172,6 +172,10 @@ export function getNoteMenu(props: {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function edit(): void {
|
||||||
|
os.post({ initialNote: appearNote, renote: appearNote.renote, reply: appearNote.reply, channel: appearNote.channel, updateMode: true });
|
||||||
|
}
|
||||||
|
|
||||||
function toggleFavorite(favorite: boolean): void {
|
function toggleFavorite(favorite: boolean): void {
|
||||||
claimAchievement('noteFavorited1');
|
claimAchievement('noteFavorited1');
|
||||||
os.apiWithDialog(favorite ? 'notes/favorites/create' : 'notes/favorites/delete', {
|
os.apiWithDialog(favorite ? 'notes/favorites/create' : 'notes/favorites/delete', {
|
||||||
|
@ -352,6 +356,11 @@ export function getNoteMenu(props: {
|
||||||
),
|
),
|
||||||
...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [
|
...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [
|
||||||
null,
|
null,
|
||||||
|
appearNote.userId === $i.id && $i.policies.canEditNote ? {
|
||||||
|
icon: 'ti ti-edit',
|
||||||
|
text: i18n.ts.edit,
|
||||||
|
action: edit,
|
||||||
|
} : undefined,
|
||||||
appearNote.userId === $i.id ? {
|
appearNote.userId === $i.id ? {
|
||||||
icon: 'ti ti-edit',
|
icon: 'ti ti-edit',
|
||||||
text: i18n.ts.deleteAndEdit,
|
text: i18n.ts.deleteAndEdit,
|
||||||
|
|
|
@ -71,6 +71,12 @@ export function useNoteCapture(props: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'updated': {
|
||||||
|
note.value.cw = body.cw;
|
||||||
|
note.value.text = body.text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'deleted': {
|
case 'deleted': {
|
||||||
props.isDeletedRef.value = true;
|
props.isDeletedRef.value = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -133,6 +133,13 @@ export type NoteUpdatedEvent = {
|
||||||
body: {
|
body: {
|
||||||
deletedAt: string;
|
deletedAt: string;
|
||||||
};
|
};
|
||||||
|
} | {
|
||||||
|
id: Note['id'];
|
||||||
|
type: 'updated';
|
||||||
|
body: {
|
||||||
|
cw: string | null;
|
||||||
|
text: string;
|
||||||
|
};
|
||||||
} | {
|
} | {
|
||||||
id: Note['id'];
|
id: Note['id'];
|
||||||
type: 'pollVoted';
|
type: 'pollVoted';
|
||||||
|
|
Loading…
Reference in a new issue