1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-21 09:38:01 +02:00

Desktop: Resolves #4462: Improved usability when plugin repository cannot be connected to

This commit is contained in:
Laurent Cozic 2021-05-15 16:04:10 +02:00
parent bb275e671d
commit 03db0c5486
6 changed files with 56 additions and 5 deletions

View File

@ -677,6 +677,9 @@ packages/app-desktop/gui/style/StyledFormLabel.js.map
packages/app-desktop/gui/style/StyledInput.d.ts packages/app-desktop/gui/style/StyledInput.d.ts
packages/app-desktop/gui/style/StyledInput.js packages/app-desktop/gui/style/StyledInput.js
packages/app-desktop/gui/style/StyledInput.js.map packages/app-desktop/gui/style/StyledInput.js.map
packages/app-desktop/gui/style/StyledLink.d.ts
packages/app-desktop/gui/style/StyledLink.js
packages/app-desktop/gui/style/StyledLink.js.map
packages/app-desktop/gui/style/StyledMessage.d.ts packages/app-desktop/gui/style/StyledMessage.d.ts
packages/app-desktop/gui/style/StyledMessage.js packages/app-desktop/gui/style/StyledMessage.js
packages/app-desktop/gui/style/StyledMessage.js.map packages/app-desktop/gui/style/StyledMessage.js.map

3
.gitignore vendored
View File

@ -663,6 +663,9 @@ packages/app-desktop/gui/style/StyledFormLabel.js.map
packages/app-desktop/gui/style/StyledInput.d.ts packages/app-desktop/gui/style/StyledInput.d.ts
packages/app-desktop/gui/style/StyledInput.js packages/app-desktop/gui/style/StyledInput.js
packages/app-desktop/gui/style/StyledInput.js.map packages/app-desktop/gui/style/StyledInput.js.map
packages/app-desktop/gui/style/StyledLink.d.ts
packages/app-desktop/gui/style/StyledLink.js
packages/app-desktop/gui/style/StyledLink.js.map
packages/app-desktop/gui/style/StyledMessage.d.ts packages/app-desktop/gui/style/StyledMessage.d.ts
packages/app-desktop/gui/style/StyledMessage.js packages/app-desktop/gui/style/StyledMessage.js
packages/app-desktop/gui/style/StyledMessage.js.map packages/app-desktop/gui/style/StyledMessage.js.map

View File

