Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Number formatting using Intl.* APIs #14174

Merged
merged 1,923 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
1923 commits
Select commit Hold shift + click to select a range
91ed597
Remove unnecessary cast to any
sergiou87 Feb 23, 2023
2eab0b4
Set `aria-haspopup` prop
sergiou87 Feb 23, 2023
0b6dc8e
(WIP) Some changes to tag autocomplete items properly
sergiou87 Feb 23, 2023
21336fa
Make screen readers read autocomplete suggestions
sergiou87 Mar 7, 2023
6e09df7
Fix unknown user autocomplete item
sergiou87 Mar 7, 2023
ddf70a8
Fix a11y attributes for autocomplete items
sergiou87 Mar 7, 2023
7544810
Make screen reader read number of co-author suggestions
sergiou87 Mar 7, 2023
617be99
Some cleanup (or not)
sergiou87 Mar 7, 2023
7da372d
(WIP) Try things
sergiou87 Mar 8, 2023
669257d
First steps to make AutocompletingTextInput accessible
sergiou87 Mar 8, 2023
ab5314b
(WIP) Use AutocompletingInput for co-authors
sergiou87 Mar 9, 2023
63051fc
Some work to make the Co-Authors textbox look good
sergiou87 Mar 9, 2023
191c0d0
Use autocompletion to get co-authors!
sergiou87 Mar 9, 2023
dfdd3f3
Create Co-Author autocompletion provider
sergiou87 Mar 10, 2023
01f7234
Add support for "unknown" users in our autocompletion component
sergiou87 Mar 10, 2023
467c228
Only show "Search user" entry when needed
sergiou87 Mar 10, 2023
2fec3d3
Always show autocomplete for co-authors
sergiou87 Mar 10, 2023
dd6f6f7
Use different IDs when autocomplete list is refreshed
sergiou87 Mar 10, 2023
c25db50
Add aria-live with number of suggestions
sergiou87 Mar 13, 2023
a7e7b70
More co-author input improvements. Needs cleanup!
sergiou87 Mar 13, 2023
b2b0070
Add name to added handle aria label
sergiou87 Mar 14, 2023
abb0855
Merge pull request #16274 from desktop/commit-attribution-descriptive…
tidy-dev Mar 14, 2023
71187ad
Add tabIndex -1 to menu items
tidy-dev Mar 14, 2023
0092b61
Make button be a menuitem
tidy-dev Mar 14, 2023
cfadaae
Bubble up unknown authors instead of keeping them as internal state
sergiou87 Mar 14, 2023
4cee176
On menu open through space/enter, select first item
tidy-dev Mar 14, 2023
0bdd850
Stop pane from stealing focus from first selected item
tidy-dev Mar 14, 2023
9dadbc8
Add icons for unknown authors added
sergiou87 Mar 14, 2023
d067454
Search for unknown users to add them as co-authors!
sergiou87 Mar 14, 2023
f080c8d
Clean up
sergiou87 Mar 14, 2023
b3d2382
Open autocomplete list without selected item
sergiou87 Mar 14, 2023
de4a6d6
Take username casing into account
sergiou87 Mar 14, 2023
5e49796
Detect use of space at the end of input and attempt autocomplete
sergiou87 Mar 14, 2023
a74b2d7
More cleanup
sergiou87 Mar 14, 2023
c87c6a8
Improve types
sergiou87 Mar 14, 2023
39dfe10
More and better comments
sergiou87 Mar 14, 2023
734528e
Display autocomplete above element when needed
sergiou87 Mar 14, 2023
58c436d
Select last author instead of deleting it when pressing backspace
sergiou87 Mar 14, 2023
81b431c
Be smart about next selected author after removing one
sergiou87 Mar 14, 2023
94e862a
Add overflow-y to dialogs
tidy-dev Mar 14, 2023
e363a9a
Make preferences dialog scroll vertically when zoomed
tidy-dev Mar 14, 2023
e3bfe23
Move uncommitted changes preference to prompts tab
niik Mar 14, 2023
922bc77
Bump webpack from 5.68.0 to 5.76.0
dependabot[bot] Mar 14, 2023
75ae97c
Improve accessibility of AutocompletingTextInput component
sergiou87 Mar 15, 2023
35fbb2d
Remove : from emoji suggestion list
sergiou87 Mar 16, 2023
4a2d721
Fix issue autocompletion style and accessibility
sergiou87 Mar 16, 2023
733a514
Add aria-haspopup to menu bar buttons
tidy-dev Mar 16, 2023
bf4b48e
Docs to aria attributtes
tidy-dev Mar 16, 2023
29c9dc2
Merge pull request #16313 from desktop/preference-tweaks
niik Mar 16, 2023
cf50f5a
Add aria-labellby to windows menus
tidy-dev Mar 16, 2023
99f7474
Merge pull request #16317 from desktop/scrollable-dialogs
tidy-dev Mar 16, 2023
21ffd81
Remove focus logic - I think is unneeded.
tidy-dev Mar 16, 2023
ac90008
Add menu items to resize main view width
tidy-dev Mar 16, 2023
ea9038d
Add the functionality to app store
tidy-dev Mar 16, 2023
e7acc4e
Docs..
tidy-dev Mar 16, 2023
ab42584
lowercase w
tidy-dev Mar 16, 2023
d9f42e8
Merge pull request #16324 from desktop/autocompleting-input-a11y
sergiou87 Mar 17, 2023
9d59b67
Merge branch 'development' into co-author-accessibility-fixes
sergiou87 Mar 17, 2023
7432214
Fix typo
sergiou87 Mar 17, 2023
9d100eb
Add new stats for PR comment notifications
sergiou87 Mar 17, 2023
51a2ef6
Record new PR comment notification stats
sergiou87 Mar 17, 2023
4a41306
Disable select on hover for autocompletion lists
sergiou87 Mar 17, 2023
9c82ce6
Use author username/name as handle `key`
sergiou87 Mar 17, 2023
b7f7988
Fix check when updating autocompleting list :facepalm:
sergiou87 Mar 17, 2023
538c201
Switch focus after component is rendered
sergiou87 Mar 17, 2023
fb2f310
Announce when authors are added/removed
sergiou87 Mar 17, 2023
d00631a
Co-authors labelled with all added co-authors
sergiou87 Mar 17, 2023
8c6808a
Fix author labelling for screen reader
sergiou87 Mar 17, 2023
0eb57b6
Move code around
sergiou87 Mar 17, 2023
2a5e465
Fix labelling of user not found
sergiou87 Mar 17, 2023
8328a9c
Add Zed as an external editor option
JosephTLyons Mar 17, 2023
f508eb7
Add new RStudio bundle identifier
steveward Mar 17, 2023
44eac84
Merge pull request #16320 from desktop/dependabot/npm_and_yarn/webpac…
sergiou87 Mar 17, 2023
e49c1a7
Announce Committing Status/Move to Undo on Completion
tidy-dev Mar 17, 2023
5d12981
Make reused method
tidy-dev Mar 17, 2023
8498eb2
Make the linter happy
steveward Mar 17, 2023
d73fefb
Typing by HTMLAttributes
tidy-dev Mar 20, 2023
083a4d0
Bump peter-evans/create-pull-request from 4.2.3 to 4.2.4
dependabot[bot] Mar 20, 2023
2d64e0f
More deterministic approach - think my brain wasn't working Friday
tidy-dev Mar 20, 2023
baae169
For first time undo displays
tidy-dev Mar 20, 2023
03330ae
Match button text - condense repeated code
tidy-dev Mar 20, 2023
6b6fc05
Tidying..
tidy-dev Mar 20, 2023
be2b4ef
Tidying.. - make sure amending gets right message
tidy-dev Mar 20, 2023
77930f5
Tidying
tidy-dev Mar 20, 2023
83e41c6
Merge pull request #16346 from desktop/dependabot/github_actions/pete…
tidy-dev Mar 20, 2023
508eb23
Merge pull request #16334 from desktop/pr-comment-notification-metrics
sergiou87 Mar 21, 2023
171874e
Merge pull request #16339 from desktop/fix-rstudio-macos
sergiou87 Mar 21, 2023
1397a87
Replace dialog `header` with `div`
sergiou87 Mar 21, 2023
6ffc1af
Merge pull request #16350 from desktop/dialog-header-is-div
sergiou87 Mar 22, 2023
ea73aeb
Use HTMLElement
tidy-dev Mar 22, 2023
25c146d
Revert undo focus changes
tidy-dev Mar 22, 2023
47083e2
Announce just committed and delay removal of loading message
tidy-dev Mar 22, 2023
9d25a96
Use one message
tidy-dev Mar 22, 2023
b4b2d82
Focus Changes/History view when accessed via shortcut
sergiou87 Mar 23, 2023
e61ce4d
Use role=combobox for co-authors input
sergiou87 Mar 23, 2023
8238146
Refactor co-author render and allow tabbing into the list
sergiou87 Mar 23, 2023
80d82f3
Fix focusing added authors with (shift+)tab
sergiou87 Mar 23, 2023
e9b0d1f
Update app/src/lib/api.ts
niik Mar 23, 2023
42257ff
Update commit-message.tsx
tidy-dev Mar 23, 2023
efbc5b0
Merge pull request #16315 from desktop/windows-app-menu-screen-reader…
tidy-dev Mar 23, 2023
bc4a096
Release 3.2.1-beta2
tidy-dev Mar 23, 2023
0c5a3b9
Merge pull request #16360 from desktop/focus-history-and-changes
sergiou87 Mar 23, 2023
65488d4
Don't need mostRecentLocalCommit anymore
tidy-dev Mar 23, 2023
0d54f03
Delay if time > 0
tidy-dev Mar 23, 2023
af13ec0
Merge branch 'development' into releases/3.2.1-beta2
tidy-dev Mar 23, 2023
0d1fb20
Add focus history/changes list fix
tidy-dev Mar 23, 2023
a5517e8
Merge pull request #16340 from desktop/annouce-commit-button-status
tidy-dev Mar 23, 2023
406785f
Update changelog.json
tidy-dev Mar 23, 2023
96b42f9
Update changelog.json
tidy-dev Mar 23, 2023
7574eff
Add remove button to author handles
sergiou87 Mar 23, 2023
8bd19fa
update bitbucket.md integration docs
dereklowlind Mar 23, 2023
ae7c15d
Update changelog.json
sergiou87 Mar 23, 2023
92403fe
Use overflow-y auto not scroll
tidy-dev Mar 23, 2023
58e6f81
Merge pull request #16367 from desktop/windows-menu-scroll-overflow
tidy-dev Mar 23, 2023
ffda449
Lint
niik Mar 23, 2023
d6cb971
Merge pull request #16362 from desktop/releases/3.2.1-beta2
tidy-dev Mar 23, 2023
00cb5cc
Merge pull request #16338 from JosephTLyons/add-Zed-as-an-external-ed…
niik Mar 23, 2023
47ecc3a
Add warning for commits with unknown authors
sergiou87 Mar 24, 2023
b6361f4
Add styling for Unknown Authors dialog
sergiou87 Mar 24, 2023
817b124
Remove unnecessary CSS class
sergiou87 Mar 24, 2023
6db32e3
State not updated when actions are updated
tidy-dev Mar 24, 2023
1f79189
Remove delay
tidy-dev Mar 23, 2023
3f874fb
Needs something new in the aria-live to ensure it is announced
tidy-dev Mar 24, 2023
7ed0504
Update to use resizeActiveResizable
tidy-dev Mar 24, 2023
f8d963c
Add resizable event listeners to resizable component
tidy-dev Mar 24, 2023
dd81309
Remove unused methods from last approach
tidy-dev Mar 24, 2023
c7dfd45
Need to be () =>
tidy-dev Mar 24, 2023
2e1a611
Typo
tidy-dev Mar 24, 2023
cc7c9ac
5px better than one
tidy-dev Mar 24, 2023
44572aa
More concise words?
tidy-dev Mar 24, 2023
9827eb6
Correct word with action
tidy-dev Mar 24, 2023
4de1dc8
Update menu state when resizable focus changes
tidy-dev Mar 24, 2023
fa80e3a
Add broken logic to enable/disable menu increase when not applicable
tidy-dev Mar 24, 2023
bb05e01
Removed unused method
tidy-dev Mar 24, 2023
8c267c5
More removal
tidy-dev Mar 24, 2023
c9b8655
Merge pull request #16366 from dereklowlind/development
sergiou87 Mar 27, 2023
3c3f113
Fix CSS of PR preview dialog
sergiou87 Mar 27, 2023
d4fee9e
Merge pull request #16395 from desktop/preview-pr-header-css
sergiou87 Mar 27, 2023
9120bdf
Merge pull request #16371 from desktop/Remove-unnecesssary-delay
tidy-dev Mar 27, 2023
a4ee318
Configure added co-authors as a listbox
sergiou87 Mar 27, 2023
34c708d
Add those Ids - different accelerator to not mingle with zoom functio…
tidy-dev Mar 27, 2023
86e79e8
Add support private repo images
sergiou87 Mar 28, 2023
8ebd9c6
Add "Co-authors" label to input and list of coauthors
sergiou87 Mar 28, 2023
f47da3d
Use tracking of a focused elements because windows menus are elements
tidy-dev Mar 27, 2023
842af74
Merge branch 'development' into resize-pane-with-keyboard-shorcut
tidy-dev Mar 28, 2023
a6f5740
Merge pull request #16286 from desktop/stream-available-repos
niik Mar 28, 2023
44fb504
Move misattributed popover into view when screen is small and zoomed
tidy-dev Mar 28, 2023
bc5a1d5
Use button not anchor for banner close button
tidy-dev Mar 28, 2023
51aa882
Remove other linters
tidy-dev Mar 28, 2023
74adc6e
make some div css apply to button
tidy-dev Mar 28, 2023
5252ec2
Make expander a button
tidy-dev Mar 28, 2023
805f675
Override user agent button styles
tidy-dev Mar 28, 2023
f697616
Remove aria-selected attribute and linter
tidy-dev Mar 28, 2023
7b3ce09
Use aria-labelledby for co-authors label references
sergiou87 Mar 29, 2023
57358e1
Add auth token for github.com private asset requests
sergiou87 Mar 29, 2023
4e549f6
Rename filter to reflect its new behavior
sergiou87 Mar 29, 2023
5b8dd9e
Use nbsp to force screen readers to read number of suggestions when n…
sergiou87 Mar 29, 2023
03c1add
Merge pull request #16408 from desktop/some-linters
tidy-dev Mar 29, 2023
4f26e19
Merge pull request #16409 from desktop/expander-button-linters
tidy-dev Mar 29, 2023
6a0a238
Merge pull request #16410 from desktop/stashed-changes-remove-aria-se…
tidy-dev Mar 29, 2023
56ae463
Merge pull request #16335 from desktop/co-author-accessibility-fixes
sergiou87 Mar 29, 2023
38a2f1a
Avoid retaining DOM elements
niik Mar 30, 2023
eeb71b9
Set aria-multiselectable when more than one item is selectable
niik Feb 15, 2023
3dd5641
Only set aria-selected for selectable items
niik Feb 15, 2023
6a503c6
Get rid of broken mouse over event in lists
niik Mar 16, 2023
d8d2713
Allow passing arbitrary a11y props to list rows
niik Mar 16, 2023
1fd8b21
Announce the included state of changed file
niik Mar 30, 2023
ccfb73b
Remove log
tidy-dev Mar 30, 2023
667703a
Use 8 and 9 as keyboard shortcut
tidy-dev Mar 30, 2023
0fd4549
Allow tabbing to empty lists
niik Mar 30, 2023
dd9f04e
Announce empty lists
niik Mar 30, 2023
afe3359
Merge pull request #16407 from desktop/misattribued-commit-popover-zo…
tidy-dev Mar 30, 2023
809e2d3
Merge pull request #16332 from desktop/resize-pane-with-keyboard-shorcut
tidy-dev Mar 30, 2023
e14401b
Condense commit description textarea when zoomed
tidy-dev Mar 30, 2023
56b5fd2
Make changes list scroll when zoomed
tidy-dev Mar 30, 2023
c832025
group non-list divs
tidy-dev Mar 31, 2023
5b8359e
Use value not clamp
tidy-dev Mar 31, 2023
b4f8a1a
Merge pull request #16412 from desktop/private-repo-assets
niik Apr 3, 2023
4437370
Merge branch 'desktop:development' into patch-2
KendallDoesCoding Apr 3, 2023
23cb6d0
Changelog and version bump
niik Apr 3, 2023
ec1544d
Merge pull request #16293 from KendallDoesCoding/patch-2
tidy-dev Apr 3, 2023
8b289cb
Use toggle tip component based on tooltip
tidy-dev Apr 3, 2023
f79b60c
Merge pull request #16445 from desktop/releases/3.2.1-beta3
niik Apr 3, 2023
d0f5b89
Don't introduce a11y props abstraction at this time
niik Apr 4, 2023
9929995
Camel case aria label prop
niik Apr 4, 2023
be5a31f
Changelog and version bump
niik Apr 4, 2023
f3241b2
Remove pr comments release notes
tidy-dev Apr 4, 2023
1d4b16d
Remove non applicable release note
tidy-dev Apr 5, 2023
12e5443
Remove duplicate release note
tidy-dev Apr 5, 2023
6e2eac3
Merge pull request #16452 from desktop/releases/3.2.1
tidy-dev Apr 5, 2023
7a3aac1
Add aria described by to changed files checkbox
tidy-dev Apr 5, 2023
25a8c7f
words
tidy-dev Apr 5, 2023
79b8816
Update app/src/ui/lib/checkbox.tsx
tidy-dev Apr 5, 2023
884a0e8
Update app/src/ui/lib/checkbox.tsx
tidy-dev Apr 5, 2023
cff01b8
Merge pull request #16420 from desktop/listitem-aria-select
niik Apr 5, 2023
00a1cac
Contrain value respects min for max.
tidy-dev Apr 5, 2023
4ca1523
Use clamp again for sidebar
tidy-dev Apr 5, 2023
6838ce3
Other ariaDescribedBy spot
tidy-dev Apr 5, 2023
f807171
Merge branch 'development' into change-list-scrollable-zoomed
tidy-dev Apr 5, 2023
9d78482
toolTipVisible should be state, subscribe to button ref in constructor
tidy-dev Apr 5, 2023
993f1d0
Add/remove tooltip visibility listeners
tidy-dev Apr 5, 2023
1733581
Merge branch 'development' into character-length-warning-keyboard-acc…
tidy-dev Apr 5, 2023
77ba189
Merge pull request #16370 from desktop/fix-pr-preview--sometimes-erro…
tidy-dev Apr 5, 2023
84177dd
Merge pull request #16457 from desktop/add-description-for-changes-li…
tidy-dev Apr 5, 2023
283dbee
Make changes list panel and history log list be the tab associated pa…
tidy-dev Apr 5, 2023
70de07e
Focus first focusable element of changes panel
tidy-dev Apr 5, 2023
8cb15f1
Merge branch 'development' into change-list-scrollable-zoomed
tidy-dev Apr 6, 2023
249fc2c
Add icons for tabs in Repository settings dialog
sweezyio Apr 6, 2023
6705f5b
Merge pull request #16425 from desktop/change-list-scrollable-zoomed
tidy-dev Apr 6, 2023
c24bf64
Keep a button ref instance to remove listeners
tidy-dev Apr 6, 2023
65de4dd
Merge branch 'development' into character-length-warning-keyboard-acc…
tidy-dev Apr 6, 2023
a6b5f5a
Merge branch 'development' into remove-avatar-tooltip
tidy-dev Apr 6, 2023
07193af
Merge branch 'character-length-warning-keyboard-accessible' into remo…
tidy-dev Apr 6, 2023
52b94a0
Revert title removal stuff
tidy-dev Apr 6, 2023
e204fc6
Use toggle tip for commit message avatar
tidy-dev Apr 6, 2023
04d9e5f
No tooltip when misattributed warning
tidy-dev Apr 6, 2023
35f659e
Put username in warning
tidy-dev Apr 6, 2023
113f033
Add role of `alertdialog` implementation
tidy-dev Apr 6, 2023
fdc7bf7
Type to require ariaDescribedBy for alertdialog roles
tidy-dev Apr 6, 2023
927bed2
enable auto-updating of theme and following system theme on Linux
shiftkey Apr 7, 2023
da438ba
pull in additional stylings to allow scrollbar styling on Linux to ma…
shiftkey Apr 7, 2023
611fa16
opt-out of rendering HTML menu on Linux
shiftkey Apr 7, 2023
ab8b209
Open the changed file header tool tip on checkbox focus
tidy-dev Apr 8, 2023
e047904
Add errors when too many popups
tidy-dev Apr 10, 2023
806daef
Update popup-manager.ts
tidy-dev Apr 10, 2023
dbf1e30
Bump xml2js from 0.4.19 to 0.5.0
dependabot[bot] Apr 10, 2023
971ef11
fix VSCodium name
GitMensch Apr 11, 2023
a0a194e
Merge pull request #16511 from GitMensch/patch-2
niik Apr 11, 2023
4e95b19
Add VimR to editors/darwin.ts
Apr 11, 2023
5d96f90
Add VimR to editor-integration.md MacOS list
Apr 11, 2023
b482085
Merge pull request #16465 from sweezyio/development
niik Apr 12, 2023
16a3de4
Merge pull request #16503 from desktop/dependabot/npm_and_yarn/xml2js…
niik Apr 12, 2023
e974cee
Update app/styles/themes/_dark.scss
shiftkey Apr 12, 2023
b214dca
Merge pull request #16515 from Elmar-Wiese/development
niik Apr 12, 2023
d83ca1b
Merge pull request #16487 from desktop/open-changed-list-heading-tool…
tidy-dev Apr 12, 2023
3862811
Merge pull request #16499 from desktop/too-many-popups
tidy-dev Apr 12, 2023
121beb7
Merge branch 'development' into undo-confirmation-alert-dialog
tidy-dev Apr 12, 2023
c11ea57
Cleaner interface union
tidy-dev Apr 12, 2023
a915933
Merge branch 'development' into character-length-warning-keyboard-acc…
tidy-dev Apr 12, 2023
5969613
Merge branch 'development' into changes-history-tabs
tidy-dev Apr 12, 2023
1317a7e
Merge pull request #16463 from desktop/changes-history-tabs
tidy-dev Apr 12, 2023
66d5cf4
Merge pull request #16449 from desktop/character-length-warning-keybo…
tidy-dev Apr 12, 2023
321b49c
Merge pull request #16272 from desktop/remove-avatar-tooltip
tidy-dev Apr 12, 2023
2146162
Merge pull request #16484 from shiftkey/allow-for-dark-styling
niik Apr 12, 2023
24e2722
Merge pull request #16472 from desktop/undo-confirmation-alert-dialog
tidy-dev Apr 12, 2023
3249868
Issue 15284 Toggle Diff Display Mode and Hide Whitespace Changes
angusdev Oct 14, 2022
187b2ed
Merge pull request #14176 from desktop/shared-formatter-caching
niik Apr 13, 2023
c7d4b33
Merge branch 'locale-aware-formatting' into region-aware-number-forma…
niik Apr 13, 2023
b7779cc
Merge branch 'development' into region-aware-number-formatting
niik Apr 13, 2023
935c44e
Merge fail
niik Apr 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/src/lib/format-commit-count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { formatCount } from './format-count'

