You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop: Resolves #4462: Improved usability when plugin repository cannot be connected to
This commit is contained in:
		| @@ -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.js | ||||
| 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.js | ||||
| packages/app-desktop/gui/style/StyledMessage.js.map | ||||
|   | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -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.js | ||||
| 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.js | ||||
| packages/app-desktop/gui/style/StyledMessage.js.map | ||||
|   | ||||
| @@ -13,8 +13,13 @@ import { PluginItem } from './PluginBox'; | ||||
| import RepositoryApi from '@joplin/lib/services/plugins/RepositoryApi'; | ||||
| import Setting from '@joplin/lib/models/Setting'; | ||||
| 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 logger = Logger.create('PluginState'); | ||||
|  | ||||
| const maxWidth: number = 320; | ||||
|  | ||||
| const Root = styled.div` | ||||
| @@ -32,6 +37,11 @@ const ToolsButton = styled(Button)` | ||||
| 	margin-right: 6px; | ||||
| `; | ||||
|  | ||||
| const RepoApiErrorMessage = styled(StyledMessage)` | ||||
| 	max-width: ${props => props.maxWidth}px; | ||||
| 	margin-bottom: 10px; | ||||
| `; | ||||
|  | ||||
| interface Props { | ||||
| 	value: any; | ||||
| 	themeId: number; | ||||
| @@ -84,6 +94,8 @@ export default function(props: Props) { | ||||
| 	const [manifestsLoaded, setManifestsLoaded] = useState<boolean>(false); | ||||
| 	const [updatingPluginsIds, setUpdatingPluginIds] = 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(); | ||||
|  | ||||
| @@ -96,9 +108,25 @@ export default function(props: Props) { | ||||
| 	useEffect(() => { | ||||
| 		let cancelled = false; | ||||
| 		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; | ||||
| 			setManifestsLoaded(true); | ||||
|  | ||||
| 			if (loadError) { | ||||
| 				setManifestsLoaded(false); | ||||
| 				setRepoApiError(loadError); | ||||
| 			} else { | ||||
| 				setManifestsLoaded(true); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		void fetchManifests(); | ||||
| @@ -106,7 +134,7 @@ export default function(props: Props) { | ||||
| 		return () => { | ||||
| 			cancelled = true; | ||||
| 		}; | ||||
| 	}, []); | ||||
| 	}, [fetchManifestTime]); | ||||
|  | ||||
| 	useEffect(() => { | ||||
| 		if (!manifestsLoaded) return () => {}; | ||||
| @@ -252,7 +280,7 @@ export default function(props: Props) { | ||||
|  | ||||
| 	function renderSearchArea() { | ||||
| 		return ( | ||||
| 			<div style={{ marginBottom: 20 }}> | ||||
| 			<div style={{ marginBottom: 0 }}> | ||||
| 				<SearchPlugins | ||||
| 					disabled={!manifestsLoaded} | ||||
| 					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() { | ||||
| 		if (searchQuery) return null; | ||||
|  | ||||
| 		return ( | ||||
| 			<div> | ||||
| 				{renderRepoApiError()} | ||||
| 				<div style={{ display: 'flex', flexDirection: 'row', maxWidth }}> | ||||
| 					<ToolsButton tooltip={_('Plugin tools')} iconName="fas fa-cog" level={ButtonLevel.Secondary} onClick={onToolsClick}/> | ||||
| 					<div style={{ display: 'flex', flex: 1 }}> | ||||
|   | ||||
| @@ -101,7 +101,7 @@ export default function(props: Props) { | ||||
| 					onChange={onChange} | ||||
| 					onSearchButtonClick={onSearchButtonClick} | ||||
| 					searchStarted={searchStarted} | ||||
| 					placeholder={_('Search for plugins...')} | ||||
| 					placeholder={props.disabled ? _('Please wait...') : _('Search for plugins...')} | ||||
| 					disabled={props.disabled} | ||||
| 				/> | ||||
| 			</div> | ||||
|   | ||||
							
								
								
									
										9
									
								
								packages/app-desktop/gui/style/StyledLink.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/app-desktop/gui/style/StyledLink.tsx
									
									
									
									
									
										Normal 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; | ||||
| @@ -7,6 +7,7 @@ const StyledMessage = styled.div` | ||||
| 	color: ${props => props.theme.color}; | ||||
| 	font-family: ${props => props.theme.fontFamily}; | ||||
| 	padding: ${props => props.type === 'error' ? props.theme.mainPadding : '0'}px; | ||||
| 	word-break: break-all; | ||||
| `; | ||||
|  | ||||
| export default StyledMessage; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user