feat: use baseurl from server config (#5369)

This commit is contained in:
DarkSky
2023-12-21 12:52:38 +00:00
parent 9fbd9b39d6
commit aa4d42b36c
16 changed files with 88 additions and 54 deletions
@@ -10,6 +10,9 @@ export class ServerConfigType {
@Field({ description: 'server flavor' }) @Field({ description: 'server flavor' })
flavor!: string; flavor!: string;
@Field({ description: 'server base url' })
baseUrl!: string;
} }
export class ServerConfigResolver { export class ServerConfigResolver {
@@ -20,6 +23,7 @@ export class ServerConfigResolver {
return { return {
version: AFFiNE.version, version: AFFiNE.version,
flavor: SERVER_FLAVOR, flavor: SERVER_FLAVOR,
baseUrl: AFFiNE.baseUrl,
}; };
} }
} }
+3
View File
@@ -8,6 +8,9 @@ type ServerConfigType {
"""server flavor""" """server flavor"""
flavor: String! flavor: String!
"""server base url"""
baseUrl: String!
} }
type UserQuotaHumanReadable { type UserQuotaHumanReadable {
@@ -391,7 +391,6 @@ export const createConfiguration: (
proxy: { proxy: {
'/api/worker/': { '/api/worker/': {
target: 'https://affine-worker.toeverything.workers.dev', target: 'https://affine-worker.toeverything.workers.dev',
pathRewrite: { '^/api/worker/': '/api/' },
changeOrigin: true, changeOrigin: true,
secure: false, secure: false,
}, },
@@ -33,7 +33,7 @@ export function getRuntimeConfig(buildFlags: BuildFlags): RuntimeConfig {
enablePayment: true, enablePayment: true,
enablePageHistory: false, enablePageHistory: false,
enableCopilot: false, enableCopilot: false,
serverUrlPrefix: 'https://insider.affine.pro', // Let insider be stable environment temporarily. serverUrlPrefix: 'https://app.affine.pro',
editorFlags, editorFlags,
appVersion: packageJson.version, appVersion: packageJson.version,
editorVersion: packageJson.dependencies['@blocksuite/presets'], editorVersion: packageJson.dependencies['@blocksuite/presets'],
@@ -8,7 +8,7 @@ import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useWorkspace } from '@toeverything/hooks/use-workspace'; import { useWorkspace } from '@toeverything/hooks/use-workspace';
import { useWorkspaceInfo } from '@toeverything/hooks/use-workspace-info'; import { useWorkspaceInfo } from '@toeverything/hooks/use-workspace-info';
import { useSelfHosted } from '../../../hooks/affine/use-server-flavor'; import { useSelfHosted } from '../../../hooks/affine/use-server-config';
import { DeleteLeaveWorkspace } from './delete-leave-workspace'; import { DeleteLeaveWorkspace } from './delete-leave-workspace';
import { EnableCloudPanel } from './enable-cloud'; import { EnableCloudPanel } from './enable-cloud';
import { ExportPanel } from './export'; import { ExportPanel } from './export';
@@ -34,7 +34,7 @@ import {
openSignOutModalAtom, openSignOutModalAtom,
} from '../../../../atoms'; } from '../../../../atoms';
import { useCurrentUser } from '../../../../hooks/affine/use-current-user'; import { useCurrentUser } from '../../../../hooks/affine/use-current-user';
import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; import { useSelfHosted } from '../../../../hooks/affine/use-server-config';
import { useUserSubscription } from '../../../../hooks/use-subscription'; import { useUserSubscription } from '../../../../hooks/use-subscription';
import { validateAndReduceImage } from '../../../../utils/reduce-image'; import { validateAndReduceImage } from '../../../../utils/reduce-image';
import { Upload } from '../../../pure/file-upload'; import { Upload } from '../../../pure/file-upload';
@@ -8,7 +8,7 @@ import {
import type { ReactElement, SVGProps } from 'react'; import type { ReactElement, SVGProps } from 'react';
import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status'; import { useCurrentLoginStatus } from '../../../../hooks/affine/use-current-login-status';
import { useSelfHosted } from '../../../../hooks/affine/use-server-flavor'; import { useSelfHosted } from '../../../../hooks/affine/use-server-config';
import { AboutAffine } from './about'; import { AboutAffine } from './about';
import { AppearanceSettings } from './appearance'; import { AppearanceSettings } from './appearance';
import { BillingSettings } from './billing'; import { BillingSettings } from './billing';
@@ -19,7 +19,7 @@ export const ShareExport = ({
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const workspaceId = workspace.id; const workspaceId = workspace.id;
const pageId = currentPage.id; const pageId = currentPage.id;
const { onClickCopyLink } = useSharingUrl({ const { sharingUrl, onClickCopyLink } = useSharingUrl({
workspaceId, workspaceId,
pageId, pageId,
urlType: 'workspace', urlType: 'workspace',
@@ -57,6 +57,7 @@ export const ShareExport = ({
onClick={onClickCopyLink} onClick={onClickCopyLink}
icon={<LinkIcon />} icon={<LinkIcon />}
type="plain" type="plain"
disabled={!sharingUrl}
> >
{t['com.affine.share-menu.copy-private-link']()} {t['com.affine.share-menu.copy-private-link']()}
</Button> </Button>
@@ -18,6 +18,7 @@ import { useCallback } from 'react';
import type { PageMode } from '../../../../atoms'; import type { PageMode } from '../../../../atoms';
import { currentModeAtom } from '../../../../atoms/mode'; import { currentModeAtom } from '../../../../atoms/mode';
import { useIsSharedPage } from '../../../../hooks/affine/use-is-shared-page'; import { useIsSharedPage } from '../../../../hooks/affine/use-is-shared-page';
import { useServerBaseUrl } from '../../../../hooks/affine/use-server-config';
import * as styles from './index.css'; import * as styles from './index.css';
import type { ShareMenuProps } from './share-menu'; import type { ShareMenuProps } from './share-menu';
import { useSharingUrl } from './use-share-url'; import { useSharingUrl } from './use-share-url';
@@ -98,6 +99,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
pageId, pageId,
urlType: 'share', urlType: 'share',
}); });
const baseUrl = useServerBaseUrl();
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const onClickCreateLink = useCallback(() => { const onClickCreateLink = useCallback(() => {
@@ -140,9 +142,13 @@ export const AffineSharePage = (props: ShareMenuProps) => {
lineHeight: '20px', lineHeight: '20px',
}} }}
value={ value={
isSharedPage (isSharedPage && sharingUrl) ||
? sharingUrl `${
: `${location.protocol}//${location.hostname}/...` baseUrl ||
`${location.protocol}${
location.port ? `:${location.port}` : ''
}//${location.hostname}`
}/...`
} }
readOnly readOnly
/> />
@@ -151,6 +157,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
onClick={onClickCopyLink} onClick={onClickCopyLink}
data-testid="share-menu-copy-link-button" data-testid="share-menu-copy-link-button"
style={{ padding: '4px 12px', whiteSpace: 'nowrap' }} style={{ padding: '4px 12px', whiteSpace: 'nowrap' }}
disabled={!sharingUrl}
> >
{t.Copy()} {t.Copy()}
</Button> </Button>
@@ -1,4 +1,5 @@
import { toast } from '@affine/component'; import { toast } from '@affine/component';
import { useServerBaseUrl } from '@affine/core/hooks/affine/use-server-config';
import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
@@ -10,22 +11,27 @@ type UseSharingUrl = {
urlType: UrlType; urlType: UrlType;
}; };
export const generateUrl = ({ const useGenerateUrl = ({ workspaceId, pageId, urlType }: UseSharingUrl) => {
workspaceId, // to generate a private url like https://app.affine.app/workspace/123/456
pageId, // to generate a public url like https://app.affine.app/share/123/456
urlType, // or https://app.affine.app/share/123/456?mode=edgeless
}: UseSharingUrl) => {
// to generate a private url like https://affine.app/workspace/123/456
// to generate a public url like https://affine.app/share/123/456
// or https://affine.app/share/123/456?mode=edgeless
const { protocol, hostname, port } = window.location; const baseUrl = useServerBaseUrl();
const url = new URL(
`${protocol}//${hostname}${ const url = useMemo(() => {
port ? `:${port}` : '' // baseUrl is null when running in electron and without network
}/${urlType}/${workspaceId}/${pageId}` if (!baseUrl) return null;
);
return url.toString(); try {
return new URL(
`${baseUrl}/${urlType}/${workspaceId}/${pageId}`
).toString();
} catch (e) {
return null;
}
}, [baseUrl, pageId, urlType, workspaceId]);
return url;
}; };
export const useSharingUrl = ({ export const useSharingUrl = ({
@@ -34,20 +40,21 @@ export const useSharingUrl = ({
urlType, urlType,
}: UseSharingUrl) => { }: UseSharingUrl) => {
const t = useAFFiNEI18N(); const t = useAFFiNEI18N();
const sharingUrl = useMemo( const sharingUrl = useGenerateUrl({ workspaceId, pageId, urlType });
() => generateUrl({ workspaceId, pageId, urlType }),
[workspaceId, pageId, urlType]
);
const onClickCopyLink = useCallback(() => { const onClickCopyLink = useCallback(() => {
navigator.clipboard if (sharingUrl) {
.writeText(sharingUrl) navigator.clipboard
.then(() => { .writeText(sharingUrl)
toast(t['Copied link to clipboard']()); .then(() => {
}) toast(t['Copied link to clipboard']());
.catch(err => { })
console.error(err); .catch(err => {
}); console.error(err);
});
} else {
toast('Network not available');
}
}, [sharingUrl, t]); }, [sharingUrl, t]);
return { return {
@@ -9,7 +9,7 @@ const errorHandler: Middleware = useSWRNext => (key, fetcher, config) => {
return useSWRNext(key, wrappedFetcher.bind(null, fetcher), config); return useSWRNext(key, wrappedFetcher.bind(null, fetcher), config);
}; };
export const useServerFlavor = () => { const useServerConfig = () => {
const { data: config, error } = useQueryImmutable( const { data: config, error } = useQueryImmutable(
{ query: serverConfigQuery }, { query: serverConfigQuery },
{ {
@@ -18,10 +18,20 @@ export const useServerFlavor = () => {
); );
if (error || !config) { if (error || !config) {
return null;
}
return config.serverConfig;
};
export const useServerFlavor = () => {
const config = useServerConfig();
if (!config) {
return 'local'; return 'local';
} }
return config.serverConfig.flavor; return config.flavor;
}; };
export const useSelfHosted = () => { export const useSelfHosted = () => {
@@ -29,3 +39,18 @@ export const useSelfHosted = () => {
return ['local', 'selfhosted'].includes(serverFlavor); return ['local', 'selfhosted'].includes(serverFlavor);
}; };
export const useServerBaseUrl = () => {
const config = useServerConfig();
if (!config) {
if (environment.isDesktop) {
// don't use window.location in electron
return null;
}
const { protocol, hostname, port } = window.location;
return `${protocol}//${hostname}${port ? `:${port}` : ''}`;
}
return config.baseUrl;
};
@@ -1,15 +0,0 @@
'use client';
import { useMemo } from 'react';
export function useShareLink(workspaceId: string): string {
return useMemo(() => {
if (environment.isServer) {
throw new Error('useShareLink is not available on server side');
}
if (environment.isDesktop) {
return '???';
} else {
return origin + '/share/' + workspaceId;
}
}, [workspaceId]);
}
@@ -2,7 +2,7 @@ import { type SubscriptionQuery, subscriptionQuery } from '@affine/graphql';
import { useQuery } from '@affine/workspace/affine/gql'; import { useQuery } from '@affine/workspace/affine/gql';
import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks'; import { useAsyncCallback } from '@toeverything/hooks/affine-async-hooks';
import { useSelfHosted } from './affine/use-server-flavor'; import { useSelfHosted } from './affine/use-server-config';
export type Subscription = NonNullable< export type Subscription = NonNullable<
NonNullable<SubscriptionQuery['currentUser']>['subscription'] NonNullable<SubscriptionQuery['currentUser']>['subscription']
@@ -655,6 +655,7 @@ query serverConfig {
serverConfig { serverConfig {
version version
flavor flavor
baseUrl
} }
}`, }`,
}; };
@@ -2,5 +2,6 @@ query serverConfig {
serverConfig { serverConfig {
version version
flavor flavor
baseUrl
} }
} }
+1
View File
@@ -632,6 +632,7 @@ export type ServerConfigQuery = {
__typename?: 'ServerConfigType'; __typename?: 'ServerConfigType';
version: string; version: string;
flavor: string; flavor: string;
baseUrl: string;
}; };
}; };