/**
* Returns a string used for communicating a quantity of commits in a human-
* readable, pluralized format (i.e '1 commit', '2 commits')
*/
export const formatCommitCount = (numberOfCommits: number) =>
formatCount(numberOfCommits, 'commit')
15 changes: 15 additions & 0 deletions app/src/lib/format-count.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { formatNumber } from './format-number'

/**
* Returns a string used for communicating a count in a human-readable,
* pluralized format (i.e '1 commit', '2 commits')
*
* @param count The number 'units'
* @param unit A string written in such a way that without
* modification it can be paired with the digit 1 such as
* 'commit' and which, when a 's' is appended to it can
* be paired with a zero digit or a number greater than
* one.
*/
export const formatCount = (count: number, unit: string) =>
`${formatNumber(count)} ${unit}${count === 1 ? '' : 's'}`
37 changes: 37 additions & 0 deletions app/src/lib/format-number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import mem from 'mem'
import QuickLRU from 'quick-lru'
import { getFormattingLocales } from './formatting-locale'

// Initializing a number formatter is expensive but formatting is relatively
// cheap so we cache them based on the locale and their options. The maxSize of
// a 100 is only as an escape hatch, we don't expect to ever create more than a
// handful different formatters.
const getNumber = mem(
(locale: string | string[], options?: Intl.NumberFormatOptions) => {
try {
return new Intl.NumberFormat(locale, options)
} catch (e) {
log.error(`Error creating NumberFormat with locale '${locale}'`, e)
return new Intl.NumberFormat(undefined, options)
}
},
{
cache: new QuickLRU({ maxSize: 100 }),
cacheKey: (...args) => JSON.stringify(args),
}
)

