Skip to content

Commit a5517e8

Browse files
authored
Merge pull request desktop#16340 from desktop/annouce-commit-button-status
Announce Committing Status
2 parents 0c5a3b9 + 0d54f03 commit a5517e8

File tree

1 file changed

+112
-36
lines changed

1 file changed

+112
-36
lines changed

app/src/ui/changes/commit-message.tsx

Lines changed: 112 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { isEmptyOrWhitespace } from '../../lib/is-empty-or-whitespace'
3636
import { TooltippedContent } from '../lib/tooltipped-content'
3737
import { TooltipDirection } from '../lib/tooltip'
3838
import { pick } from '../../lib/pick'
39+
import { delay } from 'lodash'
3940

4041
const addAuthorIcon = {
4142
w: 18,
@@ -140,6 +141,10 @@ interface ICommitMessageState {
140141
* false when there's no action bar.
141142
*/
142143
readonly descriptionObscured: boolean
144+
145+
readonly isCommittingStatusMessage: string
146+
147+
readonly startedCommitting: number | null
143148
}
144149

145150
function findUserAutoCompleteProvider(
@@ -178,6 +183,8 @@ export class CommitMessage extends React.Component<
178183
props.autocompletionProviders
179184
),
180185
descriptionObscured: false,
186+
isCommittingStatusMessage: '',
187+
startedCommitting: null,
181188
}
182189
}
183190

@@ -260,6 +267,14 @@ export class CommitMessage extends React.Component<
260267
) {
261268
this.coAuthorInputRef.current?.focus()
262269
}
270+
271+
if (
272+
prevProps.isCommitting !== this.props.isCommitting &&
273+
this.props.isCommitting &&
274+
this.state.isCommittingStatusMessage === ''
275+
) {
276+
this.setState({ isCommittingStatusMessage: this.getButtonTitle() })
277+
}
263278
}
264279

265280
private clearCommitMessage() {
@@ -316,14 +331,34 @@ export class CommitMessage extends React.Component<
316331
}
317332

318333
const timer = startTimer('create commit', this.props.repository)
334+
this.setState({ startedCommitting: new Date().getTime() })
319335
const commitCreated = await this.props.onCreateCommit(commitContext)
320336
timer.done()
321337

322338
if (commitCreated) {
323339
this.clearCommitMessage()
340+
this.updateCommitStatusMessage()
324341
}
325342
}
326343

