fix: don't rely on colour for boost/favourite state (#2234)
By changing the shape it means no matter what the colour difference between pressed and non-pressed it'll be possible to know the state. Co-authored-by: Nolan Lawson <nolan@nolanlawson.com>
This commit is contained in:
parent
fa41fe7649
commit
bc664e5ca1
|
@ -12,9 +12,13 @@
|
||||||
ref:node
|
ref:node
|
||||||
>
|
>
|
||||||
<SvgIcon className="icon-button-svg {svgClassName || ''}" ref:svg {href} />
|
<SvgIcon className="icon-button-svg {svgClassName || ''}" ref:svg {href} />
|
||||||
|
{#if checked}
|
||||||
|
<SvgIcon className="icon-button-svg icon-button-check" ref:check href="#fa-check" />
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
<style>
|
<style>
|
||||||
.icon-button {
|
.icon-button {
|
||||||
|
position: relative;
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -31,6 +35,14 @@
|
||||||
pointer-events: none; /* hack for Edge */
|
pointer-events: none; /* hack for Edge */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.icon-button-check) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 1px;
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
:global(.icon-button.big-icon .icon-button-svg) {
|
:global(.icon-button.big-icon .icon-button-svg) {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -128,7 +140,8 @@
|
||||||
className: undefined,
|
className: undefined,
|
||||||
sameColorWhenPressed: false,
|
sameColorWhenPressed: false,
|
||||||
ariaHidden: false,
|
ariaHidden: false,
|
||||||
clickListener: true
|
clickListener: true,
|
||||||
|
checked: false
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -144,8 +157,11 @@
|
||||||
ariaLabel: ({ pressable, pressed, label, pressedLabel }) => ((pressable && pressed) ? pressedLabel : label)
|
ariaLabel: ({ pressable, pressed, label, pressedLabel }) => ((pressable && pressed) ? pressedLabel : label)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
animate (animation) {
|
animate (animation, checkmarkAnimation) {
|
||||||
this.refs.svg.animate(animation)
|
this.refs.svg.animate(animation)
|
||||||
|
if (checkmarkAnimation && this.get().checked) {
|
||||||
|
this.refs.check.animate(checkmarkAnimation)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onClick (e) {
|
onClick (e) {
|
||||||
this.fire('click', e)
|
this.fire('click', e)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
pressedLabel="Unboost"
|
pressedLabel="Unboost"
|
||||||
pressable={!reblogDisabled}
|
pressable={!reblogDisabled}
|
||||||
pressed={reblogged}
|
pressed={reblogged}
|
||||||
|
checked={reblogged}
|
||||||
disabled={reblogDisabled}
|
disabled={reblogDisabled}
|
||||||
href={reblogIcon}
|
href={reblogIcon}
|
||||||
clickListener={false}
|
clickListener={false}
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
pressedLabel="{intl.unfavorite}"
|
pressedLabel="{intl.unfavorite}"
|
||||||
pressable={true}
|
pressable={true}
|
||||||
pressed={favorited}
|
pressed={favorited}
|
||||||
|
checked={favorited}
|
||||||
href="#fa-star"
|
href="#fa-star"
|
||||||
clickListener={false}
|
clickListener={false}
|
||||||
elementId={favoriteKey}
|
elementId={favoriteKey}
|
||||||
|
@ -75,7 +77,7 @@
|
||||||
import { setReblogged } from '../../_actions/reblog.js'
|
import { setReblogged } from '../../_actions/reblog.js'
|
||||||
import { importShowStatusOptionsDialog } from '../dialog/asyncDialogs/importShowStatusOptionsDialog.js'
|
import { importShowStatusOptionsDialog } from '../dialog/asyncDialogs/importShowStatusOptionsDialog.js'
|
||||||
import { updateProfileAndRelationship } from '../../_actions/accounts.js'
|
import { updateProfileAndRelationship } from '../../_actions/accounts.js'
|
||||||
import { FAVORITE_ANIMATION, REBLOG_ANIMATION } from '../../_static/animations.js'
|
import { CHECKMARK_ANIMATION, FAVORITE_ANIMATION, REBLOG_ANIMATION } from '../../_static/animations.js'
|
||||||
import { on } from '../../_utils/eventBus.js'
|
import { on } from '../../_utils/eventBus.js'
|
||||||
import { announceAriaLivePolite } from '../../_utils/announceAriaLivePolite.js'
|
import { announceAriaLivePolite } from '../../_utils/announceAriaLivePolite.js'
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@
|
||||||
const newFavoritedValue = !favorited
|
const newFavoritedValue = !favorited
|
||||||
/* no await */ setFavorited(originalStatusId, newFavoritedValue)
|
/* no await */ setFavorited(originalStatusId, newFavoritedValue)
|
||||||
if (newFavoritedValue) {
|
if (newFavoritedValue) {
|
||||||
this.refs.favoriteIcon.animate(FAVORITE_ANIMATION)
|
this.refs.favoriteIcon.animate(FAVORITE_ANIMATION, CHECKMARK_ANIMATION)
|
||||||
}
|
}
|
||||||
if (announce) {
|
if (announce) {
|
||||||
announceAriaLivePolite(newFavoritedValue ? 'intl.favorited' : 'intl.unfavorited')
|
announceAriaLivePolite(newFavoritedValue ? 'intl.favorited' : 'intl.unfavorited')
|
||||||
|
@ -129,7 +131,7 @@
|
||||||
const newRebloggedValue = !reblogged
|
const newRebloggedValue = !reblogged
|
||||||
/* no await */ setReblogged(originalStatusId, newRebloggedValue)
|
/* no await */ setReblogged(originalStatusId, newRebloggedValue)
|
||||||
if (newRebloggedValue) {
|
if (newRebloggedValue) {
|
||||||
this.refs.reblogIcon.animate(REBLOG_ANIMATION)
|
this.refs.reblogIcon.animate(REBLOG_ANIMATION, CHECKMARK_ANIMATION)
|
||||||
}
|
}
|
||||||
if (announce) {
|
if (announce) {
|
||||||
announceAriaLivePolite(newRebloggedValue ? 'intl.reblogged' : 'intl.unreblogged')
|
announceAriaLivePolite(newRebloggedValue ? 'intl.reblogged' : 'intl.unreblogged')
|
||||||
|
|
|
@ -1,39 +1,37 @@
|
||||||
export const FAVORITE_ANIMATION = [
|
const growBigThenSmall = {
|
||||||
{
|
properties: [
|
||||||
properties: [
|
{ transform: 'scale(1)' },
|
||||||
{ transform: 'scale(1)' },
|
{ transform: 'scale(2)' },
|
||||||
{ transform: 'scale(2)' },
|
{ transform: 'scale(1)' }
|
||||||
{ transform: 'scale(1)' }
|
],
|
||||||
],
|
options: {
|
||||||
options: {
|
duration: 333,
|
||||||
duration: 333,
|
easing: 'ease-in-out'
|
||||||
easing: 'ease-in-out'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
properties: [
|
|
||||||
{ fill: 'var(--action-button-fill-color)' },
|
|
||||||
{ fill: 'var(--action-button-fill-color-pressed)' }
|
|
||||||
],
|
|
||||||
options: {
|
|
||||||
duration: 333,
|
|
||||||
easing: 'linear'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fadeColorToPressedState = {
|
||||||
|
properties: [
|
||||||
|
{ fill: 'var(--action-button-fill-color)' },
|
||||||
|
{ fill: 'var(--action-button-fill-color-pressed)' }
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
duration: 333,
|
||||||
|
easing: 'linear'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FAVORITE_ANIMATION = [
|
||||||
|
growBigThenSmall,
|
||||||
|
fadeColorToPressedState
|
||||||
]
|
]
|
||||||
|
|
||||||
export const REBLOG_ANIMATION = FAVORITE_ANIMATION
|
export const REBLOG_ANIMATION = FAVORITE_ANIMATION
|
||||||
|
|
||||||
export const FOLLOW_BUTTON_ANIMATION = [
|
export const FOLLOW_BUTTON_ANIMATION = [
|
||||||
{
|
growBigThenSmall
|
||||||
properties: [
|
]
|
||||||
{ transform: 'scale(1)' },
|
|
||||||
{ transform: 'scale(2)' },
|
export const CHECKMARK_ANIMATION = [
|
||||||
{ transform: 'scale(1)' }
|
fadeColorToPressedState
|
||||||
],
|
|
||||||
options: {
|
|
||||||
duration: 333,
|
|
||||||
easing: 'ease-in-out'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -41,8 +41,8 @@ test('shows account profile 3', async t => {
|
||||||
.expect(accountProfileName.innerText).contains('foobar')
|
.expect(accountProfileName.innerText).contains('foobar')
|
||||||
.expect(accountProfileUsername.innerText).contains('@foobar')
|
.expect(accountProfileUsername.innerText).contains('@foobar')
|
||||||
// can't follow or be followed by your own account
|
// can't follow or be followed by your own account
|
||||||
.expect(accountProfileFollowedBy.innerText).eql('')
|
.expect(accountProfileFollowedBy.innerText).match(/\s*/)
|
||||||
.expect($('.account-profile .account-profile-follow').innerText).eql('')
|
.expect($('.account-profile .account-profile-follow').innerText).match(/\s*/)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('shows account profile statuses', async t => {
|
test('shows account profile statuses', async t => {
|
||||||
|
|
Loading…
Reference in a new issue