@@ -17,7 +17,6 @@ import React from 'react';
17
17
import { _t } from '../../../languageHandler' ;
18
18
import Widgets from '../../../utils/widgets' ;
19
19
import AppTile from '../elements/AppTile' ;
20
- import ContextualMenu from '../../structures/ContextualMenu' ;
21
20
import MatrixClientPeg from '../../../MatrixClientPeg' ;
22
21
import Modal from '../../../Modal' ;
23
22
import sdk from '../../../index' ;
@@ -36,6 +35,7 @@ export default class Stickerpicker extends React.Component {
36
35
this . _launchManageIntegrations = this . _launchManageIntegrations . bind ( this ) ;
37
36
this . _removeStickerpickerWidgets = this . _removeStickerpickerWidgets . bind ( this ) ;
38
37
this . _onWidgetAction = this . _onWidgetAction . bind ( this ) ;
38
+ this . _onResize = this . _onResize . bind ( this ) ;
39
39
this . _onFinished = this . _onFinished . bind ( this ) ;
40
40
41
41
this . popoverWidth = 300 ;
@@ -44,13 +44,17 @@ export default class Stickerpicker extends React.Component {
44
44
this . state = {
45
45
showStickers : false ,
46
46
imError : null ,
47
+ stickerpickerX : null ,
48
+ stickerpickerY : null ,
49
+ stickerpickerWidget : null ,
50
+ widgetId : null ,
47
51
} ;
48
52
}
49
53
50
54
_removeStickerpickerWidgets ( ) {
51
55
console . warn ( 'Removing Stickerpicker widgets' ) ;
52
- if ( this . widgetId ) {
53
- this . scalarClient . disableWidgetAssets ( widgetType , this . widgetId ) . then ( ( ) => {
56
+ if ( this . state . widgetId ) {
57
+ this . scalarClient . disableWidgetAssets ( widgetType , this . state . widgetId ) . then ( ( ) => {
54
58
console . warn ( 'Assets disabled' ) ;
55
59
} ) . catch ( ( err ) => {
56
60
console . error ( 'Failed to disable assets' ) ;
@@ -59,8 +63,7 @@ export default class Stickerpicker extends React.Component {
59
63
console . warn ( 'No widget ID specified, not disabling assets' ) ;
60
64
}
61
65
62
- // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet
63
- setTimeout ( ( ) => this . stickersMenu . close ( ) ) ;
66
+ this . setState ( { showStickers : false } ) ;
64
67
Widgets . removeStickerpickerWidgets ( ) . then ( ( ) => {
65
68
this . forceUpdate ( ) ;
66
69
} ) . catch ( ( e ) => {
@@ -69,6 +72,9 @@ export default class Stickerpicker extends React.Component {
69
72
}
70
73
71
74
componentDidMount ( ) {
75
+ // Close the sticker picker when the window resizes
76
+ window . addEventListener ( 'resize' , this . _onResize ) ;
77
+
72
78
this . scalarClient = null ;
73
79
if ( SdkConfig . get ( ) . integrations_ui_url && SdkConfig . get ( ) . integrations_rest_url ) {
74
80
this . scalarClient = new ScalarAuthClient ( ) ;
@@ -82,9 +88,15 @@ export default class Stickerpicker extends React.Component {
82
88
if ( ! this . state . imError ) {
83
89
this . dispatcherRef = dis . register ( this . _onWidgetAction ) ;
84
90
}
91
+ const stickerpickerWidget = Widgets . getStickerpickerWidgets ( ) [ 0 ] ;
92
+ this . setState ( {
93
+ stickerpickerWidget,
94
+ widgetId : stickerpickerWidget ? stickerpickerWidget . id : null ,
95
+ } ) ;
85
96
}
86
97
87
98
componentWillUnmount ( ) {
99
+ window . removeEventListener ( 'resize' , this . _onResize ) ;
88
100
if ( this . dispatcherRef ) {
89
101
dis . unregister ( this . dispatcherRef ) ;
90
102
}
@@ -102,9 +114,7 @@ export default class Stickerpicker extends React.Component {
102
114
if ( payload . action === "user_widget_updated" ) {
103
115
this . forceUpdate ( ) ;
104
116
} else if ( payload . action === "stickerpicker_close" ) {
105
- // Wrap this in a timeout in order to avoid the DOM node from being
106
- // pulled from under its feet
107
- setTimeout ( ( ) => this . stickersMenu . close ( ) ) ;
117
+ this . setState ( { showStickers : false } ) ;
108
118
}
109
119
}
110
120
@@ -137,14 +147,13 @@ export default class Stickerpicker extends React.Component {
137
147
// TODO - Add support for Stickerpickers from multiple app stores.
138
148
// Render content from multiple stickerpack sources, each within their
139
149
// own iframe, within the stickerpicker UI element.
140
- const stickerpickerWidget = Widgets . getStickerpickerWidgets ( ) [ 0 ] ;
150
+ const stickerpickerWidget = this . state . stickerpickerWidget ;
141
151
let stickersContent ;
142
152
143
153
// Load stickerpack content
144
154
if ( stickerpickerWidget && stickerpickerWidget . content && stickerpickerWidget . content . url ) {
145
155
// Set default name
146
156
stickerpickerWidget . content . name = stickerpickerWidget . name || _t ( "Stickerpack" ) ;
147
- this . widgetId = stickerpickerWidget . id ;
148
157
149
158
stickersContent = (
150
159
< div className = 'mx_Stickers_content_container' >
@@ -186,12 +195,7 @@ export default class Stickerpicker extends React.Component {
186
195
// Default content to show if stickerpicker widget not added
187
196
console . warn ( "No available sticker picker widgets" ) ;
188
197
stickersContent = this . _defaultStickerpickerContent ( ) ;
189
- this . widgetId = null ;
190
- this . forceUpdate ( ) ;
191
198
}
192
- this . setState ( {
193
- showStickers : false ,
194
- } ) ;
195
199
return stickersContent ;
196
200
}
197
201
@@ -201,37 +205,32 @@ export default class Stickerpicker extends React.Component {
201
205
* @param {Event } e Event that triggered the function
202
206
*/
203
207
_onShowStickersClick ( e ) {
204
- const GenericElementContextMenu = sdk . getComponent ( 'context_menus.GenericElementContextMenu' ) ;
205
208
const buttonRect = e . target . getBoundingClientRect ( ) ;
206
209
207
210
// The window X and Y offsets are to adjust position when zoomed in to page
208
211
const x = buttonRect . right + window . pageXOffset - 42 ;
209
212
const y = ( buttonRect . top + ( buttonRect . height / 2 ) + window . pageYOffset ) - 19 ;
210
- // const self = this;
211
- this . stickersMenu = ContextualMenu . createMenu ( GenericElementContextMenu , {
212
- chevronOffset : 10 ,
213
- chevronFace : 'bottom' ,
214
- left : x ,
215
- top : y ,
216
- menuWidth : this . popoverWidth ,
217
- menuHeight : this . popoverHeight ,
218
- element : this . _getStickerpickerContent ( ) ,
219
- onFinished : this . _onFinished ,
220
- menuPaddingTop : 0 ,
221
- menuPaddingLeft : 0 ,
222
- menuPaddingRight : 0 ,
223
- } ) ;
224
-
225
213
226
- this . setState ( { showStickers : true } ) ;
214
+ this . setState ( {
215
+ showStickers : true ,
216
+ stickerPickerX : x ,
217
+ stickerPickerY : y ,
218
+ } ) ;
227
219
}
228
220
229
221
/**
230
222
* Trigger hiding of the sticker picker overlay
231
223
* @param {Event } ev Event that triggered the function call
232
224
*/
233
225
_onHideStickersClick ( ev ) {
234
- setTimeout ( ( ) => this . stickersMenu . close ( ) ) ;
226
+ this . setState ( { showStickers : false } ) ;
227
+ }
228
+
229
+ /**
230
+ * Called when the window is resized
231
+ */
232
+ _onResize ( ) {
233
+ this . setState ( { showStickers : false } ) ;
235
234
}
236
235
237
236
/**
@@ -250,20 +249,37 @@ export default class Stickerpicker extends React.Component {
250
249
this . scalarClient . getScalarInterfaceUrlForRoom (
251
250
this . props . room ,
252
251
'type_' + widgetType ,
253
- this . widgetId ,
252
+ this . state . widgetId ,
254
253
) :
255
254
null ;
256
255
Modal . createTrackedDialog ( 'Integrations Manager' , '' , IntegrationsManager , {
257
256
src : src ,
258
257
} , "mx_IntegrationsManager" ) ;
259
258
260
- // Wrap this in a timeout in order to avoid the DOM node from being pulled from under its feet
261
- setTimeout ( ( ) => this . stickersMenu . close ( ) ) ;
259
+ this . setState ( { showStickers : false } ) ;
262
260
}
263
261
264
262
render ( ) {
265
263
const TintableSvg = sdk . getComponent ( "elements.TintableSvg" ) ;
264
+ const ContextualMenu = sdk . getComponent ( 'structures.ContextualMenu' ) ;
265
+ const GenericElementContextMenu = sdk . getComponent ( 'context_menus.GenericElementContextMenu' ) ;
266
266
let stickersButton ;
267
+
268
+ const stickerPicker = < ContextualMenu
269
+ elementClass = { GenericElementContextMenu }
270
+ chevronOffset = { 10 }
271
+ chevronFace = { 'bottom' }
272
+ left = { this . state . stickerPickerX }
273
+ top = { this . state . stickerPickerY }
274
+ menuWidth = { this . popoverWidth }
275
+ menuHeight = { this . popoverHeight }
276
+ element = { this . _getStickerpickerContent ( ) }
277
+ onFinished = { this . _onFinished }
278
+ menuPaddingTop = { 0 }
279
+ menuPaddingLeft = { 0 }
280
+ menuPaddingRight = { 0 }
281
+ /> ;
282
+
267
283
if ( this . state . showStickers ) {
268
284
// Show hide-stickers button
269
285
stickersButton =
@@ -288,6 +304,9 @@ export default class Stickerpicker extends React.Component {
288
304
< TintableSvg src = "img/icons-show-stickers.svg" width = "35" height = "35" />
289
305
</ div > ;
290
306
}
291
- return stickersButton ;
307
+ return < div >
308
+ { stickersButton }
309
+ { this . state . showStickers && stickerPicker }
310
+ </ div > ;
292
311
}
293
312
}
0 commit comments