1
1
import { Button } from '@affine/component' ;
2
+ import { AuthHeader } from '@affine/component/auth-components' ;
2
3
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks' ;
3
- import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper' ;
4
4
import { useWorkspaceName } from '@affine/core/components/hooks/use-workspace-info' ;
5
5
import { WorkspaceSelector } from '@affine/core/components/workspace-selector' ;
6
- import { AuthService } from '@affine/core/modules/cloud' ;
6
+ import { AuthService , ServerService } from '@affine/core/modules/cloud' ;
7
7
import {
8
8
type ClipperInput ,
9
9
ImportClipperService ,
@@ -16,7 +16,7 @@ import { useI18n } from '@affine/i18n';
16
16
import { AllDocsIcon } from '@blocksuite/icons/rc' ;
17
17
import { LiveData , useLiveData , useService } from '@toeverything/infra' ;
18
18
import { cssVar } from '@toeverything/theme' ;
19
- import { useCallback , useEffect , useState } from 'react' ;
19
+ import { useCallback , useEffect , useRef , useState } from 'react' ;
20
20
21
21
import * as styles from './style.css' ;
22
22
@@ -36,24 +36,29 @@ export const Component = () => {
36
36
const t = useI18n ( ) ;
37
37
const session = useService ( AuthService ) . session ;
38
38
const notLogin = useLiveData ( session . status$ ) === 'unauthenticated' ;
39
- const isSessionRevalidating = useLiveData ( session . isRevalidating$ ) ;
40
39
41
40
const [ importing , setImporting ] = useState ( false ) ;
42
41
const [ importingError , setImportingError ] = useState < any > ( null ) ;
43
42
const clipperInput = useLiveData ( clipperInput$ ) ;
44
43
const [ clipperInputSnapshot , setClipperInputSnapshot ] =
45
44
useState < ClipperInput | null > ( null ) ;
46
45
const isMissingInput = ! clipperInputSnapshot ;
46
+ const workspaceStrategy = clipperInputSnapshot ?. workspace ?? 'select-by-user' ;
47
+ const serverService = useService ( ServerService ) ;
47
48
const workspacesService = useService ( WorkspacesService ) ;
49
+ const serverConfig = useLiveData ( serverService . server . config$ ) ;
48
50
const workspaces = useLiveData ( workspacesService . list . workspaces$ ) ;
49
51
const [ rawSelectedWorkspace , setSelectedWorkspace ] =
50
52
useState < WorkspaceMetadata | null > ( null ) ;
53
+ const [ lastOpenedWorkspaceId ] = useState ( ( ) =>
54
+ localStorage . getItem ( 'last_workspace_id' )
55
+ ) ;
51
56
const selectedWorkspace =
52
57
rawSelectedWorkspace ??
58
+ workspaces . find ( w => w . id === lastOpenedWorkspaceId ) ??
53
59
workspaces . find ( w => w . flavour !== 'local' ) ??
54
60
workspaces . at ( 0 ) ;
55
61
const selectedWorkspaceName = useWorkspaceName ( selectedWorkspace ) ;
56
- const { jumpToSignIn } = useNavigateHelper ( ) ;
57
62
58
63
const noWorkspace = workspaces . length === 0 ;
59
64
@@ -65,12 +70,6 @@ export const Component = () => {
65
70
session . revalidate ( ) ;
66
71
} , [ session ] ) ;
67
72
68
- useEffect ( ( ) => {
69
- if ( ! isSessionRevalidating && notLogin ) {
70
- jumpToSignIn ( '/clipper/import' ) ;
71
- }
72
- } , [ isSessionRevalidating , jumpToSignIn , notLogin ] ) ;
73
-
74
73
useEffect ( ( ) => {
75
74
if ( ! clipperInputSnapshot ) {
76
75
setClipperInputSnapshot ( clipperInput ) ;
@@ -99,6 +98,9 @@ export const Component = () => {
99
98
selectedWorkspace ,
100
99
clipperInputSnapshot
101
100
) ;
101
+ window . postMessage ( {
102
+ type : 'affine-clipper:import:success' ,
103
+ } ) ;
102
104
window . close ( ) ;
103
105
} catch ( err ) {
104
106
setImportingError ( err ) ;
@@ -119,6 +121,9 @@ export const Component = () => {
119
121
'Workspace' ,
120
122
clipperInputSnapshot
121
123
) ;
124
+ window . postMessage ( {
125
+ type : 'affine-clipper:import:success' ,
126
+ } ) ;
122
127
window . close ( ) ;
123
128
} catch ( err ) {
124
129
setImportingError ( err ) ;
@@ -127,8 +132,70 @@ export const Component = () => {
127
132
}
128
133
} , [ clipperInputSnapshot , importClipperService ] ) ;
129
134
135
+ const handleClickSignIn = useCallback ( ( ) => {
136
+ window . open (
137
+ `/sign-in?redirect_uri=${ encodeURIComponent ( 'CLOSE_POPUP' ) } ` ,
138
+ '_blank' ,
139
+ 'popup'
140
+ ) ;
141
+ } , [ ] ) ;
142
+
143
+ const autoImportTriggered = useRef ( false ) ;
144
+
145
+ useEffect ( ( ) => {
146
+ if ( isMissingInput ) {
147
+ return ;
148
+ }
149
+ // use ref to avoid multiple auto import
150
+ // and make sure the following code only runs once
151
+ if ( autoImportTriggered . current ) {
152
+ return ;
153
+ }
154
+ autoImportTriggered . current = true ;
155
+
156
+ // if not login, we don't auto import
157
+ if ( notLogin ) {
158
+ return ;
159
+ }
160
+
161
+ // if the workspace strategy is last-open-workspace, we automatically click the import button
162
+ if (
163
+ workspaceStrategy === 'last-open-workspace' &&
164
+ selectedWorkspace ?. id === lastOpenedWorkspaceId
165
+ ) {
166
+ handleImportToSelectedWorkspace ( ) ;
167
+ }
168
+ } , [
169
+ workspaceStrategy ,
170
+ selectedWorkspace ,
171
+ handleImportToSelectedWorkspace ,
172
+ lastOpenedWorkspaceId ,
173
+ isMissingInput ,
174
+ notLogin ,
175
+ ] ) ;
176
+
130
177
const disabled = isMissingInput || importing || notLogin ;
131
178
179
+ if ( notLogin ) {
180
+ // not login
181
+ return (
182
+ < div className = { styles . container } >
183
+ < AuthHeader
184
+ className = { styles . authHeader }
185
+ title = { t [ 'com.affine.auth.sign.in' ] ( ) }
186
+ subTitle = { serverConfig . serverName }
187
+ />
188
+ < Button
189
+ className = { styles . mainButton }
190
+ variant = "primary"
191
+ onClick = { handleClickSignIn }
192
+ >
193
+ { t [ 'com.affine.auth.sign.in' ] ( ) }
194
+ </ Button >
195
+ </ div >
196
+ ) ;
197
+ }
198
+
132
199
return (
133
200
< div className = { styles . container } >
134
201
< AllDocsIcon className = { styles . mainIcon } />
0 commit comments