Skip to content

Commit

Permalink
feat: check validity of schedule time and show warning notice
Browse files Browse the repository at this point in the history
  • Loading branch information
shuuji3 committed Mar 18, 2024
1 parent 5cee244 commit 13ad4e0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
43 changes: 30 additions & 13 deletions components/publish/PublishWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,28 +118,36 @@ 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.
// Mastodon API allows to set the scheduled time to 5 minutes in the future
// 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(() => {
Expand Down Expand Up @@ -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 />
Expand All @@ -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"
Expand Down Expand Up @@ -473,7 +490,7 @@ onDeactivated(() => {
p2
type="datetime-local"
name="schedule-datetime"
:min="minimumScheduledTime"
:min="getDatetimeInputFormat(minimumScheduledTime)"
>
</template>
</CommonDropdown>
Expand Down Expand Up @@ -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"
>
Expand All @@ -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>
Expand Down
1 change: 1 addition & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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..."
Expand Down

0 comments on commit 13ad4e0

Please sign in to comment.