@@ -11,23 +11,24 @@ import { EVENT_REFRESH_TABLES } from "src/shared/events";
11
11
import { TableState } from "src/shared/types/types" ;
12
12
import _ from "lodash" ;
13
13
import { getEmbeddedTableLinkEls } from "./utils" ;
14
+ import { v4 as uuidv4 } from "uuid" ;
14
15
15
16
class NLTEmbeddedPlugin implements PluginValue {
16
- activeTables : {
17
+ private tableApps : {
18
+ id : string ;
19
+ parentEl : HTMLElement ;
17
20
leaf : WorkspaceLeaf ;
18
- containerEl : HTMLElement ;
19
21
root : Root ;
20
22
file : TFile ;
21
23
} [ ] ;
22
24
23
25
constructor ( ) {
24
- this . activeTables = [ ] ;
26
+ this . tableApps = [ ] ;
25
27
this . setupEventListeners ( ) ;
26
28
}
27
29
28
30
//This is ran on any editor change
29
31
async update ( ) {
30
- console . log ( "NLTEmbeddedPlugin update" ) ;
31
32
const activeView = app . workspace . getActiveViewOfType ( MarkdownView ) ;
32
33
if ( ! activeView ) return ;
33
34
@@ -37,28 +38,39 @@ class NLTEmbeddedPlugin implements PluginValue {
37
38
38
39
for ( let i = 0 ; i < embeddedTableLinkEls . length ; i ++ ) {
39
40
const linkEl = embeddedTableLinkEls [ i ] ;
40
- const child = linkEl . children [ 0 ] ;
41
41
42
- //If the child is not a title, we have already mounted an app
43
- if ( ! child . className . includes ( "file-embed-title" ) ) return ;
42
+ if ( linkEl . children . length === 1 ) {
43
+ const child = linkEl . children [ 0 ] ;
44
+ if ( child . classList . contains ( "NLT__embedded-container" ) )
45
+ continue ;
46
+ }
44
47
45
- //Remove the child, we don't need it
46
- linkEl . removeChild ( child ) ;
48
+ //Remove any children
49
+ for ( let i = 0 ; i < linkEl . children . length ; i ++ ) {
50
+ linkEl . removeChild ( linkEl . children [ i ] ) ;
51
+ }
47
52
48
53
//Get the table file that matches the src
49
54
const src = linkEl . getAttribute ( "src" ) ! ;
50
- const tableFile = app . vault
55
+
56
+ let tableFile = app . vault
51
57
. getFiles ( )
52
- . find ( ( file ) => file . name === src ) ;
58
+ . find ( ( file ) => file . path === src ) ;
59
+ if ( tableFile === undefined ) {
60
+ tableFile = app . vault
61
+ . getFiles ( )
62
+ . find ( ( file ) => file . name === src ) ;
63
+ }
53
64
54
- if ( ! tableFile ) return ;
65
+ if ( ! tableFile ) continue ;
55
66
56
67
linkEl . style . height = "340px" ;
57
68
linkEl . style . backgroundColor = "var(--color-primary)" ;
58
69
linkEl . style . cursor = "unset" ;
59
70
linkEl . style . padding = "10px 0px" ;
60
71
61
72
const containerEl = linkEl . createDiv ( ) ;
73
+ containerEl . className = "NLT__embedded-container" ;
62
74
containerEl . style . height = "100%" ;
63
75
containerEl . style . width = "100%" ;
64
76
@@ -82,75 +94,79 @@ class NLTEmbeddedPlugin implements PluginValue {
82
94
const data = await app . vault . read ( tableFile ) ;
83
95
const tableState = deserializeTableState ( data ) ;
84
96
85
- console . log ( "rendering table" ) ;
97
+ const appId = uuidv4 ( ) ;
86
98
const root = createRoot ( containerEl ) ;
87
- this . renderApp ( activeView . leaf , tableFile , root , tableState ) ;
99
+ this . renderApp ( appId , activeView . leaf , tableFile , root , tableState ) ;
88
100
89
- this . activeTables . push ( {
101
+ this . tableApps . push ( {
102
+ id : appId ,
90
103
leaf : activeView . leaf ,
91
- containerEl,
104
+ parentEl : containerEl ,
92
105
root,
93
106
file : tableFile ,
94
107
} ) ;
95
108
}
96
109
}
97
110
111
+ private async handleSave (
112
+ tableFile : TFile ,
113
+ appId : string ,
114
+ state : TableState
115
+ ) {
116
+ //Save the new state
117
+ const serialized = serializeTableState ( state ) ;
118
+ await app . vault . modify ( tableFile , serialized ) ;
119
+
120
+ //Tell all other views to refresh
121
+ app . workspace . trigger (
122
+ EVENT_REFRESH_TABLES ,
123
+ tableFile . path ,
124
+ appId ,
125
+ state
126
+ ) ;
127
+ }
128
+
98
129
private renderApp (
130
+ id : string ,
99
131
leaf : WorkspaceLeaf ,
100
132
tableFile : TFile ,
101
133
root : Root ,
102
134
tableState : TableState
103
135
) {
104
- async function handleSave ( value : TableState ) {
105
- console . log ( "NLTEmbeddedPlugin handleSave" ) ;
106
- //Save the new state
107
- const serialized = serializeTableState ( value ) ;
108
- await app . vault . modify ( tableFile , serialized ) ;
109
-
110
- //Tell all other views to refresh
111
- app . workspace . trigger (
112
- EVENT_REFRESH_TABLES ,
113
- leaf ,
114
- tableFile . path ,
115
- value
116
- ) ;
117
- }
118
-
119
136
//Throttle the save function so we don't save too often
120
- //This is the same time as the `debounceFunction`
121
- const throttleHandleSave = _ . throttle ( handleSave , 2000 ) ;
137
+ const throttleHandleSave = _ . throttle ( this . handleSave , 2000 ) ;
122
138
123
139
root . render (
124
140
< NotionLikeTable
125
- fileName = { tableFile . name }
141
+ appId = { id }
142
+ filePath = { tableFile . path }
126
143
leaf = { leaf }
127
144
store = { store }
128
145
tableState = { tableState }
129
- onSaveState = { throttleHandleSave }
146
+ onSaveState = { ( appId , state ) =>
147
+ throttleHandleSave ( tableFile , appId , state )
148
+ }
130
149
/>
131
150
) ;
132
151
}
133
152
134
153
private handleRefreshEvent = (
135
- leaf : WorkspaceLeaf ,
136
154
filePath : string ,
137
- tableState : TableState
155
+ sourceAppId : string ,
156
+ state : TableState
138
157
) => {
139
- console . log ( "NLTEmbeddedPlugin handleRefreshEvent" ) ;
140
-
141
- const table = this . activeTables . find (
142
- ( table ) => table . file . path === filePath
158
+ const apps = this . tableApps . filter (
159
+ ( app ) => app . id !== sourceAppId && app . file . path === filePath
143
160
) ;
144
- if ( ! table ) return ;
145
- const { leaf : tableLeaf } = table ;
146
- if ( leaf === tableLeaf ) return ;
147
-
148
- const { containerEl, root } = table ;
149
-
150
- console . log ( "handling refresh event" ) ;
151
- root . unmount ( ) ;
152
- table . root = createRoot ( containerEl ) ;
153
- this . renderApp ( tableLeaf , table . file , table . root , tableState ) ;
161
+ apps . forEach ( ( app ) => {
162
+ const { id, parentEl, leaf, file } = app ;
163
+
164
+ setTimeout ( ( ) => {
165
+ app . root . unmount ( ) ;
166
+ app . root = createRoot ( parentEl ) ;
167
+ this . renderApp ( id , leaf , file , app . root , state ) ;
168
+ } , 0 ) ;
169
+ } ) ;
154
170
} ;
155
171
156
172
private setupEventListeners ( ) {
@@ -159,7 +175,7 @@ class NLTEmbeddedPlugin implements PluginValue {
159
175
}
160
176
161
177
destroy ( ) {
162
- this . activeTables . forEach ( ( table ) => table . root . unmount ( ) ) ;
178
+ this . tableApps . forEach ( ( app ) => app . root . unmount ( ) ) ;
163
179
app . workspace . off ( EVENT_REFRESH_TABLES , this . handleRefreshEvent ) ;
164
180
}
165
181
}
0 commit comments