mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-23 02:33:08 +02:00
upd: improve post editing on polls
Fixes not being able to edit post if poll expiry was set and now checks properly if poll was edited or not
This commit is contained in:
parent
6fb8a633e0
commit
65a2ea6a74
4 changed files with 95 additions and 97 deletions
|
@ -14,18 +14,15 @@ import { extractCustomEmojisFromMfm } from '@/misc/extract-custom-emojis-from-mf
|
||||||
import { extractHashtags } from '@/misc/extract-hashtags.js';
|
import { extractHashtags } from '@/misc/extract-hashtags.js';
|
||||||
import type { IMentionedRemoteUsers } from '@/models/Note.js';
|
import type { IMentionedRemoteUsers } from '@/models/Note.js';
|
||||||
import { MiNote } from '@/models/Note.js';
|
import { MiNote } from '@/models/Note.js';
|
||||||
import type { NoteEditRepository, ChannelFollowingsRepository, ChannelsRepository, FollowingsRepository, InstancesRepository, MiFollowing, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository } from '@/models/_.js';
|
import type { NoteEditRepository, ChannelFollowingsRepository, ChannelsRepository, FollowingsRepository, InstancesRepository, MiFollowing, MutingsRepository, NotesRepository, NoteThreadMutingsRepository, UserListMembershipsRepository, UserProfilesRepository, UsersRepository, PollsRepository } from '@/models/_.js';
|
||||||
import type { MiDriveFile } from '@/models/DriveFile.js';
|
import type { MiDriveFile } from '@/models/DriveFile.js';
|
||||||
import type { MiApp } from '@/models/App.js';
|
import type { MiApp } from '@/models/App.js';
|
||||||
import { concat } from '@/misc/prelude/array.js';
|
import { concat } from '@/misc/prelude/array.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
|
import type { MiUser, MiLocalUser, MiRemoteUser } from '@/models/User.js';
|
||||||
import { MiPoll, type IPoll } from '@/models/Poll.js';
|
import { MiPoll, type IPoll } from '@/models/Poll.js';
|
||||||
import { checkWordMute } from '@/misc/check-word-mute.js';
|
|
||||||
import type { MiChannel } from '@/models/Channel.js';
|
import type { MiChannel } from '@/models/Channel.js';
|
||||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||||
import { MemorySingleCache } from '@/misc/cache.js';
|
|
||||||
import type { MiUserProfile } from '@/models/UserProfile.js';
|
|
||||||
import { RelayService } from '@/core/RelayService.js';
|
import { RelayService } from '@/core/RelayService.js';
|
||||||
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
@ -35,7 +32,6 @@ import ActiveUsersChart from '@/core/chart/charts/active-users.js';
|
||||||
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
import { WebhookService } from '@/core/WebhookService.js';
|
import { WebhookService } from '@/core/WebhookService.js';
|
||||||
import { HashtagService } from '@/core/HashtagService.js';
|
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
|
@ -48,11 +44,7 @@ import { DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js';
|
||||||
import { RoleService } from '@/core/RoleService.js';
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
import { SearchService } from '@/core/SearchService.js';
|
import { SearchService } from '@/core/SearchService.js';
|
||||||
import { FeaturedService } from '@/core/FeaturedService.js';
|
|
||||||
import { FunoutTimelineService } from '@/core/FunoutTimelineService.js';
|
import { FunoutTimelineService } from '@/core/FunoutTimelineService.js';
|
||||||
import { AntennaService } from './AntennaService.js';
|
|
||||||
import NotesChart from './chart/charts/notes.js';
|
|
||||||
import PerUserNotesChart from './chart/charts/per-user-notes.js';
|
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
|
|
||||||
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
|
type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
|
||||||
|
@ -191,6 +183,9 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
@Inject(DI.noteEditRepository)
|
@Inject(DI.noteEditRepository)
|
||||||
private noteEditRepository: NoteEditRepository,
|
private noteEditRepository: NoteEditRepository,
|
||||||
|
|
||||||
|
@Inject(DI.pollsRepository)
|
||||||
|
private pollsRepository: PollsRepository,
|
||||||
|
|
||||||
private userEntityService: UserEntityService,
|
private userEntityService: UserEntityService,
|
||||||
private noteEntityService: NoteEntityService,
|
private noteEntityService: NoteEntityService,
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
|
@ -201,18 +196,13 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private relayService: RelayService,
|
private relayService: RelayService,
|
||||||
private federatedInstanceService: FederatedInstanceService,
|
private federatedInstanceService: FederatedInstanceService,
|
||||||
private hashtagService: HashtagService,
|
|
||||||
private antennaService: AntennaService,
|
|
||||||
private webhookService: WebhookService,
|
private webhookService: WebhookService,
|
||||||
private featuredService: FeaturedService,
|
|
||||||
private remoteUserResolveService: RemoteUserResolveService,
|
private remoteUserResolveService: RemoteUserResolveService,
|
||||||
private apDeliverManagerService: ApDeliverManagerService,
|
private apDeliverManagerService: ApDeliverManagerService,
|
||||||
private apRendererService: ApRendererService,
|
private apRendererService: ApRendererService,
|
||||||
private roleService: RoleService,
|
private roleService: RoleService,
|
||||||
private metaService: MetaService,
|
private metaService: MetaService,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
private notesChart: NotesChart,
|
|
||||||
private perUserNotesChart: PerUserNotesChart,
|
|
||||||
private activeUsersChart: ActiveUsersChart,
|
private activeUsersChart: ActiveUsersChart,
|
||||||
private instanceChart: InstanceChart,
|
private instanceChart: InstanceChart,
|
||||||
private utilityService: UtilityService,
|
private utilityService: UtilityService,
|
||||||
|
@ -385,6 +375,10 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
update.hasPoll = !!data.poll;
|
update.hasPoll = !!data.poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const poll = await this.pollsRepository.findOneBy({ noteId: oldnote.id });
|
||||||
|
|
||||||
|
const oldPoll = poll ? { choices: poll.choices, multiple: poll.multiple, expiresAt: poll.expiresAt } : null;
|
||||||
|
|
||||||
if (Object.keys(update).length > 0) {
|
if (Object.keys(update).length > 0) {
|
||||||
const exists = await this.noteEditRepository.findOneBy({ noteId: oldnote.id });
|
const exists = await this.noteEditRepository.findOneBy({ noteId: oldnote.id });
|
||||||
|
|
||||||
|
@ -456,7 +450,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.poll != null) {
|
if (data.poll != null && JSON.stringify(data.poll) !== JSON.stringify(oldPoll)) {
|
||||||
// Start transaction
|
// Start transaction
|
||||||
await this.db.transaction(async transactionalEntityManager => {
|
await this.db.transaction(async transactionalEntityManager => {
|
||||||
await transactionalEntityManager.update(MiNote, oldnote.id, note);
|
await transactionalEntityManager.update(MiNote, oldnote.id, note);
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../error.js';
|
import { ApiError } from '../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ["notes"],
|
tags: ['notes'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
|
||||||
|
@ -23,99 +23,99 @@ export const meta = {
|
||||||
max: 300,
|
max: 300,
|
||||||
},
|
},
|
||||||
|
|
||||||
kind: "write:notes",
|
kind: 'write:notes',
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: "object",
|
type: 'object',
|
||||||
optional: false,
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
properties: {
|
properties: {
|
||||||
createdNote: {
|
createdNote: {
|
||||||
type: "object",
|
type: 'object',
|
||||||
optional: false,
|
optional: false,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
ref: "Note",
|
ref: 'Note',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchRenoteTarget: {
|
noSuchRenoteTarget: {
|
||||||
message: "No such renote target.",
|
message: 'No such renote target.',
|
||||||
code: "NO_SUCH_RENOTE_TARGET",
|
code: 'NO_SUCH_RENOTE_TARGET',
|
||||||
id: "b5c90186-4ab0-49c8-9bba-a1f76c282ba4",
|
id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotReRenote: {
|
cannotReRenote: {
|
||||||
message: "You can not Renote a pure Renote.",
|
message: 'You can not Renote a pure Renote.',
|
||||||
code: "CANNOT_RENOTE_TO_A_PURE_RENOTE",
|
code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE',
|
||||||
id: "fd4cc33e-2a37-48dd-99cc-9b806eb2031a",
|
id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a',
|
||||||
},
|
},
|
||||||
|
|
||||||
noSuchReplyTarget: {
|
noSuchReplyTarget: {
|
||||||
message: "No such reply target.",
|
message: 'No such reply target.',
|
||||||
code: "NO_SUCH_REPLY_TARGET",
|
code: 'NO_SUCH_REPLY_TARGET',
|
||||||
id: "749ee0f6-d3da-459a-bf02-282e2da4292c",
|
id: '749ee0f6-d3da-459a-bf02-282e2da4292c',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotReplyToPureRenote: {
|
cannotReplyToPureRenote: {
|
||||||
message: "You can not reply to a pure Renote.",
|
message: 'You can not reply to a pure Renote.',
|
||||||
code: "CANNOT_REPLY_TO_A_PURE_RENOTE",
|
code: 'CANNOT_REPLY_TO_A_PURE_RENOTE',
|
||||||
id: "3ac74a84-8fd5-4bb0-870f-01804f82ce15",
|
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotCreateAlreadyExpiredPoll: {
|
cannotCreateAlreadyExpiredPoll: {
|
||||||
message: "Poll is already expired.",
|
message: 'Poll is already expired.',
|
||||||
code: "CANNOT_CREATE_ALREADY_EXPIRED_POLL",
|
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
|
||||||
id: "04da457d-b083-4055-9082-955525eda5a5",
|
id: '04da457d-b083-4055-9082-955525eda5a5',
|
||||||
},
|
},
|
||||||
|
|
||||||
noSuchChannel: {
|
noSuchChannel: {
|
||||||
message: "No such channel.",
|
message: 'No such channel.',
|
||||||
code: "NO_SUCH_CHANNEL",
|
code: 'NO_SUCH_CHANNEL',
|
||||||
id: "b1653923-5453-4edc-b786-7c4f39bb0bbb",
|
id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb',
|
||||||
},
|
},
|
||||||
|
|
||||||
youHaveBeenBlocked: {
|
youHaveBeenBlocked: {
|
||||||
message: "You have been blocked by this user.",
|
message: 'You have been blocked by this user.',
|
||||||
code: "YOU_HAVE_BEEN_BLOCKED",
|
code: 'YOU_HAVE_BEEN_BLOCKED',
|
||||||
id: "b390d7e1-8a5e-46ed-b625-06271cafd3d3",
|
id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3',
|
||||||
},
|
},
|
||||||
|
|
||||||
accountLocked: {
|
accountLocked: {
|
||||||
message: "You migrated. Your account is now locked.",
|
message: 'You migrated. Your account is now locked.',
|
||||||
code: "ACCOUNT_LOCKED",
|
code: 'ACCOUNT_LOCKED',
|
||||||
id: "d390d7e1-8a5e-46ed-b625-06271cafd3d3",
|
id: 'd390d7e1-8a5e-46ed-b625-06271cafd3d3',
|
||||||
},
|
},
|
||||||
|
|
||||||
needsEditId: {
|
needsEditId: {
|
||||||
message: "You need to specify `editId`.",
|
message: 'You need to specify `editId`.',
|
||||||
code: "NEEDS_EDIT_ID",
|
code: 'NEEDS_EDIT_ID',
|
||||||
id: "d697edc8-8c73-4de8-bded-35fd198b79e5",
|
id: 'd697edc8-8c73-4de8-bded-35fd198b79e5',
|
||||||
},
|
},
|
||||||
|
|
||||||
noSuchNote: {
|
noSuchNote: {
|
||||||
message: "No such note.",
|
message: 'No such note.',
|
||||||
code: "NO_SUCH_NOTE",
|
code: 'NO_SUCH_NOTE',
|
||||||
id: "eef6c173-3010-4a23-8674-7c4fcaeba719",
|
id: 'eef6c173-3010-4a23-8674-7c4fcaeba719',
|
||||||
},
|
},
|
||||||
|
|
||||||
youAreNotTheAuthor: {
|
youAreNotTheAuthor: {
|
||||||
message: "You are not the author of this note.",
|
message: 'You are not the author of this note.',
|
||||||
code: "YOU_ARE_NOT_THE_AUTHOR",
|
code: 'YOU_ARE_NOT_THE_AUTHOR',
|
||||||
id: "c6e61685-411d-43d0-b90a-a448d2539001",
|
id: 'c6e61685-411d-43d0-b90a-a448d2539001',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotPrivateRenote: {
|
cannotPrivateRenote: {
|
||||||
message: "You can not perform a private renote.",
|
message: 'You can not perform a private renote.',
|
||||||
code: "CANNOT_PRIVATE_RENOTE",
|
code: 'CANNOT_PRIVATE_RENOTE',
|
||||||
id: "19a50f1c-84fa-4e33-81d3-17834ccc0ad8",
|
id: '19a50f1c-84fa-4e33-81d3-17834ccc0ad8',
|
||||||
},
|
},
|
||||||
|
|
||||||
notLocalUser: {
|
notLocalUser: {
|
||||||
message: "You are not a local user.",
|
message: 'You are not a local user.',
|
||||||
code: "NOT_LOCAL_USER",
|
code: 'NOT_LOCAL_USER',
|
||||||
id: "b907f407-2aa0-4283-800b-a2c56290b822",
|
id: 'b907f407-2aa0-4283-800b-a2c56290b822',
|
||||||
},
|
},
|
||||||
|
|
||||||
cannotRenoteOutsideOfChannel: {
|
cannotRenoteOutsideOfChannel: {
|
||||||
|
@ -127,60 +127,63 @@ export const meta = {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: "object",
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
editId: { type: "string", format: "misskey:id" },
|
editId: { type: 'string', format: 'misskey:id' },
|
||||||
visibility: { type: "string", enum: ['public', 'home', 'followers', 'specified'], default: "public" },
|
visibility: { type: 'string', enum: ['public', 'home', 'followers', 'specified'], default: 'public' },
|
||||||
visibleUserIds: {
|
visibleUserIds: {
|
||||||
type: "array",
|
type: 'array',
|
||||||
uniqueItems: true,
|
uniqueItems: true,
|
||||||
items: {
|
items: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
format: "misskey:id",
|
format: 'misskey:id',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
text: { type: "string", maxLength: MAX_NOTE_TEXT_LENGTH, nullable: true },
|
cw: { type: 'string', nullable: true, minLength: 1, maxLength: 250 },
|
||||||
cw: { type: "string", nullable: true, minLength: 1, maxLength: 250 },
|
localOnly: { type: 'boolean', default: false },
|
||||||
localOnly: { type: "boolean", default: false },
|
reactionAcceptance: { type: 'string', nullable: true, enum: [null, 'likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'], default: null },
|
||||||
noExtractMentions: { type: "boolean", default: false },
|
noExtractMentions: { type: 'boolean', default: false },
|
||||||
noExtractHashtags: { type: "boolean", default: false },
|
noExtractHashtags: { type: 'boolean', default: false },
|
||||||
noExtractEmojis: { type: "boolean", default: false },
|
noExtractEmojis: { type: 'boolean', default: false },
|
||||||
|
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
text: {
|
||||||
|
type: 'string',
|
||||||
|
minLength: 1,
|
||||||
|
maxLength: MAX_NOTE_TEXT_LENGTH,
|
||||||
|
nullable: true,
|
||||||
|
},
|
||||||
fileIds: {
|
fileIds: {
|
||||||
type: "array",
|
type: 'array',
|
||||||
uniqueItems: true,
|
uniqueItems: true,
|
||||||
minItems: 1,
|
minItems: 1,
|
||||||
maxItems: 16,
|
maxItems: 16,
|
||||||
items: { type: "string", format: "misskey:id" },
|
items: { type: 'string', format: 'misskey:id' },
|
||||||
},
|
},
|
||||||
mediaIds: {
|
mediaIds: {
|
||||||
deprecated: true,
|
type: 'array',
|
||||||
description:
|
|
||||||
"Use `fileIds` instead. If both are specified, this property is discarded.",
|
|
||||||
type: "array",
|
|
||||||
uniqueItems: true,
|
uniqueItems: true,
|
||||||
minItems: 1,
|
minItems: 1,
|
||||||
maxItems: 16,
|
maxItems: 16,
|
||||||
items: { type: "string", format: "misskey:id" },
|
items: { type: 'string', format: 'misskey:id' },
|
||||||
},
|
},
|
||||||
replyId: { type: "string", format: "misskey:id", nullable: true },
|
|
||||||
renoteId: { type: "string", format: "misskey:id", nullable: true },
|
|
||||||
channelId: { type: "string", format: "misskey:id", nullable: true },
|
|
||||||
poll: {
|
poll: {
|
||||||
type: "object",
|
type: 'object',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
properties: {
|
properties: {
|
||||||
choices: {
|
choices: {
|
||||||
type: "array",
|
type: 'array',
|
||||||
uniqueItems: true,
|
uniqueItems: true,
|
||||||
minItems: 2,
|
minItems: 2,
|
||||||
maxItems: 10,
|
maxItems: 10,
|
||||||
items: { type: "string", minLength: 1, maxLength: 50 },
|
items: { type: 'string', minLength: 1, maxLength: 50 },
|
||||||
},
|
},
|
||||||
multiple: { type: "boolean", default: false },
|
multiple: { type: 'boolean' },
|
||||||
expiresAt: { type: "integer", nullable: true },
|
expiresAt: { type: 'integer', nullable: true },
|
||||||
expiredAfter: { type: "integer", nullable: true, minimum: 1 },
|
expiredAfter: { type: 'integer', nullable: true, minimum: 1 },
|
||||||
},
|
},
|
||||||
required: ["choices"],
|
required: ['choices'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
anyOf: [
|
anyOf: [
|
||||||
|
@ -188,32 +191,32 @@ export const paramDef = {
|
||||||
// (re)note with text, files and poll are optional
|
// (re)note with text, files and poll are optional
|
||||||
properties: {
|
properties: {
|
||||||
text: {
|
text: {
|
||||||
type: "string",
|
type: 'string',
|
||||||
minLength: 1,
|
minLength: 1,
|
||||||
maxLength: MAX_NOTE_TEXT_LENGTH,
|
maxLength: MAX_NOTE_TEXT_LENGTH,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: ["text"],
|
required: ['text'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// (re)note with files, text and poll are optional
|
// (re)note with files, text and poll are optional
|
||||||
required: ["fileIds"],
|
required: ['fileIds'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// (re)note with files, text and poll are optional
|
// (re)note with files, text and poll are optional
|
||||||
required: ["mediaIds"],
|
required: ['mediaIds'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// (re)note with poll, text and files are optional
|
// (re)note with poll, text and files are optional
|
||||||
properties: {
|
properties: {
|
||||||
poll: { type: "object", nullable: false },
|
poll: { type: 'object', nullable: false },
|
||||||
},
|
},
|
||||||
required: ["poll"],
|
required: ['poll'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pure renote
|
// pure renote
|
||||||
required: ["renoteId"],
|
required: ['renoteId'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
@ -931,8 +931,8 @@ onMounted(() => {
|
||||||
poll = {
|
poll = {
|
||||||
choices: init.poll.choices.map(x => x.text),
|
choices: init.poll.choices.map(x => x.text),
|
||||||
multiple: init.poll.multiple,
|
multiple: init.poll.multiple,
|
||||||
expiresAt: init.poll.expiresAt,
|
expiresAt: init.poll.expiresAt ? new Date(init.poll.expiresAt).getTime().toString() : null,
|
||||||
expiredAfter: init.poll.expiredAfter,
|
expiredAfter: init.poll.expiredAfter ? new Date(init.poll.expiredAfter).getTime().toString() : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
visibility = init.visibility;
|
visibility = init.visibility;
|
||||||
|
|
|
@ -217,6 +217,7 @@ export type Note = {
|
||||||
clippedCount?: number;
|
clippedCount?: number;
|
||||||
poll?: {
|
poll?: {
|
||||||
expiresAt: DateString | null;
|
expiresAt: DateString | null;
|
||||||
|
expiredAfter: DateString | null;
|
||||||
multiple: boolean;
|
multiple: boolean;
|
||||||
choices: {
|
choices: {
|
||||||
isVoted: boolean;
|
isVoted: boolean;
|
||||||
|
|
Loading…
Reference in a new issue