@ -13,8 +13,13 @@ import { PluginItem } from './PluginBox';
import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi'; import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi';
import Setting from '@joplin/lib/models/Setting'; import Setting from '@joplin/lib/models/Setting';
import useOnInstallHandler, { OnPluginSettingChangeEvent } from './useOnInstallHandler'; import useOnInstallHandler, { OnPluginSettingChangeEvent } from './useOnInstallHandler';
import Logger from '@joplin/lib/Logger';
import StyledMessage from '../../../style/StyledMessage';
import StyledLink from '../../../style/StyledLink';
const { space } = require('styled-system'); const { space } = require('styled-system');
const logger = Logger.create('PluginState');
const maxWidth: number = 320; const maxWidth: number = 320;
const Root = styled.div` const Root = styled.div`
@ -32,6 +37,11 @@ const ToolsButton = styled(Button)`
margin-right: 6px; margin-right: 6px;
`; `;
const RepoApiErrorMessage = styled(StyledMessage)`
max-width: ${props => props.maxWidth}px;
margin-bottom: 10px;
`;
interface Props { interface Props {
value: any; value: any;
themeId: number; themeId: number;
@ -84,6 +94,8 @@ export default function(props: Props) {
const [manifestsLoaded, setManifestsLoaded] = useState<boolean>(false); const [manifestsLoaded, setManifestsLoaded] = useState<boolean>(false);
const [updatingPluginsIds, setUpdatingPluginIds] = useState<Record<string, boolean>>({}); const [updatingPluginsIds, setUpdatingPluginIds] = useState<Record<string, boolean>>({});
const [canBeUpdatedPluginIds, setCanBeUpdatedPluginIds] = useState<Record<string, boolean>>({}); const [canBeUpdatedPluginIds, setCanBeUpdatedPluginIds] = useState<Record<string, boolean>>({});
const [repoApiError, setRepoApiError] = useState<Error>(null);
const [fetchManifestTime, setFetchManifestTime] = useState<number>(Date.now());
const pluginService = PluginService.instance(); const pluginService = PluginService.instance();
@ -96,9 +108,25 @@ export default function(props: Props) {
useEffect(() => { useEffect(() => {
let cancelled = false; let cancelled = false;
async function fetchManifests() { async function fetchManifests() {
await repoApi().loadManifests(); setManifestsLoaded(false);
setRepoApiError(null);
let loadError: Error = null;
try {
await repoApi().loadManifests();
} catch (error) {
logger.error(error);
loadError = error;
}
if (cancelled) return; if (cancelled) return;
setManifestsLoaded(true);
if (loadError) {
setManifestsLoaded(false);
setRepoApiError(loadError);
} else {
setManifestsLoaded(true);
}
} }
void fetchManifests(); void fetchManifests();
@ -106,7 +134,7 @@ export default function(props: Props) {
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, []); }, [fetchManifestTime]);
useEffect(() => { useEffect(() => {
if (!manifestsLoaded) return () => {}; if (!manifestsLoaded) return () => {};
@ -252,7 +280,7 @@ export default function(props: Props) {
function renderSearchArea() { function renderSearchArea() {
return ( return (
<div style={{ marginBottom: 20 }}> <div style={{ marginBottom: 0 }}>
<SearchPlugins <SearchPlugins
disabled={!manifestsLoaded} disabled={!manifestsLoaded}
maxWidth={maxWidth} maxWidth={maxWidth}
@ -268,11 +296,18 @@ export default function(props: Props) {
); );
} }
function renderRepoApiError() {
if (!repoApiError) return null;
return <RepoApiErrorMessage maxWidth={maxWidth} type="error">{_('Could not connect to plugin repository')} - <StyledLink href="#" onClick={() => { setFetchManifestTime(Date.now); }}>{_('Try again')}</StyledLink></RepoApiErrorMessage>;
}
function renderBottomArea() { function renderBottomArea() {
if (searchQuery) return null; if (searchQuery) return null;
return ( return (
<div> <div>
{renderRepoApiError()}
<div style={{ display: 'flex', flexDirection: 'row', maxWidth }}> <div style={{ display: 'flex', flexDirection: 'row', maxWidth }}>
<ToolsButton tooltip={_('Plugin tools')} iconName="fas fa-cog" level={ButtonLevel.Secondary} onClick={onToolsClick}/> <ToolsButton tooltip={_('Plugin tools')} iconName="fas fa-cog" level={ButtonLevel.Secondary} onClick={onToolsClick}/>
<div style={{ display: 'flex', flex: 1 }}> <div style={{ display: 'flex', flex: 1 }}>

View File

@ -101,7 +101,7 @@ export default function(props: Props) {
onChange={onChange} onChange={onChange}
onSearchButtonClick={onSearchButtonClick} onSearchButtonClick={onSearchButtonClick}
searchStarted={searchStarted} searchStarted={searchStarted}
placeholder={_('Search for plugins...')} placeholder={props.disabled ? _('Please wait...') : _('Search for plugins...')}
disabled={props.disabled} disabled={props.disabled}
/> />
</div> </div>

View File

@ -0,0 +1,9 @@
import styled from 'styled-components';
const StyledLink = styled.a`
font-size: ${props => props.theme.fontSize}px;
color: ${props => props.theme.urlColor};
font-family: ${props => props.theme.fontFamily};
`;
export default StyledLink;

View File

@ -7,6 +7,7 @@ const StyledMessage = styled.div`
color: ${props => props.theme.color}; color: ${props => props.theme.color};
font-family: ${props => props.theme.fontFamily}; font-family: ${props => props.theme.fontFamily};
padding: ${props => props.type === 'error' ? props.theme.mainPadding : '0'}px; padding: ${props => props.type === 'error' ? props.theme.mainPadding : '0'}px;
word-break: break-all;
`; `;
export default StyledMessage; export default StyledMessage;