@@ -7,12 +7,7 @@ import { isPlainObject } from 'molstar/lib/mol-util/object';
7
7
import { sleep } from 'molstar/lib/mol-util/sleep' ;
8
8
import { BehaviorSubject } from 'rxjs' ;
9
9
import { PreemptiveQueue , PreemptiveQueueResult , combineUrl , distinct } from '../../helpers' ;
10
-
11
-
12
- const LOAD_BACKGROUND = false ; // TODO put to config+param
13
- const LOAD_CAMERA_ORIENTATION = true ; // TODO put to config+param
14
- const CAMERA_PRE_TRANSITION_MS = 100 ; // TODO put to config+param
15
- const CAMERA_TRANSITION_MS = 400 ; // TODO put to config+param
10
+ import { StateGalleryConfigValues , getStateGalleryConfig } from './config' ;
16
11
17
12
18
13
export interface StateGalleryData {
@@ -81,23 +76,26 @@ export class StateGalleryManager {
81
76
public readonly images : Image [ ] ;
82
77
public readonly requestedStateName = new BehaviorSubject < string | undefined > ( undefined ) ;
83
78
public readonly loadedStateName = new BehaviorSubject < string | undefined > ( undefined ) ;
79
+ /** True if at least one state has been loaded (this is to skip animation on the first load) */
84
80
private firstLoaded = false ;
85
81
86
82
private constructor (
87
83
public readonly plugin : PluginContext ,
88
- public readonly serverUrl : string ,
89
84
public readonly entryId : string ,
90
85
public readonly data : StateGalleryData | undefined ,
86
+ public readonly options : StateGalleryConfigValues ,
91
87
) {
92
- this . images = removeWithSuffixes ( listImages ( data , true ) , [ '_side' , '_top' ] ) ; // TODO allow suffixes by a parameter, sort by parameter
88
+ const allImages = listImages ( data , true ) ;
89
+ this . images = removeWithSuffixes ( allImages , [ '_side' , '_top' ] ) ; // removing images in different orientation than 'front'
93
90
}
94
91
95
- static async create ( plugin : PluginContext , serverUrl : string , entryId : string ) {
96
- const data = await getData ( plugin , serverUrl , entryId ) ;
92
+ static async create ( plugin : PluginContext , entryId : string , options ?: Partial < StateGalleryConfigValues > ) {
93
+ const fullOptions = { ...getStateGalleryConfig ( plugin ) , ...options } ;
94
+ const data = await getData ( plugin , fullOptions . ServerUrl , entryId ) ;
97
95
if ( data === undefined ) {
98
96
console . error ( `StateGalleryManager failed to get data for entry ${ entryId } ` ) ;
99
97
}
100
- return new this ( plugin , serverUrl , entryId , data ) ;
98
+ return new this ( plugin , entryId , data , fullOptions ) ;
101
99
}
102
100
103
101
private async _load ( filename : string ) : Promise < void > {
@@ -108,17 +106,18 @@ export class StateGalleryManager {
108
106
const incomingCamera = getCameraFromSnapshot ( snapshot ) ; // Camera position from the MOLJ file, which may be incorrectly zoomed if viewport width < height
109
107
const newCamera : Camera . Snapshot = { ...oldCamera , ...refocusCameraSnapshot ( this . plugin . canvas3d . camera , incomingCamera ) } ;
110
108
snapshot = modifySnapshot ( snapshot , {
111
- removeBackground : ! LOAD_BACKGROUND ,
109
+ removeCanvasProps : ! this . options . LoadCanvasProps ,
112
110
replaceCamera : {
113
- camera : ( LOAD_CAMERA_ORIENTATION && ! this . firstLoaded ) ? newCamera : oldCamera ,
111
+ camera : ( this . options . LoadCameraOrientation && ! this . firstLoaded ) ? newCamera : oldCamera ,
114
112
transitionDurationInMs : 0 ,
115
113
}
116
114
} ) ;
117
- const file = new File ( [ snapshot ] , `${ filename } .molj` ) ;
118
- await PluginCommands . State . Snapshots . OpenFile ( this . plugin , { file } ) ;
119
- // await this.plugin.managers.snapshot.setStateSnapshot(JSON.parse(data));
120
- await sleep ( this . firstLoaded ? CAMERA_PRE_TRANSITION_MS : 0 ) ; // it is necessary to sleep even for 0 ms here, to get animation
121
- await PluginCommands . Camera . Reset ( this . plugin , { snapshot : LOAD_CAMERA_ORIENTATION ? newCamera : undefined , durationMs : this . firstLoaded ? CAMERA_TRANSITION_MS : 0 } ) ;
115
+ await this . plugin . managers . snapshot . setStateSnapshot ( JSON . parse ( snapshot ) ) ;
116
+ await sleep ( this . firstLoaded ? this . options . CameraPreTransitionMs : 0 ) ; // it is necessary to sleep even for 0 ms here, to get animation
117
+ await PluginCommands . Camera . Reset ( this . plugin , {
118
+ snapshot : this . options . LoadCameraOrientation ? newCamera : undefined ,
119
+ durationMs : this . firstLoaded ? this . options . CameraTransitionMs : 0 ,
120
+ } ) ;
122
121
123
122
this . firstLoaded = true ;
124
123
}
@@ -135,7 +134,7 @@ export class StateGalleryManager {
135
134
136
135
private readonly cache : { [ filename : string ] : string } = { } ;
137
136
private async fetchSnapshot ( filename : string ) : Promise < string > {
138
- const url = combineUrl ( this . serverUrl , `${ filename } .molj` ) ;
137
+ const url = combineUrl ( this . options . ServerUrl , `${ filename } .molj` ) ;
139
138
const data = await this . plugin . runTask ( this . plugin . fetch ( { url, type : 'string' } ) ) ;
140
139
return data ;
141
140
}
@@ -145,7 +144,7 @@ export class StateGalleryManager {
145
144
}
146
145
147
146
148
- async function getData ( plugin : PluginContext , serverUrl : string , entryId : string ) {
147
+ async function getData ( plugin : PluginContext , serverUrl : string , entryId : string ) : Promise < StateGalleryData | undefined > {
149
148
const url = combineUrl ( serverUrl , entryId + '.json' ) ;
150
149
try {
151
150
const text = await plugin . runTask ( plugin . fetch ( url ) ) ;
@@ -161,7 +160,6 @@ function listImages(data: StateGalleryData | undefined, byCategory: boolean = fa
161
160
const out : Image [ ] = [ ] ;
162
161
163
162
// Entry
164
- // out.push(...data?.entry?.all?.image ?? []);
165
163
for ( const img of data ?. entry ?. all ?. image ?? [ ] ) {
166
164
const title = img . filename . includes ( '_chemically_distinct_molecules' )
167
165
? 'Deposited model (color by entity)'
@@ -171,19 +169,16 @@ function listImages(data: StateGalleryData | undefined, byCategory: boolean = fa
171
169
out . push ( { ...img , category : 'Entry' , simple_title : title } ) ;
172
170
}
173
171
// Validation
174
- // out.push(...data?.validation?.geometry?.deposited?.image ?? []);
175
172
for ( const img of data ?. validation ?. geometry ?. deposited ?. image ?? [ ] ) {
176
173
out . push ( { ...img , category : 'Entry' , simple_title : 'Geometry validation' } ) ;
177
174
}
178
175
// Bfactor
179
- // out.push(...data?.entry?.bfactor?.image ?? []);
180
176
for ( const img of data ?. entry ?. bfactor ?. image ?? [ ] ) {
181
177
out . push ( { ...img , category : 'Entry' , simple_title : 'B-factor' } ) ;
182
178
}
183
179
// Assembly
184
180
const assemblies = data ?. assembly ;
185
181
for ( const ass in assemblies ) {
186
- // out.push(...assemblies[ass].image);
187
182
for ( const img of assemblies [ ass ] . image ?? [ ] ) {
188
183
const title = img . filename . includes ( '_chemically_distinct_molecules' )
189
184
? `Assembly ${ ass } (color by entity)`
@@ -196,23 +191,20 @@ function listImages(data: StateGalleryData | undefined, byCategory: boolean = fa
196
191
// Entity
197
192
const entities = data ?. entity ;
198
193
for ( const entity in entities ) {
199
- // out.push(...entities[entity].image);
200
194
for ( const img of entities [ entity ] . image ?? [ ] ) {
201
195
out . push ( { ...img , category : 'Entities' , simple_title : `Entity ${ entity } ` } ) ;
202
196
}
203
197
}
204
198
// Ligand
205
199
const ligands = data ?. entry ?. ligands ;
206
200
for ( const ligand in ligands ) {
207
- // out.push(...ligands[ligand].image);
208
201
for ( const img of ligands [ ligand ] . image ?? [ ] ) {
209
202
out . push ( { ...img , category : 'Ligands' , simple_title : `Ligand environment for ${ ligand } ` } ) ;
210
203
}
211
204
}
212
205
// Modres
213
206
const modres = data ?. entry ?. mod_res ;
214
207
for ( const res in modres ) {
215
- // out.push(...modres[res].image);
216
208
for ( const img of modres [ res ] . image ?? [ ] ) {
217
209
out . push ( { ...img , category : 'Modified residues' , simple_title : `Modified residue ${ res } ` } ) ;
218
210
}
@@ -223,9 +215,8 @@ function listImages(data: StateGalleryData | undefined, byCategory: boolean = fa
223
215
for ( const db in dbs ) {
224
216
const domains = dbs [ db ] ;
225
217
for ( const domain in domains ) {
226
- // out.push(...domains[domain].image);
227
218
for ( const img of domains [ domain ] . image ?? [ ] ) {
228
- out . push ( { ...img , category : 'Domains' , simple_title : `${ db } ${ domain } in entity ${ entity } ` } ) ;
219
+ out . push ( { ...img , category : 'Domains' , simple_title : `${ db } ${ domain } ( entity ${ entity } ) ` } ) ;
229
220
}
230
221
}
231
222
}
@@ -257,12 +248,12 @@ function removeWithSuffixes(images: Image[], suffixes: string[]): Image[] {
257
248
return images . filter ( img => ! suffixes . some ( suffix => img . filename . endsWith ( suffix ) ) ) ;
258
249
}
259
250
260
- function modifySnapshot ( snapshot : string , options : { removeBackground ?: boolean , replaceCamera ?: { camera : Camera . Snapshot , transitionDurationInMs : number } } ) {
251
+ function modifySnapshot ( snapshot : string , options : { removeCanvasProps ?: boolean , replaceCamera ?: { camera : Camera . Snapshot , transitionDurationInMs : number } } ) {
261
252
const json = JSON . parse ( snapshot ) as PluginStateSnapshotManager . StateSnapshot ;
262
253
for ( const entry of json . entries ?? [ ] ) {
263
254
if ( entry . snapshot ) {
264
- if ( options . removeBackground ) {
265
- delete entry . snapshot . canvas3d ;
255
+ if ( options . removeCanvasProps && entry . snapshot . canvas3d ) {
256
+ delete entry . snapshot . canvas3d . props ;
266
257
}
267
258
if ( options . replaceCamera ) {
268
259
const { camera, transitionDurationInMs } = options . replaceCamera ;
0 commit comments