merge: Make schedule time work cross timezones (!819)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/819

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Charlotte <timo.herngreen@gmail.com>
This commit is contained in:
Marie 2024-12-17 20:29:33 +00:00
commit 3b5e3fd460
5 changed files with 28 additions and 42 deletions

View file

@ -141,11 +141,11 @@
"juice": "11.0.0", "juice": "11.0.0",
"megalodon": "workspace:*", "megalodon": "workspace:*",
"meilisearch": "0.45.0", "meilisearch": "0.45.0",
"juice": "11.0.0",
"microformats-parser": "2.0.2", "microformats-parser": "2.0.2",
"mime-types": "2.1.35", "mime-types": "2.1.35",
"misskey-js": "workspace:*", "misskey-js": "workspace:*",
"misskey-reversi": "workspace:*", "misskey-reversi": "workspace:*",
"moment": "^2.30.1",
"ms": "3.0.0-canary.1", "ms": "3.0.0-canary.1",
"nanoid": "5.0.8", "nanoid": "5.0.8",
"nested-property": "4.0.0", "nested-property": "4.0.0",

View file

@ -6,6 +6,7 @@
import ms from 'ms'; import ms from 'ms';
import { In } from 'typeorm'; import { In } from 'typeorm';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import moment from 'moment';
import { isPureRenote } from '@/misc/is-renote.js'; import { isPureRenote } from '@/misc/is-renote.js';
import type { MiUser } from '@/models/User.js'; import type { MiUser } from '@/models/User.js';
import type { import type {
@ -307,7 +308,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.poll) { if (ps.poll) {
let scheduleNote_scheduledAt = Date.now(); let scheduleNote_scheduledAt = Date.now();
if (typeof ps.scheduleNote.scheduledAt === 'number') { 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 (typeof ps.poll.expiresAt === 'number') {
if (ps.poll.expiresAt < scheduleNote_scheduledAt) { 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 (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); throw new ApiError(meta.errors.cannotCreateAlreadyExpiredSchedule);
} }
} else { } else {
@ -347,14 +348,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (ps.scheduleNote.scheduledAt) { if (ps.scheduleNote.scheduledAt) {
me.token = null; me.token = null;
const noteId = this.idService.gen(new Date().getTime()); const noteId = this.idService.gen(new Date().getTime());
const schedNoteLocalTime = moment.utc(ps.scheduleNote.scheduledAt).local().valueOf();
await this.noteScheduleRepository.insert({ await this.noteScheduleRepository.insert({
id: noteId, id: noteId,
note: note, note: note,
userId: me.id, 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), { await this.queueService.ScheduleNotePostQueue.add(String(delay), {
scheduleNoteId: noteId, scheduleNoteId: noteId,
}, { }, {

View file

@ -57,6 +57,7 @@
"misskey-bubble-game": "workspace:*", "misskey-bubble-game": "workspace:*",
"misskey-js": "workspace:*", "misskey-js": "workspace:*",
"misskey-reversi": "workspace:*", "misskey-reversi": "workspace:*",
"moment": "^2.30.1",
"photoswipe": "5.4.4", "photoswipe": "5.4.4",
"punycode": "2.3.1", "punycode": "2.3.1",
"rollup": "4.26.0", "rollup": "4.26.0",

View file

@ -18,6 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';
import moment from 'moment';
import MkInput from '@/components/MkInput.vue'; import MkInput from '@/components/MkInput.vue';
import { formatDateTimeString } from '@/scripts/format-time-string.js'; import { formatDateTimeString } from '@/scripts/format-time-string.js';
import { addTime } from '@/scripts/time.js'; import { addTime } from '@/scripts/time.js';
@ -46,7 +47,7 @@ if (props.modelValue.scheduledAt) {
function get() { function get() {
const calcAt = () => { const calcAt = () => {
return new Date(`${ atDate.value } ${ atTime.value }`).getTime(); return moment(`${ atDate.value } ${ atTime.value }`).utc().valueOf();
}; };
return { scheduledAt: calcAt() }; return { scheduledAt: calcAt() };

View file

@ -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) 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': '@nestjs/testing':
specifier: 10.4.7 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': '@peertube/http-signature':
specifier: 1.7.0 specifier: 1.7.0
version: 1.7.0 version: 1.7.0
@ -320,6 +320,9 @@ importers:
misskey-reversi: misskey-reversi:
specifier: workspace:* specifier: workspace:*
version: link:../misskey-reversi version: link:../misskey-reversi
moment:
specifier: ^2.30.1
version: 2.30.1
ms: ms:
specifier: 3.0.0-canary.1 specifier: 3.0.0-canary.1
version: 3.0.0-canary.1 version: 3.0.0-canary.1
@ -832,6 +835,9 @@ importers:
misskey-reversi: misskey-reversi:
specifier: workspace:* specifier: workspace:*
version: link:../misskey-reversi version: link:../misskey-reversi
moment:
specifier: ^2.30.1
version: 2.30.1
photoswipe: photoswipe:
specifier: 5.4.4 specifier: 5.4.4
version: 5.4.4 version: 5.4.4
@ -1194,7 +1200,7 @@ importers:
version: 7.17.0(eslint@9.14.0)(typescript@5.6.3) version: 7.17.0(eslint@9.14.0)(typescript@5.6.3)
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: 1.6.0 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': '@vue/runtime-core':
specifier: 3.5.12 specifier: 3.5.12
version: 3.5.12 version: 3.5.12
@ -8425,6 +8431,9 @@ packages:
module-details-from-path@1.0.3: module-details-from-path@1.0.3:
resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==}
moment@2.30.1:
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
ms@2.0.0: ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@ -13269,7 +13278,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - 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: dependencies:
'@nestjs/common': 10.4.7(reflect-metadata@0.2.2)(rxjs@7.8.1) '@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/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: transitivePeerDependencies:
- supports-color - 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: dependencies:
'@ampproject/remapping': 2.2.1 '@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3 '@bcoe/v8-coverage': 0.2.3
@ -15505,7 +15514,7 @@ snapshots:
std-env: 3.7.0 std-env: 3.7.0
strip-literal: 2.1.0 strip-literal: 2.1.0
test-exclude: 6.0.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: transitivePeerDependencies:
- supports-color - supports-color
@ -19348,35 +19357,6 @@ snapshots:
jsdoc-type-pratt-parser@4.1.0: {} 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): jsdom@24.1.1(bufferutil@4.0.7)(utf-8-validate@6.0.3):
dependencies: dependencies:
cssstyle: 4.0.1 cssstyle: 4.0.1
@ -20215,6 +20195,8 @@ snapshots:
module-details-from-path@1.0.3: {} module-details-from-path@1.0.3: {}
moment@2.30.1: {}
ms@2.0.0: {} ms@2.0.0: {}
ms@2.1.2: {} ms@2.1.2: {}
@ -22848,7 +22830,7 @@ snapshots:
- supports-color - supports-color
- terser - 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: dependencies:
'@vitest/expect': 1.6.0 '@vitest/expect': 1.6.0
'@vitest/runner': 1.6.0 '@vitest/runner': 1.6.0
@ -22873,7 +22855,7 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/node': 22.9.0 '@types/node': 22.9.0
happy-dom: 10.0.3 happy-dom: 10.0.3
jsdom: 24.1.1 jsdom: 24.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4)
transitivePeerDependencies: transitivePeerDependencies:
- less - less
- lightningcss - lightningcss