/**
* Format a date in the user's formatting locale, customizable with
* Intl.NumberFormatOptions.
*
* See Intl.NumberFormat for more information
*/
export const formatNumber = (num: number, options?: Intl.NumberFormatOptions) =>
getNumber(getFormattingLocales(), options).format(num)

/** Shorthand for formatNumber(x, { style: 'percent' }) */
export const formatPercent = (
num: number,
options?: Omit<Intl.NumberFormatOptions, 'style'>
) => formatNumber(num, { ...options, style: 'percent' })
2 changes: 1 addition & 1 deletion app/src/lib/progress/lfs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getTempFilePath } from '../file-system'
import { IGitProgress, IGitProgressInfo, IGitOutput } from './git'
import { formatBytes } from '../../ui/lib/bytes'
import { formatBytes } from '../../ui/lib/format-bytes'
import { open } from 'fs/promises'

/** Create the Git LFS progress reporting file and return the path. */
Expand Down
8 changes: 4 additions & 4 deletions app/src/ui/banners/cherry-pick-undone.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react'
import { formatCount } from '../../lib/format-count'
import { SuccessBanner } from './success-banner'

interface ICherryPickUndoneBannerProps {
Expand All @@ -13,12 +14,11 @@ export class CherryPickUndone extends React.Component<
> {
public render() {
const { countCherryPicked, targetBranchName, onDismissed } = this.props
const pluralized = countCherryPicked === 1 ? 'commit' : 'commits'
return (
<SuccessBanner timeout={5000} onDismissed={onDismissed}>
Cherry-pick undone. Successfully removed the {countCherryPicked}
{' copied '}
{pluralized} from <strong>{targetBranchName}</strong>.
Cherry-pick undone. Successfully removed the{' '}
{formatCount(countCherryPicked, 'copied commit')}
from <strong>{targetBranchName}</strong>.
</SuccessBanner>
)
}
Expand Down
13 changes: 4 additions & 9 deletions app/src/ui/banners/render-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { OpenThankYouCard } from './open-thank-you-card'
import { SuccessfulSquash } from './successful-squash'
import { SuccessBanner } from './success-banner'
import { ConflictsFoundBanner } from './conflicts-found-banner'
import { formatCommitCount } from '../../lib/format-commit-count'

export function renderBanner(
banner: Banner,
Expand Down Expand Up @@ -120,33 +121,27 @@ export function renderBanner(
/>
)
case BannerType.SquashUndone: {
const pluralized = banner.commitsCount === 1 ? 'commit' : 'commits'
return (
<SuccessBanner timeout={5000} onDismissed={onDismissed}>
Squash of {banner.commitsCount} {pluralized} undone.
Squash of {formatCommitCount(banner.commitsCount)} undone.
</SuccessBanner>
)
}
case BannerType.SuccessfulReorder: {
const pluralized = banner.count === 1 ? 'commit' : 'commits'

return (
<SuccessBanner
timeout={15000}
onDismissed={onDismissed}
onUndo={banner.onUndo}
>
<span>
Successfully reordered {banner.count} {pluralized}.
</span>
<span>Successfully reordered {formatCommitCount(banner.count)}.</span>
</SuccessBanner>
)
}
case BannerType.ReorderUndone: {
const pluralized = banner.commitsCount === 1 ? 'commit' : 'commits'
return (
<SuccessBanner timeout={5000} onDismissed={onDismissed}>
Reorder of {banner.commitsCount} {pluralized} undone.
Reorder of {formatCommitCount(banner.commitsCount)} undone.
</SuccessBanner>
)
}
Expand Down
5 changes: 2 additions & 3 deletions app/src/ui/banners/successful-cherry-pick.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react'
import { formatCommitCount } from '../../lib/format-commit-count'
import { SuccessBanner } from './success-banner'

interface ISuccessfulCherryPickBannerProps {
Expand All @@ -20,12 +21,10 @@ export class SuccessfulCherryPick extends React.Component<
targetBranchName,
} = this.props

const pluralized = countCherryPicked === 1 ? 'commit' : 'commits'

return (
<SuccessBanner timeout={15000} onDismissed={onDismissed} onUndo={onUndo}>
<span>
Successfully copied {countCherryPicked} {pluralized} to{' '}
Successfully copied {formatCommitCount(countCherryPicked)} to{' '}
<strong>{targetBranchName}</strong>.
</span>
</SuccessBanner>
Expand Down
7 changes: 2 additions & 5 deletions app/src/ui/banners/successful-squash.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react'
import { formatCommitCount } from '../../lib/format-commit-count'
import { SuccessBanner } from './success-banner'

interface ISuccessfulSquashedBannerProps {
Expand All @@ -14,13 +15,9 @@ export class SuccessfulSquash extends React.Component<
public render() {
const { count, onDismissed, onUndo } = this.props

const pluralized = count === 1 ? 'commit' : 'commits'

return (
<SuccessBanner timeout={15000} onDismissed={onDismissed} onUndo={onUndo}>
<span>
Successfully squashed {count} {pluralized}.
</span>
<span>Successfully squashed {formatCommitCount(count)}.</span>
</SuccessBanner>
)
}
Expand Down
31 changes: 8 additions & 23 deletions app/src/ui/branches/push-branch-commits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Dialog, DialogContent, DialogFooter } from '../dialog'
import { Repository } from '../../models/repository'
import { Ref } from '../lib/ref'
import { OkCancelButtonGroup } from '../dialog/ok-cancel-button-group'
import { formatCount } from '../../lib/format-count'

interface IPushBranchCommitsProps {
readonly dispatcher: Dispatcher
Expand All @@ -30,23 +31,6 @@ interface IPushBranchCommitsState {
readonly isPushingOrPublishing: boolean
}

/**
* Returns a string used for communicating the number of commits
* that will be pushed to the user.
*
* @param numberOfCommits The number of commits that will be pushed
* @param unit A string written in such a way that without
* modification it can be paired with the digit 1
* such as 'commit' and which, when a 's' is appended
* to it can be paired with a zero digit or a number
* greater than one.
*/
function pluralize(numberOfCommits: number, unit: string) {
return numberOfCommits === 1
? `${numberOfCommits} ${unit}`
: `${numberOfCommits} ${unit}s`
}

/**
* Simple type guard which allows us to substitute the non-obvious
* this.props.unPushedCommits === undefined checks with
Expand Down Expand Up @@ -95,28 +79,29 @@ export class PushBranchCommits extends React.Component<
}

private renderDialogContent() {
if (renderPublishView(this.props.unPushedCommits)) {
const { unPushedCommits, branch } = this.props
if (renderPublishView(unPushedCommits)) {
return (
<DialogContent>
<p>Your branch must be published before opening a pull request.</p>
<p>
Would you like to publish <Ref>{this.props.branch.name}</Ref> now
and open a pull request?
Would you like to publish <Ref>{branch.name}</Ref> now and open a
pull request?
</p>
</DialogContent>
)
}

const localCommits = pluralize(this.props.unPushedCommits, 'local commit')
const localCommits = formatCount(unPushedCommits, 'local commit')

return (
<DialogContent>
<p>
You have {localCommits} that haven't been pushed to the remote yet.
</p>
<p>
Would you like to push your changes to{' '}
<Ref>{this.props.branch.name}</Ref> before creating your pull request?
Would you like to push your changes to <Ref>{branch.name}</Ref> before
creating your pull request?
</p>
</DialogContent>
)
Expand Down
10 changes: 6 additions & 4 deletions app/src/ui/changes/changes-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import { hasConflictedFiles } from '../../lib/status'
import { createObservableRef } from '../lib/observable-ref'
import { Tooltip, TooltipDirection } from '../lib/tooltip'
import { Popup } from '../../models/popup'
import { formatCount } from '../../lib/format-count'
import { formatNumber } from '../../lib/format-number'

const RowHeight = 29
const StashIcon: OcticonSymbol.OcticonSymbolType = {
Expand Down Expand Up @@ -817,14 +819,14 @@ export class ChangesList extends React.Component<
const { workingDirectory, rebaseConflictState, isCommitting } = this.props
const { files } = workingDirectory

const filesPlural = files.length === 1 ? 'file' : 'files'
const filesDescription = `${files.length} changed ${filesPlural}`
const filesDescription = formatCount(files.length, 'changed file')

const selectedChangeCount = files.filter(
file => file.selection.getSelectionType() !== DiffSelectionType.None
).length
const totalFilesPlural = files.length === 1 ? 'file' : 'files'
const selectedChangesDescription = `${selectedChangeCount}/${files.length} changed ${totalFilesPlural} selected`
const selectedChangesDescription = `${formatNumber(
selectedChangeCount
)}/${formatCount(files.length, 'changed file')} selected`

const includeAllValue = getIncludeAllValue(
workingDirectory,
Expand Down
20 changes: 9 additions & 11 deletions app/src/ui/changes/no-changes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { Dispatcher } from '../dispatcher'
import { SuggestedActionGroup } from '../suggested-actions'
import { PreferencesTab } from '../../models/preferences'
import { PopupType } from '../../models/popup'
import { formatCommitCount } from '../../lib/format-commit-count'
import { formatCount } from '../../lib/format-count'

function formatMenuItemLabel(text: string) {
if (__WIN32__ || __LINUX__) {
Expand Down Expand Up @@ -396,8 +398,8 @@ export class NoChanges extends React.Component<
const numChanges = stashEntry.files.files.length
const description = (
<>
You have {numChanges} {numChanges === 1 ? 'change' : 'changes'} in
progress that you have not yet committed.
You have {formatCount(numChanges, 'change')} in progress that you have
not yet committed.
</>
)
const discoverabilityContent = (
Expand Down Expand Up @@ -550,9 +552,9 @@ export class NoChanges extends React.Component<
</>
)

const title = `Pull ${aheadBehind.behind} ${
aheadBehind.behind === 1 ? 'commit' : 'commits'
} from the ${remote.name} remote`
const title = `Pull ${formatCommitCount(aheadBehind.behind)} from the ${
remote.name
} remote`

const buttonText = `Pull ${remote.name}`

Expand Down Expand Up @@ -592,17 +594,13 @@ export class NoChanges extends React.Component<
if (aheadBehind.ahead > 0) {
itemsToPushTypes.push('commits')
itemsToPushDescriptions.push(
aheadBehind.ahead === 1
? '1 local commit'
: `${aheadBehind.ahead} local commits`
formatCount(aheadBehind.ahead, 'local commit')
)
}

if (tagsToPush !== null && tagsToPush.length > 0) {
itemsToPushTypes.push('tags')
itemsToPushDescriptions.push(
tagsToPush.length === 1 ? '1 tag' : `${tagsToPush.length} tags`
)
itemsToPushDescriptions.push(formatCount(tagsToPush.length, 'tag'))
}

const description = `You have ${itemsToPushDescriptions.join(
Expand Down
5 changes: 3 additions & 2 deletions app/src/ui/check-runs/ci-check-run-popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import * as OcticonSymbol from '../octicons/octicons.generated'
import { Donut } from '../donut'
import { supportsRerunningChecks } from '../../lib/endpoint-capabilities'
import { getPullRequestCommitRef } from '../../models/pull-request'
import { formatCount } from '../../lib/format-count'

const BlankSlateImage = encodePathAsUrl(
__dirname,
Expand Down Expand Up @@ -187,8 +188,8 @@ export class CICheckRunPopover extends React.PureComponent<
return `${output.slice(0, -1).join(', ')}, and ${output.slice(-1)} checks`
}

const pluralize = summaryArray[0].count > 1 ? 'checks' : 'check'
return `${summaryArray[0].count} ${summaryArray[0].conclusion} ${pluralize}`
const { count, conclusion } = summaryArray[0]
return formatCount(count, `${conclusion} check`)
}

private rerunChecks = () => {
Expand Down
12 changes: 8 additions & 4 deletions app/src/ui/check-runs/ci-check-run-rerun-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as OcticonSymbol from './../octicons/octicons.generated'
import { Row } from '../lib/row'
import { encodePathAsUrl } from '../../lib/path'
import { offsetFromNow } from '../../lib/offset-from'
import { formatCount } from '../../lib/format-count'

const BlankSlateImage = encodePathAsUrl(
__dirname,
Expand Down Expand Up @@ -147,17 +148,20 @@ export class CICheckRunRerunDialog extends React.Component<
return null
}

const pluralize = `check${this.state.nonRerunnable.length !== 1 ? 's' : ''}`
const verb = this.state.nonRerunnable.length !== 1 ? 'are' : 'is'
const notRerunnable = this.state.nonRerunnable.length
const verb = notRerunnable !== 1 ? 'are' : 'is'
return (
<Row className="non-re-run-info warning-helper-text">
<Octicon symbol={OcticonSymbol.alert} />

{this.state.rerunnable.length === 0
? `There are no checks that can be re-run. `
: `There ${verb} ${this.state.nonRerunnable.length} ${pluralize} that cannot be re-run. `}
: `There ${verb} ${formatCount(
notRerunnable,
'check'
)} that cannot be re-run. `}

{this.state.nonRerunnable.length > 0
{notRerunnable > 0
? `A check run cannot be re-run if the check is more than one month old,
the check has not completed, or the check is not configured to be
re-run.`
Expand Down