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

Release v4.9.2 #4914

Merged
merged 7 commits into from
Sep 22, 2023
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.9.2] - 2023-09-22

### Changed

- Captcha was moved to the last signup step

### Fixed

- Fixed bug with checking the encoding for non-video assets
- Fixed bug with missing upload button for mobile devices
- Fixed bug with infinite modal on signup

## [4.9.1] - 2023-09-14

### Changed
Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@joystream/atlas",
"description": "UI for consuming Joystream - a user governed video platform",
"version": "4.9.1",
"version": "4.9.2",
"license": "GPL-3.0",
"scripts": {
"start": "vite",
Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/src/components/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type ListProps = {

export const List: FC<ListProps> = ({ items, size, className, scrollable = false }) => {
return (
<ListWrapper className={className} scrollable={scrollable} size={size}>
<ListWrapper data-scroll-lock-scrollable className={className} scrollable={scrollable} size={size}>
{items.map((item, index) => {
const component = <ListItem key={index} {...item} size={size} />

Expand Down
10 changes: 3 additions & 7 deletions packages/atlas/src/components/_auth/SignUpModal/SignUpModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useGetMembershipsLazyQuery } from '@/api/queries/__generated__/membersh
import { Button } from '@/components/_buttons/Button'
import { DialogButtonProps } from '@/components/_overlays/Dialog'
import { DialogModal } from '@/components/_overlays/DialogModal'
import { AccountFormData, FaucetError, MemberFormData, RegisterError, useCreateMember } from '@/hooks/useCreateMember'
import { AccountFormData, MemberFormData, RegisterError, useCreateMember } from '@/hooks/useCreateMember'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { useSegmentAnalytics } from '@/hooks/useSegmentAnalytics'
import { useUniqueMemberHandle } from '@/hooks/useUniqueMemberHandle'
Expand Down Expand Up @@ -214,12 +214,8 @@ export const SignUpModal = () => {
onStart: () => {
goToStep(SignUpSteps.Creating)
},
onError: (error) => {
if (error === FaucetError.MemberAlreadyCreatedForGoogleAccount) {
setAuthModalOpenName(undefined)
} else {
goToStep(SignUpSteps.CreateMember)
}
onError: () => {
setAuthModalOpenName(undefined)
},
})
if (memberId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import HCaptcha from '@hcaptcha/react-hcaptcha'
import debouncePromise from 'awesome-debounce-promise'
import { FC, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
Expand All @@ -9,7 +8,6 @@ import { TextButton } from '@/components/_buttons/Button'
import { FormField } from '@/components/_inputs/FormField'
import { Input } from '@/components/_inputs/Input'
import { ImageCropModal, ImageCropModalImperativeHandle } from '@/components/_overlays/ImageCropModal'
import { atlasConfig } from '@/config'
import { MEMBERSHIP_NAME_PATTERN } from '@/config/regex'
import { MemberFormData } from '@/hooks/useCreateMember'
import { useUniqueMemberHandle } from '@/hooks/useUniqueMemberHandle'
Expand All @@ -28,7 +26,6 @@ export const SignUpMembershipStep: FC<SignInModalMembershipStepProps> = ({
setPrimaryButtonProps,
onSubmit,
hasNavigatedBack,
dialogContentRef,
avatar,
handle,
}) => {
Expand All @@ -53,12 +50,9 @@ export const SignUpMembershipStep: FC<SignInModalMembershipStepProps> = ({
shallow
)
const handleInputRef = useRef<HTMLInputElement | null>(null)
const captchaInputRef = useRef<HTMLDivElement | null>(null)
const avatarDialogRef = useRef<ImageCropModalImperativeHandle>(null)

const [isHandleValidating, setIsHandleValidating] = useState(false)
// used to scroll the form to the bottom upon first handle field focus - this is done to let the user see Captcha form field
const hasDoneInitialScroll = useRef(false)

const { checkIfMemberIsAvailable } = useUniqueMemberHandle()

Expand Down Expand Up @@ -109,11 +103,7 @@ export const SignUpMembershipStep: FC<SignInModalMembershipStepProps> = ({
if (errors.handle) {
handleInputRef.current?.scrollIntoView({ behavior: 'smooth' })
}

if (errors.captchaToken) {
captchaInputRef.current?.scrollIntoView({ behavior: 'smooth' })
}
}, [errors.captchaToken, errors.handle])
}, [errors.handle])

return (
<AuthenticationModalStepTemplate
Expand Down Expand Up @@ -179,39 +169,8 @@ export const SignUpMembershipStep: FC<SignInModalMembershipStepProps> = ({
error={!!errors.handle}
processing={isHandleValidating || isSubmitting}
autoComplete="off"
onClick={() => {
if (hasDoneInitialScroll.current || !dialogContentRef?.current) return
hasDoneInitialScroll.current = true
dialogContentRef.current.scrollTo({ top: dialogContentRef.current.scrollHeight, behavior: 'smooth' })
}}
/>
</FormField>
{atlasConfig.features.members.hcaptchaSiteKey && (
<Controller
control={control}
name="captchaToken"
render={({ field: { onChange }, fieldState: { error } }) => (
<FormField error={error?.message} ref={captchaInputRef}>
<HCaptcha
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
sitekey={atlasConfig.features.members.hcaptchaSiteKey!}
theme="dark"
languageOverride="en"
onVerify={(token) => {
onChange(token)
trigger('captchaToken')
}}
/>
</FormField>
)}
rules={{
required: {
value: !!atlasConfig.features.members.hcaptchaSiteKey,
message: "Verify that you're not a robot.",
},
}}
/>
)}
</StyledForm>
}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import HCaptcha from '@hcaptcha/react-hcaptcha'
import { zodResolver } from '@hookform/resolvers/zod'
import { FC, RefObject, useCallback, useEffect, useRef } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { Controller, FormProvider, useForm } from 'react-hook-form'

import { AuthenticationModalStepTemplate } from '@/components/_auth/AuthenticationModalStepTemplate'
import { PasswordCriterias } from '@/components/_auth/PasswordCriterias'
import { FormField } from '@/components/_inputs/FormField'
import { Input } from '@/components/_inputs/Input'
import { atlasConfig } from '@/config'
import { AccountFormData } from '@/hooks/useCreateMember'
import { useHidePasswordInInput } from '@/hooks/useHidePasswordInInput'
import { passwordAndRepeatPasswordSchema } from '@/utils/formValidationOptions'
Expand All @@ -16,6 +18,7 @@ import { SignUpStepsCommonProps } from '../SignUpSteps.types'
type PasswordStepForm = {
password: string
confirmPassword: string
captchaToken?: string
}

type SignUpPasswordStepProps = {
Expand All @@ -34,6 +37,7 @@ export const SignUpPasswordStep: FC<SignUpPasswordStepProps> = ({
}) => {
const form = useForm<PasswordStepForm>({
shouldFocusError: true,
reValidateMode: 'onSubmit',
defaultValues: {
password,
confirmPassword: password,
Expand All @@ -44,11 +48,17 @@ export const SignUpPasswordStep: FC<SignUpPasswordStepProps> = ({
handleSubmit,
register,
formState: { errors },
control,
trigger,
} = form
const [hidePasswordProps] = useHidePasswordInInput()
const [hideConfirmPasswordProps] = useHidePasswordInInput()

const captchaRef = useRef<HCaptcha | null>(null)
const captchaInputRef = useRef<HTMLDivElement | null>(null)

const handleGoToNextStep = useCallback(() => {
captchaRef.current?.resetCaptcha()
handleSubmit((data) => {
onPasswordSubmit(data.password)
})()
Expand All @@ -61,7 +71,13 @@ export const SignUpPasswordStep: FC<SignUpPasswordStepProps> = ({
})
}, [handleGoToNextStep, setPrimaryButtonProps])

// used to scroll the form to the bottom upon first handle field focus - this is done to let the user see password requirements
useEffect(() => {
if (errors.captchaToken) {
captchaInputRef.current?.scrollIntoView({ behavior: 'smooth' })
}
}, [errors.captchaToken])

// used to scroll the form to the bottom upon first handle field focus - this is done to let the user see password requirements & captcha
const hasDoneInitialScroll = useRef(false)

return (
Expand Down Expand Up @@ -96,6 +112,27 @@ export const SignUpPasswordStep: FC<SignUpPasswordStepProps> = ({
/>
</FormField>
<PasswordCriterias />
{atlasConfig.features.members.hcaptchaSiteKey && (
<Controller
control={control}
name="captchaToken"
render={({ field: { onChange }, fieldState: { error } }) => (
<FormField error={error?.message} ref={captchaInputRef}>
<HCaptcha
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
sitekey={atlasConfig.features.members.hcaptchaSiteKey!}
theme="dark"
languageOverride="en"
ref={captchaRef}
onVerify={(token) => {
onChange(token)
trigger('captchaToken')
}}
/>
</FormField>
)}
/>
)}
</StyledSignUpForm>
</AuthenticationModalStepTemplate>
</FormProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export const MultiFileSelect: FC<MultiFileSelectProps> = memo(
} else if (errorCode === 'file-too-large') {
setError('File too large')
} else {
SentryLogger.error('Unknown file select error', 'MultiFileSelect', null, { error: { code: errorCode } })
SentryLogger.error('Unknown file select error', 'MultiFileSelect', null, { parsedError: { code: errorCode } })
setError('Unknown error')
}
}, [])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import styled from '@emotion/styled'

import { ActionBar } from '@/components/ActionBar'
import { cVar, zIndex } from '@/styles'

export const DrawerOverlay = styled.div`
Expand Down Expand Up @@ -43,7 +42,7 @@ export const Container = styled.div`
top: var(--size-topbar-height);
left: 0;
right: 0;
height: calc(100vh - var(--size-topbar-height));
height: calc(100% - var(--size-topbar-height));
display: flex;
flex-direction: column;
background-color: ${cVar('colorBackground')};
Expand Down Expand Up @@ -75,20 +74,15 @@ export const Container = styled.div`
}
`

type ScrollContainerProps = {
actionBarHeight?: number
fixedScrollbar?: boolean
}
export const ScrollContainer = styled.div<ScrollContainerProps>`
export const Outer = styled.div`
position: relative;
flex: 1;
margin-bottom: ${({ actionBarHeight = 0 }) => actionBarHeight}px;
overflow-y: ${({ fixedScrollbar }) => (fixedScrollbar ? 'scroll' : 'auto')};
overflow-x: hidden;
width: 100%;
`

export const StyledActionBar = styled(ActionBar)`
position: fixed;
bottom: 0;
right: 0;
left: 0;
export const Inner = styled.div<{ fixedScrollbar?: boolean }>`
position: absolute;
inset: 0;
overflow-x: hidden;
overflow-y: ${({ fixedScrollbar }) => (fixedScrollbar ? 'scroll' : 'auto')};
`
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { FC, PropsWithChildren, useEffect, useState } from 'react'
import { CSSTransition } from 'react-transition-group'
import useResizeObserver from 'use-resize-observer'

import { ActionBarProps } from '@/components/ActionBar'
import { ActionBar, ActionBarProps } from '@/components/ActionBar'
import { DrawerHeader } from '@/components/DrawerHeader'
import { useHeadTags } from '@/hooks/useHeadTags'
import { useOverlayManager } from '@/providers/overlayManager'
import { cVar } from '@/styles'

import { Container, DrawerOverlay, ScrollContainer, StyledActionBar } from './BottomDrawer.styles'
import { Container, DrawerOverlay, Inner, Outer } from './BottomDrawer.styles'

export type BottomDrawerProps = PropsWithChildren<{
isOpen: boolean
Expand Down Expand Up @@ -36,10 +35,6 @@ export const BottomDrawer: FC<BottomDrawerProps> = ({
const { lastOverlayId, decrementOverlaysOpenCount, incrementOverlaysOpenCount } = useOverlayManager()
const [overlayId, setOverlayId] = useState<string | null>(null)

const actionBarActive = actionBar?.isActive ?? true
const { ref: actionBarRef, height: _actionBarHeight } = useResizeObserver({ box: 'border-box' })
const actionBarHeight = actionBarActive ? _actionBarHeight : 0

useEffect(() => {
if (isOpen === cachedIsOpen) return

Expand Down Expand Up @@ -92,14 +87,13 @@ export const BottomDrawer: FC<BottomDrawerProps> = ({
>
<Container role="dialog">
<DrawerHeader title={title} label={titleLabel} onCloseClick={onClose} />
<ScrollContainer
data-scroll-lock-scrollable
actionBarHeight={actionBarHeight}
fixedScrollbar={fixedScrollbar}
>
{children}
</ScrollContainer>
{actionBar ? <StyledActionBar ref={actionBarRef} {...actionBar} /> : null}
<Outer>
<Inner fixedScrollbar={fixedScrollbar} data-scroll-lock-scrollable>
{children}
</Inner>
</Outer>

{actionBar ? <ActionBar {...actionBar} /> : null}
</Container>
</CSSTransition>
</>
Expand Down
4 changes: 3 additions & 1 deletion packages/atlas/src/hooks/useCreateMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ export const useCreateMember = () => {

const errorCode = isAxiosError<NewMemberErrorResponse>(error) ? error.response?.data?.error : null

SentryLogger.error('Failed to create a membership', 'SignUpModal', error, { error: { errorCode } })
SentryLogger.error(`Failed to create a membership ${ytResponseData ? 'YPP' : ''}`, 'SignUpModal', error, {
parsed: { errorCode },
})

switch (errorCode) {
case 'TooManyRequestsPerIp':
Expand Down
15 changes: 12 additions & 3 deletions packages/atlas/src/hooks/useGetAssetUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,19 @@ export const getSingleAssetUrl = async (
return distributionAssetUrl
} catch (err) {
if (err instanceof MediaError) {
const codec = getVideoCodec(distributionAssetUrl)
UserEventsLogger.logWrongCodecEvent(eventEntry, { codec })
let codec = ''
if (type === 'video') {
codec = getVideoCodec(distributionAssetUrl)
}
UserEventsLogger.logWrongCodecEvent(eventEntry, { assetType: type, ...(type === 'video' ? { codec } : {}) })
SentryLogger.error('Error during asset download test, media is not supported', 'AssetsManager', err, {
asset: { parent, distributionAssetUrl, mediaError: err, codec },
asset: {
parent,
distributionAssetUrl,
mediaError: err,
assetType: type,
...(type === 'video' ? { codec } : {}),
},
})
}
}
Expand Down
Loading
Loading