344+
/** We want to give a couple seconds for voice reader to be able to read the
345+
* in progress message when commit is fast. */
346+
private updateCommitStatusMessage() {
347+
const timeSinceStartedCommitting = Math.abs(
348+
(this.state.startedCommitting ?? new Date().getTime()) -
349+
new Date().getTime()
350+
)
351+
const delayed = 2000 - timeSinceStartedCommitting
352+
delay(
353+
() =>
354+
this.setState({
355+
isCommittingStatusMessage: 'Committed Just Now',
356+
startedCommitting: null,
357+
}),
358+
delayed > 0 ? delayed : 0
359+
)
360+
}
361+
327362
private canCommit(): boolean {
328363
return (
329364
(this.props.anyFilesSelected === true && this.state.summary.length > 0) ||
@@ -658,53 +693,91 @@ export class CommitMessage extends React.Component<
658693
this.props.onShowFoldout({ type: FoldoutType.Branch })
659694
}
660695

661-
private renderSubmitButton() {
662-
const { isCommitting, branch, commitButtonText } = this.props
663-
const isSummaryBlank = isEmptyOrWhitespace(this.summaryOrPlaceholder)
664-
const buttonEnabled =
665-
(this.canCommit() || this.canAmend()) && !isCommitting && !isSummaryBlank
666-
667-
const loading = isCommitting ? <Loading /> : undefined
668-
669-
const isAmending = this.props.commitToAmend !== null
696+
private getButtonVerb() {
697+
const { isCommitting, commitToAmend } = this.props
670698

671699
const amendVerb = isCommitting ? 'Amending' : 'Amend'
672700
const commitVerb = isCommitting ? 'Committing' : 'Commit'
701+
const isAmending = commitToAmend !== null
673702

674-
const amendTitle = `${amendVerb} last commit`
675-
const commitTitle =
676-
branch !== null ? `${commitVerb} to ${branch}` : commitVerb
703+
return isAmending ? amendVerb : commitVerb
704+
}
677705

678-
let tooltip: string | undefined = undefined
706+
private getCommittingButtonText() {
707+
const { branch } = this.props
708+
const verb = this.getButtonVerb()
679709

680-
if (buttonEnabled) {
681-
tooltip = isAmending ? amendTitle : commitTitle
682-
} else {
683-
if (isSummaryBlank) {
684-
tooltip = `A commit summary is required to commit`
685-
} else if (!this.props.anyFilesSelected && this.props.anyFilesAvailable) {
686-
tooltip = `Select one or more files to commit`
687-
} else if (isCommitting) {
688-
tooltip = `Committing changes…`
689-
}
710+
if (branch === null) {
711+
return verb
690712
}
691713

692-
const defaultCommitContents =
693-
branch !== null ? (
694-
<>
695-
{commitVerb} to <strong>{branch}</strong>
696-
</>
697-
) : (
698-
commitVerb
699-
)
714+
return (
715+
<>
716+
{verb} to <strong>{branch}</strong>
717+
</>
718+
)
719+
}
720+
721+
private getCommittingButtonTitle() {
722+
const { branch } = this.props
723+
const verb = this.getButtonVerb()
724+
725+
if (branch === null) {
726+
return verb
727+
}
728+
729+
return `${verb} to ${branch}`
730+
}
731+
732+
private getButtonText() {
733+
const { commitToAmend, commitButtonText } = this.props
700734

701-
const defaultAmendContents = <>{amendVerb} last commit</>
735+
if (commitButtonText) {
736+
return commitButtonText
737+
}
738+
739+
const isAmending = commitToAmend !== null
740+
return isAmending ? this.getButtonTitle() : this.getCommittingButtonText()
741+
}
742+
743+
private getButtonTitle(): string {
744+
const { commitToAmend, commitButtonText } = this.props
702745

703-
const defaultContents = isAmending
704-
? defaultAmendContents
705-
: defaultCommitContents
746+
if (commitButtonText) {
747+
return commitButtonText
748+
}
749+
750+
const isAmending = commitToAmend !== null
751+
return isAmending
752+
? `${this.getButtonVerb()} last commit`
753+
: this.getCommittingButtonTitle()
754+
}
706755

707-
const commitButton = commitButtonText ? commitButtonText : defaultContents
756+
private getButtonTooltip(buttonEnabled: boolean) {
757+
if (buttonEnabled) {
758+
return this.getButtonTitle()
759+
}
760+
761+
const isSummaryBlank = isEmptyOrWhitespace(this.summaryOrPlaceholder)
762+
if (isSummaryBlank) {
763+
return `A commit summary is required to commit`
764+
} else if (!this.props.anyFilesSelected && this.props.anyFilesAvailable) {
765+
return `Select one or more files to commit`
766+
} else if (this.props.isCommitting) {
767+
return `Committing changes…`
768+
}
769+
770+
return undefined
771+
}
772+
773+
private renderSubmitButton() {
774+
const { isCommitting } = this.props
775+
const isSummaryBlank = isEmptyOrWhitespace(this.summaryOrPlaceholder)
776+
const buttonEnabled =
777+
(this.canCommit() || this.canAmend()) && !isCommitting && !isSummaryBlank
778+
const loading = isCommitting ? <Loading /> : undefined
779+
const tooltip = this.getButtonTooltip(buttonEnabled)
780+
const commitButton = this.getButtonText()
708781

709782
return (
710783
<Button
@@ -815,6 +888,9 @@ export class CommitMessage extends React.Component<
815888
{this.renderPermissionsCommitWarning()}
816889

817890
{this.renderSubmitButton()}
891+
<span className="sr-only" aria-live="polite">
892+
{this.state.isCommittingStatusMessage}
893+
</span>
818894
</div>
819895
)
820896
}

0 commit comments

Comments
 (0)