Skip to content

Commit

Permalink
Make the image captcha not look terrible (#1287)
Browse files Browse the repository at this point in the history
* Make the image captcha target text not look terrible

* Capitalize target only

* Fix cypress tests

* Reduce padding

* Add spacing to theme

* Try to fix cypress tests

* remove trailing comma
  • Loading branch information
forgetso authored Jun 20, 2024
1 parent 3ecb8e9 commit 2b8f371
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 52 deletions.
27 changes: 13 additions & 14 deletions demos/cypress-shared/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,19 @@ function clickIAmHuman(): Cypress.Chainable<Captcha[]> {
}

function captchaImages(): Cypress.Chainable<JQuery<HTMLElement>> {
return (
cy
.xpath("//p[contains(text(),'images containing')]", { timeout: 4000 })
.should('be.visible')
.parent()
.parent()
.children()
.next()
//.next()
.children()
.first()
.children()
.as('captchaImages')
)
return cy
.xpath("//p[contains(text(),'all containing')]", { timeout: 4000 })
.should('be.visible')
.parent()
.parent()
.parent()
.parent()
.children()
.next()
.children()
.first()
.children()
.as('captchaImages')
}

function getSelectors(captcha: Captcha) {
Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"NO_POLKADOT_EXTENSION": "Polkadot extension not found"
},
"WIDGET": {
"SELECT_ALL": "Select all images containing a",
"SELECT_ALL": "Select all containing the following",
"IF_NONE_CLICK_NEXT": "If there are none, click Next",
"NEXT": "Next",
"SUBMIT": "Submit",
"CANCEL": "Cancel",
Expand Down
63 changes: 42 additions & 21 deletions packages/procaptcha-react/src/components/CaptchaComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ const CaptchaComponent = ({
maxHeight: '100%',
display: 'flex',
flexDirection: 'column',
border: '1px solid #dddddd',
boxShadow: 'rgba(255, 255, 255, 0.2) 0px 0px 4px',
borderRadius: '4px',
padding: `${theme.spacing.unit}px`,
backgroundColor: theme.palette.background.default,
}}
>
<div
Expand All @@ -73,30 +78,46 @@ const CaptchaComponent = ({
display: 'flex',
alignItems: 'center',
width: '100%',
backgroundColor: theme.palette.primary.main,
padding: '24px 16px',
}}
>
<p
<div
style={{
color: '#ffffff',
fontWeight: 700,
lineHeight: 1.5,
backgroundColor: theme.palette.primary.main,
width: '100%',
}}
>
{t('WIDGET.SELECT_ALL')}
{': '}
</p>
<p
style={{
color: '#ffffff',
fontWeight: 700,
textTransform: 'capitalize',
lineHeight: 1.5,
}}
>
{`${at(challenge.captchas, index).captcha.target}`}
</p>
<div
style={{
paddingLeft: `${theme.spacing.half}px`,
paddingRight: `${theme.spacing.half}px`,
}}
>
<p
style={{
color: '#ffffff',
fontWeight: 700,
lineHeight: 1.5,
}}
>
{t('WIDGET.SELECT_ALL')}
{':'}
&nbsp;
<span style={{ textTransform: 'capitalize' }}>
{`${at(challenge.captchas, index).captcha.target}`}
</span>
</p>
<p
style={{
color: '#ffffff',
fontWeight: 500,
lineHeight: 0.8,
fontSize: '0.8rem',
}}
>
{t('WIDGET.IF_NONE_CLICK_NEXT')}
</p>
</div>
</div>
</div>
<div {...addDataAttr({ dev: { cy: 'captcha-' + index } })}>
{captcha && (
Expand All @@ -119,14 +140,14 @@ const CaptchaComponent = ({
/>
<div
style={{
padding: '8px 16px',
padding: `0 ${theme.spacing}px`,
display: 'flex',
width: '100%',
}}
></div>
<div
style={{
padding: '0 16px 16px',
padding: `0 ${theme.spacing}px`,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
Expand Down
51 changes: 36 additions & 15 deletions packages/procaptcha-react/src/components/CaptchaWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { CaptchaWithProof } from '@prosopo/types'
import { Properties } from 'csstype'
import { ProsopoDatasetError } from '@prosopo/common'
import { darkTheme, lightTheme } from '@prosopo/web-components'
import { useMemo } from 'react'
Expand All @@ -36,6 +37,20 @@ export const CaptchaWidget = ({ challenge, solution, onClick, themeColor }: Capt

const isTouchDevice = 'ontouchstart' in window

// Assumes a 3x3 grid, could be made more generic
const fullSpacing = `${theme.spacing.unit}px`
const halfSpacing = `${theme.spacing.half}px`
const paddingForImageColumns: { [key: number]: any } = {
0: { paddingLeft: 0, paddingRight: halfSpacing, paddingTop: halfSpacing, paddingBottom: halfSpacing },
1: { paddingLeft: halfSpacing, paddingRight: halfSpacing, paddingTop: halfSpacing, paddingBottom: halfSpacing },
2: { paddingLeft: halfSpacing, paddingRight: 0, paddingTop: halfSpacing, paddingBottom: halfSpacing },
}

const paddingForImageRows: { [key: number]: any } = {
0: { paddingTop: fullSpacing },
2: { paddingBottom: fullSpacing },
}

return (
<div
style={{
Expand All @@ -52,26 +67,32 @@ export const CaptchaWidget = ({ challenge, solution, onClick, themeColor }: Capt
>
{items.map((item, index) => {
const hash = getHash(item)
const imageStyle: Properties<string | number, string> = {
...paddingForImageColumns[index % 3],
...paddingForImageRows[Math.floor(index / 3)],
// enable the items in the grid to grow in width to use up excess space
flexGrow: 1,
// make the width of each item 1/3rd of the width overall, i.e. 3 columns
flexBasis: '33.3333%',
// include the padding / margin / border in the width
boxSizing: 'border-box',
}
console.log('imageStyle index ', index, imageStyle)
return (
<div
style={{
paddingTop: '4px',
paddingLeft: '4px',
// enable the items in the grid to grow in width to use up excess space
flexGrow: 1,
// make the width of each item 1/3rd of the width overall, i.e. 3 columns
flexBasis: '33.3333%',
// include the padding / margin / border in the width
boxSizing: 'border-box',
}}
key={index}
>
<div style={imageStyle} key={index}>
<div
style={{ cursor: 'pointer', height: '100%', width: '100%' }}
style={{
cursor: 'pointer',
height: '100%',
width: '100%',
border: 1,
borderStyle: 'solid',
borderColor: theme.palette.grey[300],
}}
onClick={isTouchDevice ? undefined : () => onClick(hash)}
onTouchStart={isTouchDevice ? () => onClick(hash) : undefined}
>
<div style={{ border: 1, borderColor: theme.palette.grey[300] }}>
<div>
<img
style={{
width: '100%', // image should be full width / height of the item
Expand Down
2 changes: 1 addition & 1 deletion packages/procaptcha-react/src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const ModalComponent = React.memo((props: ModalProps, nextProps: ModalProps) =>
left: '50%',
transform: 'translate(-50%, -50%)',
width: '400px',
backgroundColor: 'rgb(255, 255, 255)',
backgroundColor: 'transparent',
border: 'none',
boxShadow:
'rgba(0, 0, 0, 0.2) 0px 11px 15px -7px, rgba(0, 0, 0, 0.14) 0px 24px 38px 3px, rgba(0, 0, 0, 0.12) 0px 9px 46px 8px,',
Expand Down
10 changes: 10 additions & 0 deletions packages/web-components/src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const grey = {
900: '#212121',
}

const DEFAULT_SPACING = 10 // size in pixels

export const lightTheme = {
palette: {
mode: 'light',
Expand All @@ -38,6 +40,10 @@ export const lightTheme = {
},
grey,
},
spacing: {
unit: DEFAULT_SPACING,
half: Math.floor(DEFAULT_SPACING / 2),
},
}

export const darkTheme = {
Expand All @@ -53,4 +59,8 @@ export const darkTheme = {
},
grey,
},
spacing: {
unit: DEFAULT_SPACING,
half: Math.floor(DEFAULT_SPACING / 2),
},
}

0 comments on commit 2b8f371

Please sign in to comment.