Bug: Add custom app feature works weird or doesn't work (#2279)

* prevent trigger for "" value

* remove autocomplete for input

* Add loading indicator

* Ivan feedback

* fix  jumping

* Rename prop

Co-authored-by: katspaugh <katspaugh@users.noreply.github.com>
This commit is contained in:
nicolas 2021-05-14 06:32:49 -03:00 committed by GitHub
parent f9f7b3dad2
commit 4f6a3e93eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 9 deletions

View File

@ -28,22 +28,34 @@ export const appUrlResolver = createDecorator({
}, },
}) })
export const AppInfoUpdater = ({ onAppInfo }: { onAppInfo: (appInfo: SafeApp) => void }): null => { type AppInfoUpdaterProps = {
onAppInfo: (appInfo: SafeApp) => void
onLoading: (isLoading: boolean) => void
}
export const AppInfoUpdater = ({ onAppInfo, onLoading }: AppInfoUpdaterProps): null => {
const { const {
input: { value: appUrl }, input: { value: appUrl },
} = useField('appUrl', { subscription: { value: true } }) } = useField('appUrl', { subscription: { value: true } })
const debouncedValue = useDebounce(appUrl, 500) const debouncedValue = useDebounce(appUrl, 500)
React.useEffect(() => { React.useEffect(() => {
const updateAppInfo = async () => { const updateAppInfo = async () => {
const appInfo = await getAppInfoFromUrl(debouncedValue) try {
onAppInfo({ ...appInfo }) onLoading(true)
const appInfo = await getAppInfoFromUrl(debouncedValue)
onAppInfo({ ...appInfo })
onLoading(false)
} catch (error) {
onLoading(false)
}
} }
if (isValidURL(debouncedValue)) { if (isValidURL(debouncedValue)) {
updateAppInfo() updateAppInfo()
} }
}, [debouncedValue, onAppInfo]) }, [debouncedValue, onAppInfo, onLoading])
return null return null
} }
@ -55,7 +67,15 @@ const AppUrl = ({ appList }: { appList: SafeApp[] }): React.ReactElement => {
const validate = !visited?.appUrl ? undefined : composeValidators(required, validateUrl, uniqueApp(appList)) const validate = !visited?.appUrl ? undefined : composeValidators(required, validateUrl, uniqueApp(appList))
return ( return (
<Field label="App URL" name="appUrl" placeholder="App URL" type="text" component={TextField} validate={validate} /> <Field
label="App URL"
name="appUrl"
placeholder="App URL"
type="text"
component={TextField}
validate={validate}
autoComplete="off"
/>
) )
} }

View File

@ -1,4 +1,4 @@
import { TextField } from '@gnosis.pm/safe-react-components' import { TextField, Loader } from '@gnosis.pm/safe-react-components'
import React, { useState, ReactElement } from 'react' import React, { useState, ReactElement } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
@ -24,6 +24,7 @@ const StyledTextFileAppName = styled(TextField)`
` `
const AppInfo = styled.div` const AppInfo = styled.div`
display: flex;
margin: 36px 0 24px 0; margin: 36px 0 24px 0;
img { img {
@ -41,6 +42,18 @@ const AppDocsInfo = styled.div`
} }
` `
const WrapperLoader = styled.div`
height: 55px;
width: 65px;
display: flex;
align-items: center;
justify-content: center;
`
const StyledLoader = styled(Loader)`
margin-right: 15px;
`
interface AddAppFormValues { interface AddAppFormValues {
appUrl: string appUrl: string
agreementAccepted: boolean agreementAccepted: boolean
@ -62,6 +75,7 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => {
const [appInfo, setAppInfo] = useState<SafeApp>(APP_INFO) const [appInfo, setAppInfo] = useState<SafeApp>(APP_INFO)
const history = useHistory() const history = useHistory()
const matchSafeWithAddress = useRouteMatch<{ safeAddress: string }>({ path: `${SAFELIST_ADDRESS}/:safeAddress` }) const matchSafeWithAddress = useRouteMatch<{ safeAddress: string }>({ path: `${SAFELIST_ADDRESS}/:safeAddress` })
const [isLoading, setIsLoading] = useState(false)
const handleSubmit = () => { const handleSubmit = () => {
const newAppList = [ const newAppList = [
@ -93,14 +107,26 @@ const AddApp = ({ appList, closeModal }: AddAppProps): ReactElement => {
<Icon size="sm" type="externalLink" color="primary" /> <Icon size="sm" type="externalLink" color="primary" />
</Link> </Link>
</AppDocsInfo> </AppDocsInfo>
<AppUrl appList={appList} /> <AppUrl appList={appList} />
{/* Fetch app from url and return a SafeApp */} {/* Fetch app from url and return a SafeApp */}
<AppInfoUpdater onAppInfo={setAppInfo} /> <AppInfoUpdater onAppInfo={setAppInfo} onLoading={setIsLoading} />
<AppInfo> <AppInfo>
<Img alt="Token image" height={55} src={appInfo.iconUrl} /> {isLoading ? (
<StyledTextFileAppName label="App name" readOnly value={appInfo.name} onChange={() => {}} /> <WrapperLoader>
<StyledLoader size="sm" />
</WrapperLoader>
) : (
<Img alt="Token image" width={55} src={appInfo.iconUrl} />
)}
<StyledTextFileAppName
label="App name"
readOnly
value={isLoading ? 'Loading...' : appInfo.name}
onChange={() => {}}
/>
</AppInfo> </AppInfo>
<AppAgreement /> <AppAgreement />