Add UI for Scheduled Post

This commit is contained in:
Otavio Cordeiro 2023-04-05 15:01:15 +02:00
parent baae9b8cad
commit 37af7ef22f
2 changed files with 113 additions and 18 deletions

View File

@ -34,10 +34,10 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
public onOpen() {
super.onOpen()
const {contentEl} = this
const { contentEl } = this
contentEl.empty()
contentEl.createEl('h2', {text: 'Review'})
contentEl.createEl('h2', { text: 'Review' })
new Setting(contentEl)
.setName('Title')
@ -47,7 +47,8 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
.setValue(this.viewModel.title)
.onChange(value => {
this.viewModel.title = value
}))
})
)
.addExtraButton(button => button
.setIcon('cross')
.setTooltip('Remove title')
@ -77,7 +78,8 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
.setValue(this.viewModel.tags)
.onChange(value => {
this.viewModel.tags = value
}))
})
)
.addExtraButton(button => button
.setIcon('plus')
.setTooltip('Add categories')
@ -100,25 +102,47 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
})
)
new Setting(contentEl)
.setName('Scheduled date')
.setDesc('Scheduled date is optional and used to schedule posts to be published in the future. If empty it will use the current date and time.')
.addText(text => text
.setPlaceholder('YYYY-MM-DD HH:MM')
.setValue(this.viewModel.scheduledDate)
.onChange(value => {
this.viewModel.scheduledDate = value
})
)
.addExtraButton(button => button
.setIcon('cross')
.setTooltip('Clear date')
.onClick(() => {
this.viewModel.clearDate()
})
)
new Setting(contentEl)
.addButton(button => button
.setButtonText('Publish')
.setCta()
.onClick(async _ => {
button
.setDisabled(true)
.removeCta()
.setButtonText('Publishing...')
await this.viewModel.publishNote()
})
.then(_ => {
if (this.viewModel.showPublishingButton) {
button
.setDisabled(true)
.removeCta()
.setButtonText('Publishing...')
}
})
)
.setDesc(this.viewModel.showInvalidDateMessage ? "Invalid date format" : "")
}
public onClose() {
super.onClose()
const {contentEl} = this
const { contentEl } = this
contentEl.empty()
this.viewModel.delegate = undefined
@ -130,6 +154,10 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
this.onOpen()
}
public publishDidClearDate() {
this.onOpen()
}
public publishDidSucceed(response: PublishResponse) {
this.makeConfirmationView(response)
}
@ -142,30 +170,34 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
this.onOpen()
}
public publishDidValidateDate() {
this.onOpen()
}
// Private
private makeConfirmationView(response: PublishResponse) {
const {contentEl} = this
const { contentEl } = this
contentEl.empty()
contentEl.createEl('h2', {text: 'Published'})
contentEl.createEl('a', {text: 'Open post URL', href: response.url})
contentEl.createEl('h2', { text: 'Published' })
contentEl.createEl('a', { text: 'Open post URL', href: response.url })
contentEl.createEl('br')
contentEl.createEl('a', {text: 'Open post Preview URL', href: response.preview})
contentEl.createEl('a', { text: 'Open post Preview URL', href: response.preview })
contentEl.createEl('br')
contentEl.createEl('a', {text: 'Open post Edit URL', href: response.edit})
contentEl.createEl('a', { text: 'Open post Edit URL', href: response.edit })
}
private makeMessageView(
title: string,
message: string
) {
const {contentEl} = this
const { contentEl } = this
contentEl.empty()
contentEl.createEl('h2', {text: title})
contentEl.createEl('p', {text: message})
contentEl.createEl('h2', { text: title })
contentEl.createEl('p', { text: message })
}
}

View File

@ -14,6 +14,10 @@ export interface PublishViewModelDelegate {
// title property is reset.
publishDidClearTitle(): void
// triggered when user clicks the clear button when the
// date property is reset.
publishDidClearDate(): void
// Triggered when publishing a new post succeeds.
publishDidSucceed(response: PublishResponse): void
@ -22,6 +26,11 @@ export interface PublishViewModelDelegate {
// Triggered when selecting a tag from the picker.
publishDidSelectTag(): void
// Triggered after checking whether the scheduled date
// is valid or not. It returns `true` for no date or for
// valid date, and false for invalid dates.
publishDidValidateDate(): void
}
/*
@ -33,11 +42,14 @@ export class PublishViewModel implements TagSuggestionDelegate {
// Properties
public delegate?: PublishViewModelDelegate
private isValidDate: boolean
private isSubmitting: boolean
private titleWrappedValue: string
private content: string
private visibilityWrappedValue: string
private tagsWrappedValue: string
private selectedBlogIDWrappedValue: string
private scheduledDateWrappedValue: string
private networkClient: NetworkClientInterface
private networkRequestFactory: NetworkRequestFactoryInterface
private viewModelFactory: ViewModelFactoryInterface
@ -62,6 +74,9 @@ export class PublishViewModel implements TagSuggestionDelegate {
this.visibilityWrappedValue = visibility
this.blogs = blogs
this.selectedBlogIDWrappedValue = selectedBlogID
this.scheduledDateWrappedValue = ''
this.isValidDate = true
this.isSubmitting = false
this.networkClient = networkClient
this.networkRequestFactory = networkRequestFactory
this.viewModelFactory = viewModelFactory
@ -109,7 +124,28 @@ export class PublishViewModel implements TagSuggestionDelegate {
console.log('Selected blog changed: ' + value)
}
public get scheduledDate(): string {
return this.scheduledDateWrappedValue
}
public set scheduledDate(value: string) {
this.scheduledDateWrappedValue = value
console.log('Scheduled date changed: ' + value)
}
public get showPublishingButton(): boolean {
return this.isValidDate && this.isSubmitting
}
public get showInvalidDateMessage(): boolean {
return !this.isValidDate
}
public async publishNote() {
if (!this.validateDateAndContinue()) {
return
}
try {
const response = this.networkRequestFactory.makePublishRequest(
this.title,
@ -146,6 +182,33 @@ export class PublishViewModel implements TagSuggestionDelegate {
)
}
public clearDate() {
this.scheduledDateWrappedValue = ''
this.isValidDate = true
this.delegate?.publishDidClearDate()
}
// Private
private validateDateAndContinue(): boolean {
const scheduledDate = new Date(this.scheduledDateWrappedValue)
const isInvalidDate = isNaN(scheduledDate.getTime())
if (this.scheduledDateWrappedValue.length > 0 && isInvalidDate) {
this.isValidDate = false
this.isSubmitting = false
this.delegate?.publishDidValidateDate()
return false
}
this.isValidDate = true
this.isSubmitting = true
this.delegate?.publishDidValidateDate()
return true
}
// TagSuggestionDelegate
public tagSuggestionDidSelectTag(category: string) {