From e50ff9db6ae91e1ad34bc50935300515841bf719 Mon Sep 17 00:00:00 2001 From: Marie <github@yuugi.dev> Date: Sun, 15 Dec 2024 22:41:16 +0100 Subject: [PATCH] upd: make schedule time work cross timezones --- packages/backend/package.json | 2 +- .../api/endpoints/notes/schedule/create.ts | 10 ++-- packages/frontend/package.json | 1 + .../src/components/MkScheduleEditor.vue | 3 +- pnpm-lock.yaml | 54 +++++++------------ 5 files changed, 28 insertions(+), 42 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 702b788061..dd6c9cc792 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -141,11 +141,11 @@ "juice": "11.0.0", "megalodon": "workspace:*", "meilisearch": "0.45.0", - "juice": "11.0.0", "microformats-parser": "2.0.2", "mime-types": "2.1.35", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", + "moment": "^2.30.1", "ms": "3.0.0-canary.1", "nanoid": "5.0.8", "nested-property": "4.0.0", diff --git a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts index 7d20b6b82a..c6032fbdae 100644 --- a/packages/backend/src/server/api/endpoints/notes/schedule/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/schedule/create.ts @@ -6,6 +6,7 @@ import ms from 'ms'; import { In } from 'typeorm'; import { Inject, Injectable } from '@nestjs/common'; +import moment from 'moment'; import { isPureRenote } from '@/misc/is-renote.js'; import type { MiUser } from '@/models/User.js'; import type { @@ -307,7 +308,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (ps.poll) { let scheduleNote_scheduledAt = Date.now(); if (typeof ps.scheduleNote.scheduledAt === 'number') { - scheduleNote_scheduledAt = ps.scheduleNote.scheduledAt; + scheduleNote_scheduledAt = moment.utc(ps.scheduleNote.scheduledAt).local().valueOf(); } if (typeof ps.poll.expiresAt === 'number') { if (ps.poll.expiresAt < scheduleNote_scheduledAt) { @@ -318,7 +319,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- } } if (typeof ps.scheduleNote.scheduledAt === 'number') { - if (ps.scheduleNote.scheduledAt < Date.now()) { + if (moment.utc(ps.scheduleNote.scheduledAt).local().valueOf() < Date.now()) { throw new ApiError(meta.errors.cannotCreateAlreadyExpiredSchedule); } } else { @@ -347,14 +348,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- if (ps.scheduleNote.scheduledAt) { me.token = null; const noteId = this.idService.gen(new Date().getTime()); + const schedNoteLocalTime = moment.utc(ps.scheduleNote.scheduledAt).local().valueOf(); await this.noteScheduleRepository.insert({ id: noteId, note: note, userId: me.id, - scheduledAt: new Date(ps.scheduleNote.scheduledAt), + scheduledAt: new Date(schedNoteLocalTime), }); - const delay = new Date(ps.scheduleNote.scheduledAt).getTime() - Date.now(); + const delay = new Date(schedNoteLocalTime).getTime() - Date.now(); await this.queueService.ScheduleNotePostQueue.add(String(delay), { scheduleNoteId: noteId, }, { diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 752b6cb388..ce3fd90a86 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -57,6 +57,7 @@ "misskey-bubble-game": "workspace:*", "misskey-js": "workspace:*", "misskey-reversi": "workspace:*", + "moment": "^2.30.1", "photoswipe": "5.4.4", "punycode": "2.3.1", "rollup": "4.26.0", diff --git a/packages/frontend/src/components/MkScheduleEditor.vue b/packages/frontend/src/components/MkScheduleEditor.vue index f40d37c962..695a474998 100644 --- a/packages/frontend/src/components/MkScheduleEditor.vue +++ b/packages/frontend/src/components/MkScheduleEditor.vue @@ -18,6 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { onMounted, ref, watch } from 'vue'; +import moment from 'moment'; import MkInput from '@/components/MkInput.vue'; import { formatDateTimeString } from '@/scripts/format-time-string.js'; import { addTime } from '@/scripts/time.js'; @@ -46,7 +47,7 @@ if (props.modelValue.scheduledAt) { function get() { const calcAt = () => { - return new Date(`${ atDate.value } ${ atTime.value }`).getTime(); + return moment(`${ atDate.value } ${ atTime.value }`).utc().valueOf(); }; return { scheduledAt: calcAt() }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d01454e892..39956522fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -139,7 +139,7 @@ importers: version: 10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/testing': specifier: 10.4.7 - version: 10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7)) + version: 10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7)(@nestjs/platform-express@10.4.7) '@peertube/http-signature': specifier: 1.7.0 version: 1.7.0 @@ -320,6 +320,9 @@ importers: misskey-reversi: specifier: workspace:* version: link:../misskey-reversi + moment: + specifier: ^2.30.1 + version: 2.30.1 ms: specifier: 3.0.0-canary.1 version: 3.0.0-canary.1 @@ -832,6 +835,9 @@ importers: misskey-reversi: specifier: workspace:* version: link:../misskey-reversi + moment: + specifier: ^2.30.1 + version: 2.30.1 photoswipe: specifier: 5.4.4 version: 5.4.4 @@ -1194,7 +1200,7 @@ importers: version: 7.17.0(eslint@9.14.0)(typescript@5.6.3) '@vitest/coverage-v8': specifier: 1.6.0 - version: 1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0)) + version: 1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0)) '@vue/runtime-core': specifier: 3.5.12 version: 3.5.12 @@ -8425,6 +8431,9 @@ packages: module-details-from-path@1.0.3: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -13269,7 +13278,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/testing@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7))': + '@nestjs/testing@10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.7)(@nestjs/platform-express@10.4.7)': dependencies: '@nestjs/common': 10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.4.7(@nestjs/common@10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.7)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -15490,7 +15499,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0))': + '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0))': dependencies: '@ampproject/remapping': 2.2.1 '@bcoe/v8-coverage': 0.2.3 @@ -15505,7 +15514,7 @@ snapshots: std-env: 3.7.0 strip-literal: 2.1.0 test-exclude: 6.0.0 - vitest: 1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0) + vitest: 1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0) transitivePeerDependencies: - supports-color @@ -19348,35 +19357,6 @@ snapshots: jsdoc-type-pratt-parser@4.1.0: {} - jsdom@24.1.1: - dependencies: - cssstyle: 4.0.1 - data-urls: 5.0.0 - decimal.js: 10.4.3 - form-data: 4.0.1 - html-encoding-sniffer: 4.0.0 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.12 - parse5: 7.2.1 - rrweb-cssom: 0.7.1 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 3.1.1 - whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 - ws: 8.18.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) - xml-name-validator: 5.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - optional: true - jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3): dependencies: cssstyle: 4.0.1 @@ -20215,6 +20195,8 @@ snapshots: module-details-from-path@1.0.3: {} + moment@2.30.1: {} + ms@2.0.0: {} ms@2.1.2: {} @@ -22848,7 +22830,7 @@ snapshots: - supports-color - terser - vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1)(sass@1.79.4)(terser@5.36.0): + vitest@1.6.0(@types/node@22.9.0)(happy-dom@10.0.3)(jsdom@24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4))(sass@1.79.4)(terser@5.36.0): dependencies: '@vitest/expect': 1.6.0 '@vitest/runner': 1.6.0 @@ -22873,7 +22855,7 @@ snapshots: optionalDependencies: '@types/node': 22.9.0 happy-dom: 10.0.3 - jsdom: 24.1.1 + jsdom: 24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) transitivePeerDependencies: - less - lightningcss -- GitLab