Stage 17 (contour round 4a): quick fixes
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 12s
CI / ui (pull_request) Successful in 27s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 12s
CI / ui (pull_request) Successful in 27s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
- #4 bag label: '{n} in the bag' / 'Bag is empty' (was 'Bag {n}') - #6 allow a single trailing dot in display names (backend + UI regex + tests) - #1 double-tap zooms toward the tapped cell, not the top-left - #8 shuffle fires a short multi-pulse haptic - #11 highlighted/flashing tiles darken their bottom edge too (shadow joins the flash) - #13 toast slides up from the bottom and fades out - #7 hide the logout button (kept wired behind `hidden`) - #16 admin game seats: left-align numeric columns, clarify the 'Hints used' header
This commit is contained in:
@@ -28,9 +28,10 @@ const maxAwayWindow = 12 * time.Hour
|
||||
|
||||
// displayNameRe enforces the editable display-name format (Stage 8): Unicode letters
|
||||
// joined by single space / "." / "_" separators, where a "." or "_" may be followed
|
||||
// by a single space. No leading or trailing separator and no two adjacent separators,
|
||||
// except "<dot|underscore> <space>". So "Name_P. Last" is valid, "Name P._Last" is not.
|
||||
var displayNameRe = regexp.MustCompile(`^\p{L}+(?:(?:[._] ?| )\p{L}+)*$`)
|
||||
// by a single space. No leading separator and no two adjacent separators (except
|
||||
// "<dot|underscore> <space>"); a single trailing "." is allowed (Stage 17), so
|
||||
// "Name_P. Last" and "Anna B." are valid, "Name P._Last" is not.
|
||||
var displayNameRe = regexp.MustCompile(`^\p{L}+(?:(?:[._] ?| )\p{L}+)*\.?$`)
|
||||
|
||||
// ErrInvalidProfile is returned when a profile update carries an unacceptable
|
||||
// field (an unknown language, an invalid timezone, or an over-long display name).
|
||||
|
||||
@@ -12,19 +12,21 @@ func TestValidateDisplayName(t *testing.T) {
|
||||
want string
|
||||
ok bool
|
||||
}{
|
||||
"plain": {"Kaya", "Kaya", true},
|
||||
"cyrillic": {"Кая", "Кая", true},
|
||||
"dot underscore mix": {"Name_P. Last", "Name_P. Last", true},
|
||||
"single dot": {"Mr.Smith", "Mr.Smith", true},
|
||||
"dot then space": {"Mr. Smith", "Mr. Smith", true},
|
||||
"trim surrounding": {" Kaya ", "Kaya", true},
|
||||
"adjacent specials": {"Name P._Last", "", false},
|
||||
"two spaces": {"Name Last", "", false},
|
||||
"leading special": {"_Name", "", false},
|
||||
"trailing special": {"Name.", "", false},
|
||||
"digit rejected": {"Name2", "", false},
|
||||
"blank": {" ", "", false},
|
||||
"too long": {strings.Repeat("a", 33), "", false},
|
||||
"plain": {"Kaya", "Kaya", true},
|
||||
"cyrillic": {"Кая", "Кая", true},
|
||||
"dot underscore mix": {"Name_P. Last", "Name_P. Last", true},
|
||||
"single dot": {"Mr.Smith", "Mr.Smith", true},
|
||||
"dot then space": {"Mr. Smith", "Mr. Smith", true},
|
||||
"trim surrounding": {" Kaya ", "Kaya", true},
|
||||
"adjacent specials": {"Name P._Last", "", false},
|
||||
"two spaces": {"Name Last", "", false},
|
||||
"leading special": {"_Name", "", false},
|
||||
"trailing underscore": {"Name_", "", false},
|
||||
"trailing dot ok": {"Anna B.", "Anna B.", true},
|
||||
"double trailing dot": {"Name..", "", false},
|
||||
"digit rejected": {"Name2", "", false},
|
||||
"blank": {" ", "", false},
|
||||
"too long": {strings.Repeat("a", 33), "", false},
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
</section>
|
||||
<section class="panel"><h2>Seats</h2>
|
||||
<table class="list">
|
||||
<thead><tr><th class="num">Seat</th><th>Player</th><th class="num">Score</th><th class="num">Hints</th><th>Winner</th></tr></thead>
|
||||
<thead><tr><th>Seat</th><th>Player</th><th>Score</th><th>Hints used</th><th>Winner</th></tr></thead>
|
||||
<tbody>
|
||||
{{range .Seats}}
|
||||
<tr><td class="num">{{.Seat}}</td><td><a href="/_gm/users/{{.AccountID}}">{{.DisplayName}}</a></td><td class="num">{{.Score}}</td><td class="num">{{.HintsUsed}}</td><td>{{if .Winner}}<span class="ok">winner</span>{{end}}</td></tr>
|
||||
<tr><td>{{.Seat}}</td><td><a href="/_gm/users/{{.AccountID}}">{{.DisplayName}}</a></td><td>{{.Score}}</td><td>{{.HintsUsed}}</td><td>{{if .Winner}}<span class="ok">winner</span>{{end}}</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user