releasebird-javascript-sdk 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,14 +54,44 @@ export default class RbirdScreenshotManager {
54
54
  RbirdWebsiteWidget.getInstance().openWebsiteWidget();
55
55
  }
56
56
 
57
+ showLoader() {
58
+ const loader = document.createElement('div');
59
+ loader.id = 'rbirdScreenshotLoader';
60
+ loader.className = 'rbird-screenshot-loader';
61
+
62
+ const spinner = document.createElement('div');
63
+ spinner.className = 'rbird-screenshot-loader-spinner';
64
+
65
+ const text = document.createElement('div');
66
+ text.className = 'rbird-screenshot-loader-text';
67
+ text.textContent = 'Creating screenshot...';
68
+
69
+ loader.appendChild(spinner);
70
+ loader.appendChild(text);
71
+ document.body.appendChild(loader);
72
+
73
+ return loader;
74
+ }
75
+
76
+ hideLoader() {
77
+ const loader = document.getElementById('rbirdScreenshotLoader');
78
+ if (loader) {
79
+ document.body.removeChild(loader);
80
+ }
81
+ }
82
+
57
83
  screenshot() {
58
84
  let that = this;
85
+ const loader = this.showLoader();
86
+
59
87
  html2canvas(document.body, {
60
88
  allowTaint: false,
61
89
  useCORS: false,
62
90
  logging: false,
63
91
  foreignObjectRendering: false
64
92
  }).then(function (canvas) {
93
+ that.hideLoader();
94
+
65
95
  if (RbirdWebsiteWidget.getInstance().iframe) {
66
96
  RbirdWebsiteWidget.getInstance().iframe.contentWindow?.postMessage({
67
97
  type: 'screenshot',
@@ -73,7 +103,8 @@ export default class RbirdScreenshotManager {
73
103
 
74
104
  //document.body.appendChild(canvas);
75
105
  }).catch((e) => {
76
- document.body.appendChild(e.toString());
106
+ that.hideLoader();
107
+ console.error('Screenshot error:', e);
77
108
  });
78
109
  }
79
110
 
package/src/SVGEditor.js CHANGED
@@ -28,6 +28,9 @@ class Menu {
28
28
  pathButton.style.boxShadow = "none";
29
29
  pathButton.style.border = "none";
30
30
  pathButton.style.cursor = "pointer";
31
+ pathButton.style.touchAction = "manipulation";
32
+ pathButton.style.webkitTapHighlightColor = "transparent";
33
+ pathButton.style.padding = "5px";
31
34
  pathButton.innerHTML = "<svg fill=\"none\" height=\"20pt\" viewBox=\"0 0 120 120\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
32
35
  " <path clip-rule=\"evenodd\"\n" +
33
36
  " d=\"m76.25 82.5c-.6904 0-1.25.5596-1.25 1.25s.5596 1.25 1.25 1.25h21.25c6.904 0 12.5 5.5964 12.5 12.5 0 6.904-5.596 12.5-12.5 12.5h-71.5c-2.2091 0-4-1.791-4-4s1.7909-4 4-4h71.5c2.4853 0 4.5-2.0147 4.5-4.5s-2.0147-4.5-4.5-4.5h-21.25c-5.1086 0-9.25-4.1414-9.25-9.25s4.1414-9.25 9.25-9.25h24.75c2.209 0 4 1.7909 4 4s-1.791 4-4 4z\"\n" +
@@ -46,6 +49,9 @@ class Menu {
46
49
  rectButton.style.cursor = "pointer";
47
50
  rectButton.style.boxShadow = "none";
48
51
  rectButton.style.border = "none";
52
+ rectButton.style.touchAction = "manipulation";
53
+ rectButton.style.webkitTapHighlightColor = "transparent";
54
+ rectButton.style.padding = "5px";
49
55
  rectButton.innerHTML = "<svg id=\"Layer_1\" enable-background=\"new 0 0 48 48\" height=\"20pt\" viewBox=\"0 0 48 48\" width=\"20pt\"\n" +
50
56
  " xmlns=\"http://www.w3.org/2000/svg\">\n" +
51
57
  " <path d=\"m44 12.5h-40c-.83 0-1.5.67-1.5 1.5v20c0 .83.67 1.5 1.5 1.5h40c.83 0 1.5-.67 1.5-1.5v-20c0-.83-.67-1.5-1.5-1.5zm-1.5 20h-37v-17h37z\"/>\n" +
@@ -59,6 +65,9 @@ class Menu {
59
65
  circleButton.style.cursor = "pointer";
60
66
  circleButton.style.boxShadow = "none";
61
67
  circleButton.style.border = "none";
68
+ circleButton.style.touchAction = "manipulation";
69
+ circleButton.style.webkitTapHighlightColor = "transparent";
70
+ circleButton.style.padding = "5px";
62
71
  circleButton.innerHTML = "<svg height=\"20pt\" viewBox=\"0 0 512 512\" width=\"20pt\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
63
72
  " <path d=\"m256 512c-68.378906 0-132.667969-26.628906-181.019531-74.980469-48.351563-48.351562-74.980469-112.640625-74.980469-181.019531s26.628906-132.667969 74.980469-181.019531c48.351562-48.351563 112.640625-74.980469 181.019531-74.980469s132.667969 26.628906 181.019531 74.980469c48.351563 48.351562 74.980469 112.640625 74.980469 181.019531s-26.628906 132.667969-74.980469 181.019531c-48.351562 48.351563-112.640625 74.980469-181.019531 74.980469zm0-482c-124.617188 0-226 101.382812-226 226s101.382812 226 226 226 226-101.382812 226-226-101.382812-226-226-226zm0 0\"/>\n" +
64
73
  " <path d=\"m256 512c-68.378906 0-132.667969-26.628906-181.019531-74.980469-48.351563-48.351562-74.980469-112.640625-74.980469-181.019531s26.628906-132.667969 74.980469-181.019531c48.351562-48.351563 112.640625-74.980469 181.019531-74.980469s132.667969 26.628906 181.019531 74.980469c48.351563 48.351562 74.980469 112.640625 74.980469 181.019531s-26.628906 132.667969-74.980469 181.019531c-48.351562 48.351563-112.640625 74.980469-181.019531 74.980469zm0-482c-124.617188 0-226 101.382812-226 226s101.382812 226 226 226 226-101.382812 226-226-101.382812-226-226-226zm0 0\"/>\n" +
@@ -71,6 +80,9 @@ class Menu {
71
80
  ellipseButton.style.boxShadow = "none";
72
81
  ellipseButton.style.cursor = "pointer";
73
82
  ellipseButton.style.border = "none";
83
+ ellipseButton.style.touchAction = "manipulation";
84
+ ellipseButton.style.webkitTapHighlightColor = "transparent";
85
+ ellipseButton.style.padding = "5px";
74
86
  ellipseButton.addEventListener("click", (event) => this.onClick("shape", "ellipse"));
75
87
  ellipseButton.innerHTML = "<svg clip-rule=\"evenodd\" fill-rule=\"evenodd\" height=\"20pt\" stroke-linejoin=\"round\" stroke-miterlimit=\"2\"\n" +
76
88
  " viewBox=\"0 0 24 24\" width=\"20pt\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
@@ -89,17 +101,22 @@ class Menu {
89
101
  setResets() {
90
102
  const button = document.createElement("button");
91
103
  button.addEventListener("click", (event) => this.reset());
92
- button.style.setProperty("border-color", 'black');
93
104
  button.style.border = "none";
94
105
  button.style.background = "none";
95
106
  button.style.cursor = "pointer";
96
- button.style.marginTop = '3px';
97
- button.innerHTML = "<svg id=\"Capa_1\" enable-background=\"new 0 0 511.697 511.697\" height=\"15pt\" viewBox=\"0 0 511.697 511.697\" width=\"15pt\"\n" +
107
+ button.style.padding = "5px";
108
+ button.style.display = "flex";
109
+ button.style.alignItems = "center";
110
+ button.style.justifyContent = "center";
111
+ button.style.touchAction = "manipulation";
112
+ button.style.webkitTapHighlightColor = "transparent";
113
+ button.title = "Undo last drawing";
114
+ button.innerHTML = "<svg id=\"Capa_1\" enable-background=\"new 0 0 511.697 511.697\" height=\"20pt\" viewBox=\"0 0 511.697 511.697\" width=\"20pt\"\n" +
98
115
  " xmlns=\"http://www.w3.org/2000/svg\">\n" +
99
116
  " <g>\n" +
100
117
  " <path clip-rule=\"evenodd\"\n" +
101
118
  " d=\"m450.09 150.319c82.253 82.41 82.126 215.896-.284 298.149-39.451 39.376-92.891 61.526-148.63 61.606h-301.176v-60.235h301.176c83.167-.214 150.414-67.809 150.199-150.976-.214-82.864-67.335-149.985-150.199-150.199h-98.676v86.806l-202.5-116.922 202.5-116.926v86.807h98.678c55.893.006 109.48 22.278 148.912 61.89z\"\n" +
102
- " fill=\"#0291f7\" fill-rule=\"evenodd\"/>\n" +
119
+ " fill=\"#6b7280\" fill-rule=\"evenodd\"/>\n" +
103
120
  " </g>\n" +
104
121
  "</svg>";
105
122
  this.resets = [button];
@@ -111,13 +128,17 @@ class Menu {
111
128
  color.id = 'colorCircle';
112
129
  color.addEventListener("click", (event) => this.openColorPicker());
113
130
  color.style.cursor = 'pointer';
114
- color.style.marginTop = '3px';
115
- color.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"18pt\" width=\"18pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
131
+ color.style.padding = '5px';
132
+ color.style.display = 'flex';
133
+ color.style.alignItems = 'center';
134
+ color.style.justifyContent = 'center';
135
+ color.style.touchAction = 'manipulation';
136
+ color.style.webkitTapHighlightColor = 'transparent';
137
+ color.title = 'Select color';
138
+ color.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"24pt\" width=\"24pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
116
139
  " y=\"0px\"\n" +
117
140
  " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
118
- "<path style=\"fill:" + this.settings['color'] + "\"\n" +
119
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
120
- "/>\n" +
141
+ "<circle cx=\"256\" cy=\"256\" r=\"240\" fill=\"" + this.settings['color'] + "\" stroke=\"#d1d5db\" stroke-width=\"32\"/>\n" +
121
142
  "</svg>\n"
122
143
  temp.push(color);
123
144
  this.colors = temp;
@@ -133,138 +154,57 @@ class Menu {
133
154
  openColorPicker = () => {
134
155
  const colorPicker = document.createElement("div");
135
156
  colorPicker.id = "rbirdColorPicker";
136
- colorPicker.style.width = "200px";
137
- colorPicker.style.height = "60px";
157
+ colorPicker.style.display = "flex";
158
+ colorPicker.style.gap = "10px";
159
+ colorPicker.style.padding = "15px";
138
160
  colorPicker.style.cursor = "pointer";
139
161
  colorPicker.style.backgroundColor = "white";
140
162
  colorPicker.style.position = "absolute";
141
163
  colorPicker.style.top = "80px";
142
164
  colorPicker.style.zIndex = "900000000000";
143
165
  colorPicker.style.left = "50%";
144
- colorPicker.style.border = "1px solid lightgrey";
145
- colorPicker.style.padding = "10px";
146
- colorPicker.style.paddingTop = "15px";
166
+ colorPicker.style.transform = "translateX(-50%)";
167
+ colorPicker.style.border = "1px solid #e5e7eb";
168
+ colorPicker.style.borderRadius = "8px";
169
+ colorPicker.style.boxShadow = "0 4px 6px rgba(0, 0, 0, 0.1)";
147
170
  document.body.appendChild(colorPicker);
148
171
 
149
- const blackIcon = document.createElement("div");
150
- blackIcon.style.float = "left";
151
- blackIcon.addEventListener("click", (event) => {
152
- this.onClick("color", "black");
153
- if (this.colors[0]) {
154
- this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
155
- " y=\"0px\"\n" +
156
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
157
- "<path style=\"fill:black;\"\n" +
158
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
159
- "/>\n" +
160
- "</svg>\n";
161
- }
162
- });
163
- blackIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
164
- " y=\"0px\"\n" +
165
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
166
- "<path style=\"fill:#000000;\"\n" +
167
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
168
- "/>\n" +
169
- "</svg>\n";
170
- colorPicker.appendChild(blackIcon);
171
-
172
- const redIcon = document.createElement("div");
173
- redIcon.style.float = "left";
174
- redIcon.style.marginLeft = "10px";
175
- redIcon.addEventListener("click", (event) => {
176
- this.onClick("color", "red");
177
- if (this.colors[0]) {
178
- this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
179
- " y=\"0px\"\n" +
180
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
181
- "<path style=\"fill:red;\"\n" +
182
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
183
- "/>\n" +
184
- "</svg>\n";
185
- }
186
- });
187
- redIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
188
- " y=\"0px\"\n" +
189
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
190
- "<path style=\"fill:red;\"\n" +
191
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
192
- "/>\n" +
193
- "</svg>\n";
194
- colorPicker.appendChild(redIcon);
195
-
196
- const blueIcon = document.createElement("div");
197
- blueIcon.style.float = "left";
198
- blueIcon.style.marginLeft = "10px";
199
- blueIcon.addEventListener("click", (event) => {
200
- this.onClick("color", "blue");
201
- if (this.colors[0]) {
202
- this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
203
- " y=\"0px\"\n" +
204
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
205
- "<path style=\"fill:blue;\"\n" +
206
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
207
- "/>\n" +
208
- "</svg>\n";
209
- }
210
-
211
- });
212
- blueIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
213
- " y=\"0px\"\n" +
214
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
215
- "<path style=\"fill:blue;\"\n" +
216
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
217
- "/>\n" +
218
- "</svg>\n";
219
- colorPicker.appendChild(blueIcon);
220
-
221
- const yellowIcon = document.createElement("div");
222
- yellowIcon.style.float = "left";
223
- yellowIcon.style.marginLeft = "10px";
224
- yellowIcon.addEventListener("click", (event) => {
225
- this.onClick("color", "yellow");
226
- if (this.colors[0]) {
227
- this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
228
- " y=\"0px\"\n" +
229
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
230
- "<path style=\"fill:yellow;\"\n" +
231
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
232
- "/>\n" +
233
- "</svg>\n";
234
- }
235
- });
236
- yellowIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
237
- " y=\"0px\"\n" +
238
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
239
- "<path style=\"fill:yellow;\"\n" +
240
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
241
- "/>\n" +
242
- "</svg>\n";
243
- colorPicker.appendChild(yellowIcon);
244
-
245
- const greenIcon = document.createElement("div");
246
- greenIcon.style.float = "left";
247
- greenIcon.style.marginLeft = "10px";
248
- greenIcon.addEventListener("click", (event) => {
249
- this.onClick("color", "green");
250
- if (this.colors[0]) {
251
- this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
252
- " y=\"0px\"\n" +
253
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
254
- "<path style=\"fill:green;\"\n" +
255
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
256
- "/>\n" +
257
- "</svg>\n";
258
- }
172
+ const colors = [
173
+ { name: 'black', hex: '#000000' },
174
+ { name: 'red', hex: '#ef4444' },
175
+ { name: 'blue', hex: '#3b82f6' },
176
+ { name: 'yellow', hex: '#fbbf24' },
177
+ { name: 'green', hex: '#10b981' }
178
+ ];
179
+
180
+ colors.forEach(colorObj => {
181
+ const colorIcon = document.createElement("div");
182
+ colorIcon.style.cursor = "pointer";
183
+ colorIcon.style.transition = "transform 0.2s";
184
+ colorIcon.addEventListener("mouseenter", () => {
185
+ colorIcon.style.transform = "scale(1.1)";
186
+ });
187
+ colorIcon.addEventListener("mouseleave", () => {
188
+ colorIcon.style.transform = "scale(1)";
189
+ });
190
+ colorIcon.addEventListener("click", (event) => {
191
+ this.onClick("color", colorObj.name);
192
+ if (this.colors[0]) {
193
+ this.colors[0].innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"24pt\" width=\"24pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
194
+ " y=\"0px\"\n" +
195
+ " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
196
+ "<circle cx=\"256\" cy=\"256\" r=\"240\" fill=\"" + colorObj.hex + "\" stroke=\"#d1d5db\" stroke-width=\"32\"/>\n" +
197
+ "</svg>\n";
198
+ }
199
+ this.closeColorPicker();
200
+ });
201
+ colorIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"28pt\" width=\"28pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
202
+ " y=\"0px\"\n" +
203
+ " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
204
+ "<circle cx=\"256\" cy=\"256\" r=\"240\" fill=\"" + colorObj.hex + "\" stroke=\"#d1d5db\" stroke-width=\"32\"/>\n" +
205
+ "</svg>\n";
206
+ colorPicker.appendChild(colorIcon);
259
207
  });
260
- greenIcon.innerHTML = "<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20pt\" width=\"20pt\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\"\n" +
261
- " y=\"0px\"\n" +
262
- " viewBox=\"0 0 512 512\" style=\"enable-background:new 0 0 512 512;\" xml:space=\"preserve\">\n" +
263
- "<path style=\"fill:green;\"\n" +
264
- " d=\"M256,0C114.608,0,0,114.608,0,256s114.608,256,256,256s256-114.608,256-256S397.392,0,256,0L256,0z\"\n" +
265
- "/>\n" +
266
- "</svg>\n";
267
- colorPicker.appendChild(greenIcon);
268
208
 
269
209
  colorPicker.addEventListener("click", (event) => this.closeColorPicker());
270
210
  }
@@ -281,34 +221,84 @@ class Menu {
281
221
  this.updateButtons();
282
222
 
283
223
  const menu = document.createElement("div");
284
- menu.classList.add("menu")
285
-
286
- Object.keys(this.settings).forEach((setting) => {
287
- const section = document.createElement("div");
288
- section.style.float = "left";
289
- this[setting + "s"].forEach((button) => section.appendChild(button));
290
- menu.appendChild(section);
291
- });
292
-
293
- const nextButton = document.createElement('div')
294
- nextButton.style.backgroundColor = 'green';
224
+ menu.classList.add("menu");
225
+ menu.style.display = "flex";
226
+ menu.style.alignItems = "center";
227
+ menu.style.gap = "15px";
228
+ menu.style.flexWrap = "wrap";
229
+
230
+ // Tools section (shapes)
231
+ const toolsSection = document.createElement("div");
232
+ toolsSection.style.display = "flex";
233
+ toolsSection.style.gap = "5px";
234
+ toolsSection.style.alignItems = "center";
235
+ toolsSection.style.paddingRight = "15px";
236
+ toolsSection.style.borderRight = "1px solid #ddd";
237
+ this.shapes.forEach((button) => toolsSection.appendChild(button));
238
+ menu.appendChild(toolsSection);
239
+
240
+ // Color section
241
+ const colorSection = document.createElement("div");
242
+ colorSection.style.display = "flex";
243
+ colorSection.style.gap = "5px";
244
+ colorSection.style.alignItems = "center";
245
+ colorSection.style.paddingRight = "15px";
246
+ colorSection.style.borderRight = "1px solid #ddd";
247
+ this.colors.forEach((button) => colorSection.appendChild(button));
248
+ menu.appendChild(colorSection);
249
+
250
+ // Reset section
251
+ const resetSection = document.createElement("div");
252
+ resetSection.style.display = "flex";
253
+ resetSection.style.gap = "5px";
254
+ resetSection.style.alignItems = "center";
255
+ this.resets.forEach((button) => resetSection.appendChild(button));
256
+ menu.appendChild(resetSection);
257
+
258
+ // Take Screenshot button
259
+ const nextButton = document.createElement('div');
260
+ nextButton.style.backgroundColor = '#10b981';
295
261
  nextButton.style.color = 'white';
296
- nextButton.style.fontWeight = '500';
262
+ nextButton.style.fontWeight = '600';
297
263
  nextButton.innerHTML = "Take Screenshot";
298
- nextButton.style.float = "left";
299
- nextButton.style.padding = "13px";
300
- nextButton.style.paddingTop = "8px";
301
- nextButton.style.paddingBottom = "8px";
302
- nextButton.style.fontFamily = "Arial";
303
- nextButton.style.fontSize = "16px";
264
+ nextButton.style.padding = "10px 20px";
265
+ nextButton.style.fontFamily = "Arial, sans-serif";
266
+ nextButton.style.fontSize = "15px";
304
267
  nextButton.style.borderRadius = "8px";
305
- nextButton.style.marginLeft = "10px";
306
268
  nextButton.style.cursor = "pointer";
269
+ nextButton.style.touchAction = "manipulation";
270
+ nextButton.style.userSelect = "none";
271
+ nextButton.style.webkitUserSelect = "none";
272
+ nextButton.style.webkitTapHighlightColor = "transparent";
273
+ nextButton.style.transition = "background-color 0.2s";
274
+ nextButton.style.whiteSpace = "nowrap";
275
+
276
+ nextButton.addEventListener("mouseenter", () => {
277
+ nextButton.style.backgroundColor = "#059669";
278
+ });
279
+
280
+ nextButton.addEventListener("mouseleave", () => {
281
+ nextButton.style.backgroundColor = "#10b981";
282
+ });
283
+
284
+ // Mobile responsive adjustments
285
+ if (window.innerWidth <= 768) {
286
+ nextButton.style.fontSize = "14px";
287
+ nextButton.style.padding = "8px 16px";
288
+ menu.style.gap = "8px";
289
+ toolsSection.style.paddingRight = "8px";
290
+ colorSection.style.paddingRight = "8px";
291
+ }
307
292
 
308
293
  nextButton.addEventListener("click", (event) => {
309
294
  RbirdScreenshotManager.getInstance().screenshot();
310
295
  });
311
296
 
297
+ // Add touch event for better mobile support
298
+ nextButton.addEventListener("touchstart", (event) => {
299
+ event.stopPropagation();
300
+ });
301
+
312
302
  menu.appendChild(nextButton);
313
303
 
314
304
  return menu;
@@ -380,9 +370,16 @@ export default class SVGEditor {
380
370
  }
381
371
 
382
372
  attachEvents(svg) {
373
+ // Mouse events
383
374
  svg.addEventListener("mousedown", this.onMouseDown.bind(this));
384
375
  svg.addEventListener("mousemove", this.onMouseMove.bind(this));
385
376
  svg.addEventListener("mouseup", this.onMouseUp.bind(this));
377
+
378
+ // Touch events for mobile/tablet
379
+ svg.addEventListener("touchstart", this.onTouchStart.bind(this), {passive: false});
380
+ svg.addEventListener("touchmove", this.onTouchMove.bind(this), {passive: false});
381
+ svg.addEventListener("touchend", this.onTouchEnd.bind(this));
382
+ svg.addEventListener("touchcancel", this.onTouchEnd.bind(this));
386
383
  }
387
384
 
388
385
  createMenu() {
@@ -409,6 +406,19 @@ export default class SVGEditor {
409
406
  element.style.padding = '10px';
410
407
  element.style.borderRadius = '8px';
411
408
  element.style.transform = 'translateX(-50%)';
409
+ element.style.touchAction = 'manipulation';
410
+ element.style.userSelect = 'none';
411
+ element.style.webkitUserSelect = 'none';
412
+ element.style.zIndex = '900000001';
413
+
414
+ // Mobile responsive adjustments
415
+ if (window.innerWidth <= 768) {
416
+ element.style.padding = '8px';
417
+ element.style.top = '5px';
418
+ element.style.maxWidth = '95vw';
419
+ element.style.overflowX = 'auto';
420
+ }
421
+
412
422
  return element;
413
423
  }
414
424
 
@@ -416,6 +426,37 @@ export default class SVGEditor {
416
426
  this.codeSection.innerText = this.svg.innerHTML.replace(new RegExp("><", "g"), ">\n<");
417
427
  }
418
428
 
429
+ getEventPosition(event) {
430
+ // Handle touch events
431
+ if (event.touches && event.touches.length > 0) {
432
+ const touch = event.touches[0];
433
+ const rect = this.svg.getBoundingClientRect();
434
+ return {
435
+ x: touch.clientX - rect.left,
436
+ y: touch.clientY - rect.top
437
+ };
438
+ }
439
+ // Handle mouse events
440
+ return {
441
+ x: event.offsetX,
442
+ y: event.offsetY
443
+ };
444
+ }
445
+
446
+ onTouchStart(event) {
447
+ event.preventDefault();
448
+ this.onMouseDown(event);
449
+ }
450
+
451
+ onTouchMove(event) {
452
+ event.preventDefault();
453
+ this.onMouseMove(event);
454
+ }
455
+
456
+ onTouchEnd(event) {
457
+ this.onMouseUp();
458
+ }
459
+
419
460
  onMouseDown(event) {
420
461
  this.createdObject = document.createElementNS(svgns, this.menuSettings.shape);
421
462
  this.createdObject.setAttributeNS(null, "fill", this.menuSettings.fill);
@@ -423,10 +464,8 @@ export default class SVGEditor {
423
464
  this.createdObject.setAttributeNS(null, "stroke-width", String(this.menuSettings.size));
424
465
  this.svg.appendChild(this.createdObject);
425
466
 
426
- this.originalMousePosition = this.lastMousePosition = this.currentMousePosition = {
427
- x: event.offsetX,
428
- y: event.offsetY
429
- };
467
+ const position = this.getEventPosition(event);
468
+ this.originalMousePosition = this.lastMousePosition = this.currentMousePosition = position;
430
469
 
431
470
  switch (this.menuSettings.shape) {
432
471
  case "path":
@@ -441,7 +480,7 @@ export default class SVGEditor {
441
480
  return;
442
481
 
443
482
  this.lastMousePosition = this.currentMousePosition;
444
- this.currentMousePosition = {x: event.offsetX, y: event.offsetY};
483
+ this.currentMousePosition = this.getEventPosition(event);
445
484
 
446
485
  this.updateCurrentObject();
447
486
  }
package/src/Styles.js CHANGED
@@ -85,6 +85,7 @@ export const injectStyledCSS = (
85
85
  font-family: inherit;
86
86
  overflow-y: hidden;
87
87
  height: ${!isMobile ? '725px' : '100%'};
88
+ max-height: ${!isMobile ? '725px' : '100%'};
88
89
  text-align: center;
89
90
  bottom: ${!isMobile ? spaceBottom + 30 : 0}px;
90
91
  right: ${(launcherPosition === 'right' && !isMobile) ? (spaceLeftRight + 10) + 'px' : 'unset'};
@@ -92,6 +93,20 @@ export const injectStyledCSS = (
92
93
  top: ${!isMobile ? 'unset' : 0}px;
93
94
  }
94
95
 
96
+ @media (min-width: 769px) and (max-width: 1024px) {
97
+ .cta__modal {
98
+ width: 100% !important;
99
+ height: 100% !important;
100
+ max-height: 100vh !important;
101
+ bottom: 0 !important;
102
+ top: env(safe-area-inset-top) !important;
103
+ left: 0 !important;
104
+ right: 0 !important;
105
+ border-radius: 0 !important;
106
+ padding-top: env(safe-area-inset-top);
107
+ }
108
+ }
109
+
95
110
  .cta__modal_loading {
96
111
  position: fixed;
97
112
  outline: none;
@@ -296,6 +311,41 @@ background: transparent
296
311
  width: 100%;
297
312
  }
298
313
  }
314
+
315
+ .rbird-screenshot-loader {
316
+ position: fixed;
317
+ top: 50%;
318
+ left: 50%;
319
+ transform: translate(-50%, -50%);
320
+ z-index: 900000010;
321
+ text-align: center;
322
+ background-color: rgba(255, 255, 255, 0.95);
323
+ padding: 30px 40px;
324
+ border-radius: 12px;
325
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
326
+ }
327
+
328
+ .rbird-screenshot-loader-spinner {
329
+ border: 4px solid #f3f3f3;
330
+ border-top: 4px solid #3498db;
331
+ border-radius: 50%;
332
+ width: 50px;
333
+ height: 50px;
334
+ animation: rbird-spin 1s linear infinite;
335
+ margin: 0 auto 15px;
336
+ }
337
+
338
+ .rbird-screenshot-loader-text {
339
+ color: #333;
340
+ font-size: 16px;
341
+ font-weight: 500;
342
+ font-family: Arial, sans-serif;
343
+ }
344
+
345
+ @keyframes rbird-spin {
346
+ 0% { transform: rotate(0deg); }
347
+ 100% { transform: rotate(360deg); }
348
+ }
299
349
  }`
300
350
 
301
351
  const oldNode = document.querySelector(".rbird-styles");
package/webpack.config.js CHANGED
@@ -66,7 +66,7 @@ module.exports = {
66
66
  new webpack.DefinePlugin({
67
67
  PRODUCTION: 'true',
68
68
  API: JSON.stringify("https://api.releasebird.com/papi"),
69
- CONTENT_URL: JSON.stringify("https://prod.d2ihnay16ya32m.amplifyapp.com"),
69
+ CONTENT_URL: JSON.stringify("https://wcontent.releasebird.net"),
70
70
  }),
71
71
  {
72
72
  apply: (compiler) => {