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

Make the image captcha not look terrible #1287

Merged
merged 7 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -20,7 +20,7 @@
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable<Subject = any> {

Check warning on line 23 in demos/cypress-shared/cypress/support/commands.ts

View workflow job for this annotation

GitHub Actions / check

'Subject' is defined but never used

Check warning on line 23 in demos/cypress-shared/cypress/support/commands.ts

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
clickIAmHuman(): Cypress.Chainable<Captcha[]>
captchaImages(): Cypress.Chainable<JQuery<HTMLElement>>
clickCorrectCaptchaImages(captcha: Captcha): Chainable<JQuery<Node>>
Expand Down Expand Up @@ -59,20 +59,19 @@
}

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 @@ -23,7 +24,7 @@
themeColor: 'light' | 'dark'
}

const getHash = (item: any) => {

Check warning on line 27 in packages/procaptcha-react/src/components/CaptchaWidget.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
if (!item.hash) {
throw new ProsopoDatasetError('CAPTCHA.MISSING_ITEM_HASH', { context: { item } })
}
Expand All @@ -36,6 +37,20 @@

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 } = {

Check warning on line 43 in packages/procaptcha-react/src/components/CaptchaWidget.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
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 } = {

Check warning on line 49 in packages/procaptcha-react/src/components/CaptchaWidget.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
0: { paddingTop: fullSpacing },
2: { paddingBottom: fullSpacing },
}

return (
<div
style={{
Expand All @@ -52,26 +67,32 @@
>
{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 @@ -17,7 +17,7 @@
children: React.ReactNode
}

const ModalComponent = React.memo((props: ModalProps, nextProps: ModalProps) => {

Check warning on line 20 in packages/procaptcha-react/src/components/Modal.tsx

View workflow job for this annotation

GitHub Actions / check

'nextProps' is defined but never used
const { show, children } = props
const display = show ? 'block' : 'none'
const ModalOuterDivCss: CSSProperties = {
Expand Down Expand Up @@ -45,7 +45,7 @@
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),
},
}
Loading