feat: check validity of schedule time and show warning notice

pull/2643/head
TAKAHASHI Shuuji 2024-03-04 02:35:53 +09:00
rodzic 5cee244d0f
commit 13ad4e0a58
2 zmienionych plików z 31 dodań i 13 usunięć

Wyświetl plik

@ -118,14 +118,19 @@ const expiresInOptions = computed(() => [
const expiresInDefaultOptionIndex = 2
const scheduledTime = ref('')
watchEffect(() => {
draft.value.params.scheduledAt = scheduledTime.value
const now = useNow({ interval: 1000 })
const minimumScheduledTime = computed(() => getMinimumScheduledTime(now.value))
const isValidScheduledTime = computed(() => {
if (scheduledTime.value === '')
return true
const scheduledTimeDate = new Date(scheduledTime.value)
return minimumScheduledTime.value.getTime() <= scheduledTimeDate.getTime()
})
const now = useNow({ interval: 1000 })
const minimumScheduledTime = ref()
watchEffect(() => {
minimumScheduledTime.value = getMinimumScheduledTime(now.value)
draft.value.params.scheduledAt = scheduledTime.value
})
// Calculate the minimum scheduled time.
@ -133,13 +138,16 @@ watchEffect(() => {
// but if the specified scheduled time is less than 5 minutes, Mastodon will
// send the post immediately.
// To prevent this, we add a buffer and round up the minutes.
function getMinimumScheduledTime(now: Date): string {
function getMinimumScheduledTime(now: Date): Date {
const bufferInSec = 5 + 5 * 60 // + 5 minutes and 5 seconds
const nowInSec = Math.floor(now.getTime() / 1000)
const bufferedTimeInSec
= Math.ceil((nowInSec + bufferInSec) / 60) * 60
const minimumScheduledTime = new Date(bufferedTimeInSec * 1000)
return minimumScheduledTime.toISOString().slice(0, 16)
return new Date(bufferedTimeInSec * 1000)
}
function getDatetimeInputFormat(time: Date) {
return time.toISOString().slice(0, 16)
}
const characterCount = computed(() => {
@ -284,9 +292,9 @@ onDeactivated(() => {
<div aria-hidden="true" i-ri:error-warning-fill />
<p>{{ scheduledTime ? $t('state.schedule_failed') : $t('state.publish_failed') }}</p>
</div>
<CommonTooltip placement="bottom" :content="scheduledTime ? $t('state.clear_schedule_failed') : $t('action.clear_publish_failed')">
<CommonTooltip placement="bottom" :content="scheduledTime ? $t('action.clear_schedule_failed') : $t('action.clear_publish_failed')">
<button
flex rounded-4 p1 hover:bg-active cursor-pointer transition-100 :aria-label="scheduledTime ? $t('state.clear_schedule_failed') : $t('action.clear_publish_failed')"
flex rounded-4 p1 hover:bg-active cursor-pointer transition-100 :aria-label="scheduledTime ? $t('action.clear_schedule_failed') : $t('action.clear_publish_failed')"
@click="failedMessages = []"
>
<span aria-hidden="true" w="1.75em" h="1.75em" i-ri:close-line />
@ -301,6 +309,15 @@ onDeactivated(() => {
</ol>
</CommonErrorMessage>
<CommonErrorMessage v-if="!isValidScheduledTime" described-by="scheduled-time-invalid" pt-2>
<header id="scheduled-time-invalid" flex justify-between>
<div flex items-center gap-x-2 font-bold>
<div aria-hidden="true" i-ri:error-warning-fill />
<p>{{ $t('state.schedule_time_invalid', [minimumScheduledTime.toLocaleString()]) }}</p>
</div>
</header>
</CommonErrorMessage>
<div relative flex-1 flex flex-col>
<EditorContent
:editor="editor"
@ -473,7 +490,7 @@ onDeactivated(() => {
p2
type="datetime-local"
name="schedule-datetime"
:min="minimumScheduledTime"
:min="getDatetimeInputFormat(minimumScheduledTime)"
>
</template>
</CommonDropdown>
@ -528,7 +545,7 @@ onDeactivated(() => {
btn-solid rounded-3 text-sm w-full flex="~ gap1" items-center
md:w-fit
class="publish-button"
:aria-disabled="isPublishDisabled || isExceedingCharacterLimit"
:aria-disabled="isPublishDisabled || isExceedingCharacterLimit || !isValidScheduledTime"
aria-describedby="publish-tooltip"
@click="publish"
>
@ -539,8 +556,8 @@ onDeactivated(() => {
<div block i-carbon:face-dizzy-filled />
</span>
<span v-if="draft.editingStatus">{{ $t('action.save_changes') }}</span>
<span v-else-if="draft.params.inReplyToId">{{ $t('action.reply') }}</span>
<span v-else-if="scheduledTime">{{ !isSending ? $t('action.schedule') : $t('state.scheduling') }}</span>
<span v-else-if="draft.params.inReplyToId">{{ $t('action.reply') }}</span>
<span v-else>{{ !isSending ? $t('action.publish') : $t('state.publishing') }}</span>
</button>
</CommonTooltip>

Wyświetl plik

@ -601,6 +601,7 @@
"publishing": "Publishing",
"save_failed": "Save failed",
"schedule_failed": "Schedule failed",
"schedule_time_invalid": "The scheduled time must be at least 5 minutes later in the future. Set to {0} or later.",
"scheduling": "Scheduling",
"upload_failed": "Upload failed",
"uploading": "Uploading..."