55 TFolder ,
66 TFile ,
77 ViewState ,
8- MarkdownView ,
9- Menu
108} from 'obsidian' ;
119
1210import {
@@ -23,16 +21,20 @@ import {
2321 DbfAPIInterface
2422} from 'typings/api' ;
2523
26- import {
27- DBFolderAPI
28- } from 'api/plugin-api' ;
2924import { DatabaseSettings , LocalSettings } from 'cdm/SettingsModel' ;
3025
3126import StateManager from 'StateManager' ;
3227import { around } from 'monkey-around' ;
3328import { LOGGER } from 'services/Logger' ;
3429import { DatabaseCore , DatabaseFrontmatterOptions , DEFAULT_SETTINGS , YAML_INDENT } from 'helpers/Constants' ;
3530import { PreviewDatabaseModeService } from 'services/MarkdownPostProcessorService' ;
31+ import { unmountComponentAtNode } from 'react-dom' ;
32+
33+ interface WindowRegistry {
34+ viewMap : Map < string , DatabaseView > ;
35+ viewStateReceivers : Array < ( views : DatabaseView [ ] ) => void > ;
36+ appRoot : HTMLElement ;
37+ }
3638
3739export default class DBFolderPlugin extends Plugin {
3840 /** Plugin-wide default settings. */
@@ -54,9 +56,23 @@ export default class DBFolderPlugin extends Plugin {
5456
5557 stateManagers : Map < TFile , StateManager > = new Map ( ) ;
5658
59+ windowRegistry : Map < Window , WindowRegistry > = new Map ( ) ;
60+
5761 async onload ( ) : Promise < void > {
5862 await this . load_settings ( ) ;
5963
64+ this . registerEvent (
65+ app . workspace . on ( 'window-open' , ( _ : any , win : Window ) => {
66+ this . mount ( win ) ;
67+ } )
68+ ) ;
69+
70+ this . registerEvent (
71+ app . workspace . on ( 'window-close' , ( _ : any , win : Window ) => {
72+ this . unmount ( win ) ;
73+ } )
74+ ) ;
75+
6076 // This adds a settings tab so the user can configure various aspects of the plugin
6177 this . addSettingTab ( new DBFolderSettingTab ( this , {
6278 onSettingsChange : async ( newSettings ) => {
@@ -75,13 +91,24 @@ export default class DBFolderPlugin extends Plugin {
7591 this . registerEvents ( ) ;
7692 this . registerMonkeyPatches ( ) ;
7793 this . addMarkdownPostProcessor ( ) ;
78- this . api = new DBFolderAPI ( this . app , this . settings ) ;
94+ // Mount an empty component to start; views will be added as we go
95+ this . mount ( window ) ;
96+
97+ ( app . workspace as any ) . floatingSplit ?. children ?. forEach ( ( c : any ) => {
98+ this . mount ( c . win ) ;
99+ } ) ;
79100 }
80101
81102 async onunload ( ) {
103+ this . windowRegistry . forEach ( ( reg , win ) => {
104+ reg . viewStateReceivers . forEach ( ( fn ) => fn ( [ ] ) ) ;
105+ this . unmount ( win ) ;
106+ } ) ;
82107 LOGGER . info ( 'Unloading DBFolder plugin' ) ;
83108 // Unmount views first
84109 this . stateManagers . clear ( ) ;
110+ this . unmount ( window ) ;
111+ this . windowRegistry . clear ( ) ;
85112 }
86113
87114 /** Update plugin settings. */
@@ -123,6 +150,13 @@ export default class DBFolderPlugin extends Plugin {
123150 viewStateReceivers : Array < ( views : DatabaseView [ ] ) => void > = [ ] ;
124151
125152 addView ( view : DatabaseView , data : string , shouldParseData : boolean ) {
153+ const win = view . getWindow ( ) ;
154+ const reg = this . windowRegistry . get ( win ) ;
155+
156+ if ( ! reg ) {
157+ return ;
158+ }
159+
126160 if ( ! this . viewMap . has ( view . id ) ) {
127161 this . viewMap . set ( view . id , view ) ;
128162 }
@@ -142,25 +176,54 @@ export default class DBFolderPlugin extends Plugin {
142176 )
143177 ) ;
144178 }
145-
146- this . viewStateReceivers . forEach ( ( fn ) => fn ( this . getDatabaseViews ( ) ) ) ;
179+ reg . viewStateReceivers . forEach ( ( fn ) => fn ( this . getDatabaseViews ( win ) ) ) ;
147180 }
148181
149182 getStateManager ( file : TFile ) {
150183 return this . stateManagers . get ( file ) ;
151184 }
152185
153186 removeView ( view : DatabaseView ) {
187+ const entry = Array . from ( this . windowRegistry . entries ( ) ) . find ( ( [ , reg ] ) => {
188+ return reg . viewMap . has ( view . id ) ;
189+ } , [ ] ) ;
190+
191+ if ( ! entry ) {
192+ return ;
193+ }
194+
195+ const [ win , reg ] = entry ;
154196 const file = view . file ;
155197
156- if ( this . viewMap . has ( view . id ) ) {
157- this . viewMap . delete ( view . id ) ;
198+ if ( reg . viewMap . has ( view . id ) ) {
199+ reg . viewMap . delete ( view . id ) ;
158200 }
159201
160202 if ( this . stateManagers . has ( file ) ) {
161203 this . stateManagers . get ( file ) . unregisterView ( view ) ;
162- this . viewStateReceivers . forEach ( ( fn : any ) => fn ( this . getDatabaseViews ( ) ) ) ;
204+ reg . viewStateReceivers . forEach ( ( fn ) => fn ( this . getDatabaseViews ( win ) ) ) ;
205+ }
206+ }
207+
208+ unmount ( win : Window ) {
209+ if ( ! this . windowRegistry . has ( win ) ) {
210+ return ;
211+ }
212+
213+ const reg = this . windowRegistry . get ( win ) ;
214+
215+ for ( const view of reg . viewMap . values ( ) ) {
216+ view . destroy ( ) ;
163217 }
218+
219+ unmountComponentAtNode ( reg . appRoot ) ;
220+
221+ reg . appRoot . remove ( ) ;
222+ reg . viewMap . clear ( ) ;
223+ reg . viewStateReceivers . length = 0 ;
224+ reg . appRoot = null ;
225+
226+ this . windowRegistry . delete ( win ) ;
164227 }
165228
166229 async setMarkdownView ( leaf : WorkspaceLeaf , focus = true ) {
@@ -174,14 +237,36 @@ export default class DBFolderPlugin extends Plugin {
174237 ) ;
175238 }
176239
177- getDatabaseViews ( ) {
178- return Array . from ( this . viewMap . values ( ) ) ;
240+ getDatabaseViews ( win : Window ) {
241+ const reg = this . windowRegistry . get ( win ) ;
242+
243+ if ( reg ) {
244+ return Array . from ( reg . viewMap . values ( ) ) ;
245+ }
246+
247+ return [ ] ;
179248 }
180249
181250 getDatabaseView ( id : string ) {
182251 return this . viewMap . get ( id ) ;
183252 }
184253
254+ mount ( win : Window ) {
255+ if ( this . windowRegistry . has ( win ) ) {
256+ return ;
257+ }
258+
259+ const el = win . document . body . createDiv ( ) ;
260+
261+ this . windowRegistry . set ( win , {
262+ viewMap : new Map ( ) ,
263+ viewStateReceivers : [ ] ,
264+ appRoot : el ,
265+ } ) ;
266+
267+ //Preact.render(createApp(win, this), el);
268+ }
269+
185270 async newDatabase ( folder ?: TFolder ) {
186271 const targetFolder = folder
187272 ? folder
@@ -311,42 +396,42 @@ export default class DBFolderPlugin extends Plugin {
311396 } )
312397 ) ;
313398
314- // Add a menu item to go back to database view
315- this . register (
316- around ( MarkdownView . prototype , {
317- onPaneMenu ( next ) {
318- return function ( menu : Menu ) {
319- const file = this . file ;
320- const cache = file
321- ? self . app . metadataCache . getFileCache ( file )
322- : null ;
323-
324- if (
325- ! file ||
326- ! cache ?. frontmatter ||
327- ! cache . frontmatter [ DatabaseCore . FRONTMATTER_KEY ]
328- ) {
329- return next . call ( this , menu ) ;
330- }
331-
332- menu
333- . addItem ( ( item ) => {
334- item
335- . setTitle ( 'Open as database folder' )
336- . setIcon ( databaseIcon )
337- . onClick ( ( ) => {
338- self . databaseFileModes [ this . leaf . id || file . path ] =
339- DatabaseCore . FRONTMATTER_KEY ;
340- self . setDatabaseView ( this . leaf ) ;
341- } ) ;
342- } )
343- . addSeparator ( ) ;
344-
345- next . call ( this , menu ) ;
346- } ;
347- } ,
348- } )
349- ) ;
399+ // // Add a menu item to go back to database view
400+ // this.register(
401+ // around(MarkdownView.prototype, {
402+ // onPaneMenu(next) {
403+ // return function (menu: Menu) {
404+ // const file = this.file;
405+ // const cache = file
406+ // ? self.app.metadataCache.getFileCache(file)
407+ // : null;
408+
409+ // if (
410+ // !file ||
411+ // !cache?.frontmatter ||
412+ // !cache.frontmatter[DatabaseCore.FRONTMATTER_KEY]
413+ // ) {
414+ // return next.call(this, menu);
415+ // }
416+
417+ // menu
418+ // .addItem((item) => {
419+ // item
420+ // .setTitle('Open as database folder')
421+ // .setIcon(databaseIcon)
422+ // .onClick(() => {
423+ // self.databaseFileModes[this.leaf.id || file.path] =
424+ // DatabaseCore.FRONTMATTER_KEY;
425+ // self.setDatabaseView(this.leaf);
426+ // });
427+ // })
428+ // .addSeparator();
429+
430+ // next.call(this, menu);
431+ // };
432+ // },
433+ // })
434+ // );
350435 }
351436
352437 // private debuggingMobile(plugin:Plugin){
0 commit comments