mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-26 13:19:34 +07:00
💄 style(desktop): improve WelcomeStep layout centering in onboarding (#13125)
* 💄 style(desktop): improve WelcomeStep layout centering in onboarding Made-with: Cursor * 🐛 fix(desktop): validate remote server URL in isRemoteServerConfigured Made-with: Cursor
This commit is contained in:
@@ -93,10 +93,26 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
||||
*/
|
||||
async isRemoteServerConfigured(config?: DataSyncConfig): Promise<boolean> {
|
||||
const effectiveConfig = config ?? (await this.getRemoteServerConfig());
|
||||
return (
|
||||
effectiveConfig.active &&
|
||||
(effectiveConfig.storageMode !== 'selfHost' || !!effectiveConfig.remoteServerUrl)
|
||||
);
|
||||
const isActive = Boolean(effectiveConfig.active);
|
||||
const isSelfHostConfigured =
|
||||
effectiveConfig.storageMode !== 'selfHost' ||
|
||||
this.isValidSelfHostRemoteUrl(effectiveConfig.remoteServerUrl);
|
||||
|
||||
return isActive && isSelfHostConfigured;
|
||||
}
|
||||
|
||||
private isValidSelfHostRemoteUrl(remoteServerUrl?: string): boolean {
|
||||
if (!remoteServerUrl) return false;
|
||||
const normalizedUrl = remoteServerUrl.trim();
|
||||
|
||||
if (!normalizedUrl) return false;
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(normalizedUrl);
|
||||
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,7 +553,7 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
||||
}
|
||||
|
||||
async getRemoteServerUrl(config?: DataSyncConfig) {
|
||||
const dataConfig = this.normalizeConfig(config ? config : await this.getRemoteServerConfig());
|
||||
const dataConfig = this.normalizeConfig(config ?? (await this.getRemoteServerConfig()));
|
||||
|
||||
return dataConfig.storageMode === 'cloud' ? OFFICIAL_CLOUD_SERVER : dataConfig.remoteServerUrl;
|
||||
}
|
||||
|
||||
@@ -747,6 +747,16 @@ describe('RemoteServerConfigCtr', () => {
|
||||
});
|
||||
|
||||
describe('isRemoteServerConfigured', () => {
|
||||
it('should return false when active is undefined', async () => {
|
||||
mockStoreManager.get.mockReturnValue({
|
||||
storageMode: 'cloud',
|
||||
});
|
||||
|
||||
const result = await controller.isRemoteServerConfigured();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true for active cloud mode (no remoteServerUrl needed)', async () => {
|
||||
mockStoreManager.get.mockReturnValue({
|
||||
active: true,
|
||||
@@ -794,6 +804,30 @@ describe('RemoteServerConfigCtr', () => {
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for selfHost mode with blank remoteServerUrl', async () => {
|
||||
mockStoreManager.get.mockReturnValue({
|
||||
active: true,
|
||||
remoteServerUrl: ' ',
|
||||
storageMode: 'selfHost',
|
||||
});
|
||||
|
||||
const result = await controller.isRemoteServerConfigured();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false for selfHost mode with invalid remoteServerUrl', async () => {
|
||||
mockStoreManager.get.mockReturnValue({
|
||||
active: true,
|
||||
remoteServerUrl: 'foo',
|
||||
storageMode: 'selfHost',
|
||||
});
|
||||
|
||||
const result = await controller.isRemoteServerConfigured();
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should use provided config instead of fetching', async () => {
|
||||
// Store has inactive config
|
||||
mockStoreManager.get.mockReturnValue({
|
||||
|
||||
@@ -46,9 +46,9 @@ const WelcomeStep = memo<WelcomeStepProps>(({ onNext }) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flexbox gap={16}>
|
||||
<Flexbox align="center" gap={16} justify="center">
|
||||
<ProductLogo size={64} />
|
||||
<Flexbox style={{ marginBottom: 16 }}>
|
||||
<Flexbox align="center" gap={16} justify="center" style={{ marginBottom: 16 }}>
|
||||
<Text as={'h1'} fontSize={28} weight={'bold'}>
|
||||
<TypewriterEffect
|
||||
cursorCharacter={<LoadingDots size={28} variant={'pulse'} />}
|
||||
|
||||
Reference in New Issue
Block a user