@blerp/design 1.3.16 → 1.4.1
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.
- package/dist/cjs/Blerp/BlerpImageRow.js +176 -57
- package/dist/cjs/Blerp/BlerpSavePopup.js +44 -40
- package/dist/cjs/Blerp/BlerpTitleRow.js +36 -19
- package/dist/cjs/Blerp/BlerpTopRow.js +110 -44
- package/dist/cjs/Blerp.js +9 -16
- package/dist/cjs/BlerpAudioContextProvider.js +2 -2
- package/dist/cjs/BlerpListView.js +318 -168
- package/dist/cjs/BlerpListViewPremium.js +155 -130
- package/dist/cjs/BlerpListViewSkeleton.js +60 -13
- package/dist/cjs/BlerpSkeleton.js +32 -9
- package/dist/cjs/CollectionCard.js +139 -60
- package/dist/cjs/CollectionListViewPremium.js +368 -297
- package/dist/cjs/CollectionSkeleton.js +74 -13
- package/dist/cjs/Dropdown.js +272 -172
- package/dist/cjs/EllipsisLoader.js +66 -21
- package/dist/cjs/GroupCard.js +64 -57
- package/dist/cjs/Icons/Icons.js +288 -426
- package/dist/cjs/ImageEditor.js +247 -0
- package/dist/cjs/ImageUpload.js +226 -0
- package/dist/cjs/NewBlerp.js +354 -160
- package/dist/cjs/NewBlerpTest.js +10 -792
- package/dist/cjs/NewCollectionModal.js +294 -310
- package/dist/cjs/PremiumCollectionCard.js +191 -454
- package/dist/cjs/PurchaseModals/CheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumBlerpCheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumCollectionCheckoutModal.js +1 -1
- package/dist/cjs/PurchaseModals/PremiumSubscriptionCheckoutModal.js +1 -1
- package/dist/cjs/ReactionButtons.js +26 -13
- package/dist/cjs/SnackbarContextProvider.js +200 -116
- package/dist/cjs/Theme.js +217 -90
- package/dist/cjs/Toggle.js +86 -32
- package/dist/cjs/UserCard.js +13 -32
- package/dist/cjs/UserPage/LibraryControls.js +180 -93
- package/dist/cjs/UserPage/UserLibraryHeader.js +23 -14
- package/dist/cjs/UserPage/UserProfileHeader.js +120 -105
- package/dist/cjs/UsernameWithPopout.js +12 -8
- package/dist/cjs/colors.js +15 -8
- package/dist/cjs/helpers.js +131 -0
- package/dist/cjs/index.js +98 -52
- package/dist/cjs/neo-components/Autocomplete.js +280 -0
- package/dist/cjs/neo-components/BottomNavigation.js +120 -0
- package/dist/cjs/neo-components/Box.js +48 -0
- package/dist/cjs/neo-components/Button.js +206 -0
- package/dist/cjs/neo-components/CircularProgress.js +92 -0
- package/dist/cjs/neo-components/Container.js +75 -0
- package/dist/cjs/neo-components/Dialog.js +441 -0
- package/dist/cjs/neo-components/Fab.js +237 -0
- package/dist/cjs/neo-components/FormControls.js +1057 -0
- package/dist/cjs/neo-components/Grid.js +256 -0
- package/dist/cjs/neo-components/IconButton.js +111 -0
- package/dist/cjs/neo-components/Input.js +493 -0
- package/dist/cjs/neo-components/Layout.js +1213 -0
- package/dist/cjs/neo-components/Misc.js +858 -0
- package/dist/cjs/neo-components/Navigation.js +1578 -0
- package/dist/cjs/neo-components/Paper.js +256 -0
- package/dist/cjs/neo-components/Stack.js +194 -0
- package/dist/cjs/neo-components/Stepper.js +291 -0
- package/dist/cjs/neo-components/Text.js +290 -0
- package/dist/cjs/neo-components/ThemeProvider.js +731 -0
- package/dist/cjs/neo-components/ToggleButton.js +223 -0
- package/dist/cjs/neo-components/createTheme.js +306 -0
- package/dist/cjs/neo-components/withSx.js +164 -0
- package/dist/cjs/neo-utils/sxToStyle.js +508 -0
- package/dist/esm/Blerp/BlerpImageRow.js +166 -46
- package/dist/esm/Blerp/BlerpSavePopup.js +35 -27
- package/dist/esm/Blerp/BlerpTitleRow.js +32 -13
- package/dist/esm/Blerp/BlerpTopRow.js +85 -16
- package/dist/esm/Blerp.js +4 -12
- package/dist/esm/BlerpAudioContextProvider.js +1 -2
- package/dist/esm/BlerpListView.js +313 -160
- package/dist/esm/BlerpListViewPremium.js +135 -109
- package/dist/esm/BlerpListViewSkeleton.js +60 -11
- package/dist/esm/BlerpSkeleton.js +32 -7
- package/dist/esm/CollectionCard.js +118 -38
- package/dist/esm/CollectionListViewPremium.js +367 -294
- package/dist/esm/CollectionSkeleton.js +73 -11
- package/dist/esm/Dropdown.js +260 -161
- package/dist/esm/EllipsisLoader.js +63 -18
- package/dist/esm/GroupCard.js +54 -46
- package/dist/esm/Icons/Icons.js +226 -367
- package/dist/esm/ImageEditor.js +240 -0
- package/dist/esm/ImageUpload.js +217 -0
- package/dist/esm/NewBlerp.js +282 -79
- package/dist/esm/NewBlerpTest.js +11 -781
- package/dist/esm/NewCollectionModal.js +289 -304
- package/dist/esm/PremiumCollectionCard.js +192 -451
- package/dist/esm/PurchaseModals/CheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumBlerpCheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumCollectionCheckoutModal.js +1 -1
- package/dist/esm/PurchaseModals/PremiumSubscriptionCheckoutModal.js +1 -1
- package/dist/esm/ReactionButtons.js +23 -8
- package/dist/esm/SnackbarContextProvider.js +196 -110
- package/dist/esm/Theme.js +187 -66
- package/dist/esm/Toggle.js +84 -29
- package/dist/esm/UserCard.js +1 -20
- package/dist/esm/UserPage/LibraryControls.js +159 -65
- package/dist/esm/UserPage/UserLibraryHeader.js +18 -10
- package/dist/esm/UserPage/UserProfileHeader.js +100 -79
- package/dist/esm/UsernameWithPopout.js +7 -4
- package/dist/esm/colors.js +11 -9
- package/dist/esm/helpers.js +122 -0
- package/dist/esm/icons.js +1 -1
- package/dist/esm/index.js +39 -3
- package/dist/esm/neo-components/Autocomplete.js +269 -0
- package/dist/esm/neo-components/BottomNavigation.js +109 -0
- package/dist/esm/neo-components/Box.js +36 -0
- package/dist/esm/neo-components/Button.js +194 -0
- package/dist/esm/neo-components/CircularProgress.js +81 -0
- package/dist/esm/neo-components/Container.js +63 -0
- package/dist/esm/neo-components/Dialog.js +423 -0
- package/dist/esm/neo-components/Fab.js +225 -0
- package/dist/esm/neo-components/FormControls.js +1041 -0
- package/dist/esm/neo-components/Grid.js +244 -0
- package/dist/esm/neo-components/IconButton.js +99 -0
- package/dist/esm/neo-components/Input.js +478 -0
- package/dist/esm/neo-components/Layout.js +1179 -0
- package/dist/esm/neo-components/Misc.js +840 -0
- package/dist/esm/neo-components/Navigation.js +1556 -0
- package/dist/esm/neo-components/Paper.js +243 -0
- package/dist/esm/neo-components/Stack.js +182 -0
- package/dist/esm/neo-components/Stepper.js +278 -0
- package/dist/esm/neo-components/Text.js +277 -0
- package/dist/esm/neo-components/ThemeProvider.js +718 -0
- package/dist/esm/neo-components/ToggleButton.js +214 -0
- package/dist/esm/neo-components/createTheme.js +297 -0
- package/dist/esm/neo-components/withSx.js +153 -0
- package/dist/esm/neo-utils/sxToStyle.js +502 -0
- package/package.json +19 -15
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
2
|
+
import React, { forwardRef, useRef, useState, useImperativeHandle, useEffect, useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
5
|
+
|
|
6
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
7
|
+
const ImageEditor = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
8
|
+
let {
|
|
9
|
+
image,
|
|
10
|
+
width = 250,
|
|
11
|
+
height = 250,
|
|
12
|
+
borderRadius = 0,
|
|
13
|
+
scale = 1,
|
|
14
|
+
position = {
|
|
15
|
+
x: 0.5,
|
|
16
|
+
y: 0.5
|
|
17
|
+
},
|
|
18
|
+
onPositionChange,
|
|
19
|
+
rotate = 0,
|
|
20
|
+
crossOrigin = 'anonymous',
|
|
21
|
+
style = {},
|
|
22
|
+
className = ''
|
|
23
|
+
} = _ref;
|
|
24
|
+
const canvasRef = useRef(null);
|
|
25
|
+
const containerRef = useRef(null);
|
|
26
|
+
const imageRef = useRef(null);
|
|
27
|
+
const [internalPosition, setInternalPosition] = useState(position);
|
|
28
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
29
|
+
const dragStart = useRef({
|
|
30
|
+
x: 0,
|
|
31
|
+
y: 0
|
|
32
|
+
});
|
|
33
|
+
const [imageLoaded, setImageLoaded] = useState(false);
|
|
34
|
+
const [imageError, setImageError] = useState(false); // Expose the same API as react-avatar-editor
|
|
35
|
+
|
|
36
|
+
useImperativeHandle(ref, () => ({
|
|
37
|
+
getImage: () => {
|
|
38
|
+
return canvasRef.current;
|
|
39
|
+
},
|
|
40
|
+
getImageScaledToCanvas: () => {
|
|
41
|
+
return canvasRef.current;
|
|
42
|
+
}
|
|
43
|
+
})); // Sync position prop with internal state
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setInternalPosition(position);
|
|
47
|
+
}, [position]); // Draw the image on canvas
|
|
48
|
+
|
|
49
|
+
const drawImage = useCallback(() => {
|
|
50
|
+
if (!imageRef.current || !imageLoaded) return;
|
|
51
|
+
const canvas = canvasRef.current;
|
|
52
|
+
if (!canvas) return;
|
|
53
|
+
const ctx = canvas.getContext('2d'); // Clear canvas
|
|
54
|
+
|
|
55
|
+
ctx.clearRect(0, 0, width, height); // Save context for clipping
|
|
56
|
+
|
|
57
|
+
ctx.save(); // Apply circular clipping if borderRadius equals half of width (circular)
|
|
58
|
+
|
|
59
|
+
if (borderRadius > 0) {
|
|
60
|
+
ctx.beginPath();
|
|
61
|
+
|
|
62
|
+
if (borderRadius >= width / 2) {
|
|
63
|
+
// Circular clip
|
|
64
|
+
ctx.arc(width / 2, height / 2, width / 2, 0, Math.PI * 2);
|
|
65
|
+
} else {
|
|
66
|
+
// Rounded rectangle clip
|
|
67
|
+
const x = 0,
|
|
68
|
+
y = 0,
|
|
69
|
+
w = width,
|
|
70
|
+
h = height,
|
|
71
|
+
r = borderRadius;
|
|
72
|
+
ctx.moveTo(x + r, y);
|
|
73
|
+
ctx.lineTo(x + w - r, y);
|
|
74
|
+
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
|
|
75
|
+
ctx.lineTo(x + w, y + h - r);
|
|
76
|
+
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
|
|
77
|
+
ctx.lineTo(x + r, y + h);
|
|
78
|
+
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
|
|
79
|
+
ctx.lineTo(x, y + r);
|
|
80
|
+
ctx.quadraticCurveTo(x, y, x + r, y);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
ctx.clip();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const img = imageRef.current; // Calculate scaled dimensions
|
|
87
|
+
|
|
88
|
+
const scaledWidth = img.naturalWidth * scale;
|
|
89
|
+
const scaledHeight = img.naturalHeight * scale; // Calculate position - convert from 0-1 range to pixel offset
|
|
90
|
+
|
|
91
|
+
const maxOffsetX = Math.max(0, (scaledWidth - width) / 2);
|
|
92
|
+
const maxOffsetY = Math.max(0, (scaledHeight - height) / 2);
|
|
93
|
+
const offsetX = (internalPosition.x - 0.5) * maxOffsetX * 2;
|
|
94
|
+
const offsetY = (internalPosition.y - 0.5) * maxOffsetY * 2; // Center the image with position offset
|
|
95
|
+
|
|
96
|
+
const x = (width - scaledWidth) / 2 - offsetX;
|
|
97
|
+
const y = (height - scaledHeight) / 2 - offsetY; // Apply rotation if needed
|
|
98
|
+
|
|
99
|
+
if (rotate !== 0) {
|
|
100
|
+
ctx.translate(width / 2, height / 2);
|
|
101
|
+
ctx.rotate(rotate * Math.PI / 180);
|
|
102
|
+
ctx.translate(-width / 2, -height / 2);
|
|
103
|
+
} // Draw image
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
ctx.drawImage(img, x, y, scaledWidth, scaledHeight); // Restore context
|
|
107
|
+
|
|
108
|
+
ctx.restore();
|
|
109
|
+
}, [imageLoaded, width, height, scale, internalPosition, borderRadius, rotate]); // Load image
|
|
110
|
+
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (!image) {
|
|
113
|
+
setImageLoaded(false);
|
|
114
|
+
setImageError(false);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const img = new Image();
|
|
119
|
+
|
|
120
|
+
if (crossOrigin) {
|
|
121
|
+
img.crossOrigin = crossOrigin;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
img.onload = () => {
|
|
125
|
+
imageRef.current = img;
|
|
126
|
+
setImageLoaded(true);
|
|
127
|
+
setImageError(false);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
img.onerror = () => {
|
|
131
|
+
console.error('Failed to load image');
|
|
132
|
+
setImageError(true);
|
|
133
|
+
setImageLoaded(false);
|
|
134
|
+
}; // Handle both File objects and URLs
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
let objectURL = null;
|
|
138
|
+
|
|
139
|
+
if (typeof image === 'string') {
|
|
140
|
+
img.src = image;
|
|
141
|
+
} else if (image instanceof File || image instanceof Blob) {
|
|
142
|
+
objectURL = URL.createObjectURL(image);
|
|
143
|
+
img.src = objectURL;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return () => {
|
|
147
|
+
if (objectURL) {
|
|
148
|
+
URL.revokeObjectURL(objectURL);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}, [image, crossOrigin]); // Redraw when dependencies change
|
|
152
|
+
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
drawImage();
|
|
155
|
+
}, [drawImage]); // Mouse drag handlers for panning
|
|
156
|
+
|
|
157
|
+
const handleMouseDown = e => {
|
|
158
|
+
e.preventDefault();
|
|
159
|
+
setIsDragging(true);
|
|
160
|
+
dragStart.current = {
|
|
161
|
+
x: e.clientX,
|
|
162
|
+
y: e.clientY,
|
|
163
|
+
startPosX: internalPosition.x,
|
|
164
|
+
startPosY: internalPosition.y
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const handleMouseMove = useCallback(e => {
|
|
169
|
+
if (!isDragging || !imageRef.current) return;
|
|
170
|
+
const img = imageRef.current;
|
|
171
|
+
const scaledWidth = img.naturalWidth * scale;
|
|
172
|
+
const scaledHeight = img.naturalHeight * scale; // Calculate how much the image is larger than the canvas
|
|
173
|
+
|
|
174
|
+
const maxOffsetX = Math.max(0, (scaledWidth - width) / 2);
|
|
175
|
+
const maxOffsetY = Math.max(0, (scaledHeight - height) / 2); // Convert pixel movement to position (0-1 range)
|
|
176
|
+
|
|
177
|
+
const deltaX = e.clientX - dragStart.current.x;
|
|
178
|
+
const deltaY = e.clientY - dragStart.current.y;
|
|
179
|
+
const positionDeltaX = maxOffsetX > 0 ? deltaX / maxOffsetX / 2 : 0;
|
|
180
|
+
const positionDeltaY = maxOffsetY > 0 ? deltaY / maxOffsetY / 2 : 0;
|
|
181
|
+
const newPosition = {
|
|
182
|
+
x: Math.max(0, Math.min(1, dragStart.current.startPosX + positionDeltaX)),
|
|
183
|
+
y: Math.max(0, Math.min(1, dragStart.current.startPosY + positionDeltaY))
|
|
184
|
+
};
|
|
185
|
+
setInternalPosition(newPosition);
|
|
186
|
+
|
|
187
|
+
if (onPositionChange) {
|
|
188
|
+
onPositionChange(newPosition);
|
|
189
|
+
}
|
|
190
|
+
}, [isDragging, scale, width, height, onPositionChange]);
|
|
191
|
+
const handleMouseUp = useCallback(() => {
|
|
192
|
+
setIsDragging(false);
|
|
193
|
+
}, []); // Add/remove global mouse event listeners
|
|
194
|
+
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
if (isDragging) {
|
|
197
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
198
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
199
|
+
return () => {
|
|
200
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
201
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}, [isDragging, handleMouseMove, handleMouseUp]);
|
|
205
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
206
|
+
ref: containerRef,
|
|
207
|
+
className: className,
|
|
208
|
+
style: _objectSpread({
|
|
209
|
+
width: "".concat(width, "px"),
|
|
210
|
+
height: "".concat(height, "px"),
|
|
211
|
+
borderRadius: "".concat(borderRadius, "px"),
|
|
212
|
+
overflow: 'hidden',
|
|
213
|
+
cursor: isDragging ? 'grabbing' : 'grab',
|
|
214
|
+
backgroundColor: '#f0f0f0'
|
|
215
|
+
}, style),
|
|
216
|
+
onMouseDown: handleMouseDown
|
|
217
|
+
}, /*#__PURE__*/React.createElement("canvas", {
|
|
218
|
+
ref: canvasRef,
|
|
219
|
+
width: width,
|
|
220
|
+
height: height,
|
|
221
|
+
style: {
|
|
222
|
+
display: 'block',
|
|
223
|
+
width: '100%',
|
|
224
|
+
height: '100%'
|
|
225
|
+
}
|
|
226
|
+
}), imageError && /*#__PURE__*/React.createElement("div", {
|
|
227
|
+
style: {
|
|
228
|
+
position: 'absolute',
|
|
229
|
+
top: '50%',
|
|
230
|
+
left: '50%',
|
|
231
|
+
transform: 'translate(-50%, -50%)',
|
|
232
|
+
color: '#999',
|
|
233
|
+
fontSize: '12px',
|
|
234
|
+
textAlign: 'center'
|
|
235
|
+
}
|
|
236
|
+
}, "Failed to load image"));
|
|
237
|
+
});
|
|
238
|
+
ImageEditor.displayName = 'ImageEditor';
|
|
239
|
+
|
|
240
|
+
export { ImageEditor as default };
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import _extends from '@babel/runtime/helpers/extends';
|
|
2
|
+
import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
3
|
+
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
4
|
+
import { Stack, Text, Box, Button } from './index.js';
|
|
5
|
+
import React, { useState, useRef, useEffect, createRef } from 'react';
|
|
6
|
+
import ImageEditor from './ImageEditor.js';
|
|
7
|
+
import { useWindowSize } from './ScreenSizeHook.js';
|
|
8
|
+
import { useBlerpTheme } from './Theme.js';
|
|
9
|
+
|
|
10
|
+
const _excluded = ["path", "sx", "size"];
|
|
11
|
+
|
|
12
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
13
|
+
|
|
14
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
15
|
+
|
|
16
|
+
const Icon = _ref => {
|
|
17
|
+
let {
|
|
18
|
+
path,
|
|
19
|
+
sx,
|
|
20
|
+
size = "24px"
|
|
21
|
+
} = _ref,
|
|
22
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
23
|
+
|
|
24
|
+
return /*#__PURE__*/React.createElement(Box, _extends({
|
|
25
|
+
component: "svg",
|
|
26
|
+
viewBox: "0 0 24 24",
|
|
27
|
+
width: size,
|
|
28
|
+
height: size,
|
|
29
|
+
fill: "currentColor",
|
|
30
|
+
sx: _objectSpread({
|
|
31
|
+
display: "inline-block",
|
|
32
|
+
flexShrink: 0
|
|
33
|
+
}, sx)
|
|
34
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
35
|
+
d: path
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const paths = {
|
|
40
|
+
photo: "M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z",
|
|
41
|
+
close: "M18.3 5.71a.9959.9959 0 00-1.41 0L12 10.59 7.11 5.7a.9959.9959 0 00-1.41 0c-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const ImageUploadModal = _ref2 => {
|
|
45
|
+
let {
|
|
46
|
+
prevImage,
|
|
47
|
+
updateImage,
|
|
48
|
+
onClose,
|
|
49
|
+
title,
|
|
50
|
+
isCircularImage,
|
|
51
|
+
isSquareImage,
|
|
52
|
+
sizeInfo
|
|
53
|
+
} = _ref2;
|
|
54
|
+
const [image, setImage] = useState(prevImage);
|
|
55
|
+
const [zoom, setZoom] = useState(50);
|
|
56
|
+
const [loading, setLoading] = useState(false);
|
|
57
|
+
const [dropzoneHovered, setDropzoneHovered] = useState(false);
|
|
58
|
+
const size = useWindowSize();
|
|
59
|
+
const theme = useBlerpTheme();
|
|
60
|
+
const inputRef = useRef(null);
|
|
61
|
+
const imageEditorRef = /*#__PURE__*/createRef();
|
|
62
|
+
|
|
63
|
+
const urlToObject = async img => {
|
|
64
|
+
const response = await fetch(img);
|
|
65
|
+
const blob = await response.blob();
|
|
66
|
+
const file = new File([blob], img, {
|
|
67
|
+
type: blob.type
|
|
68
|
+
});
|
|
69
|
+
setImage(file);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (prevImage) urlToObject(prevImage);
|
|
74
|
+
}, [prevImage]);
|
|
75
|
+
|
|
76
|
+
const handleImageDrop = files => {
|
|
77
|
+
setImage(files[0]);
|
|
78
|
+
setDropzoneHovered(false);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleUploadClick = async () => {
|
|
82
|
+
if (!image) {
|
|
83
|
+
alert("You must upload a valid image");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (image.size > 8842038) {
|
|
88
|
+
alert("You must update with a valid image less then 7mb");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setLoading(true);
|
|
93
|
+
const canvas = imageEditorRef.current.getImage().toDataURL();
|
|
94
|
+
const blob = await (await fetch(canvas)).blob();
|
|
95
|
+
const file = new File([blob], image.name, {
|
|
96
|
+
type: image.type,
|
|
97
|
+
size: image.size
|
|
98
|
+
});
|
|
99
|
+
await updateImage(file);
|
|
100
|
+
setLoading(false);
|
|
101
|
+
onClose();
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return /*#__PURE__*/React.createElement(Stack, {
|
|
105
|
+
sx: {
|
|
106
|
+
minHeight: "580px"
|
|
107
|
+
},
|
|
108
|
+
alignItems: "center",
|
|
109
|
+
justifyContent: "space-between"
|
|
110
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
111
|
+
path: paths.close,
|
|
112
|
+
onClick: onClose,
|
|
113
|
+
sx: {
|
|
114
|
+
position: "absolute",
|
|
115
|
+
top: 20,
|
|
116
|
+
right: 20,
|
|
117
|
+
cursor: "pointer"
|
|
118
|
+
}
|
|
119
|
+
}), /*#__PURE__*/React.createElement(Stack, {
|
|
120
|
+
alignItems: "center"
|
|
121
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
122
|
+
sx: {
|
|
123
|
+
fontSize: "32px"
|
|
124
|
+
}
|
|
125
|
+
}, title), /*#__PURE__*/React.createElement(Text, {
|
|
126
|
+
color: "grey4"
|
|
127
|
+
}, "Adjust your image below."), /*#__PURE__*/React.createElement(Text, {
|
|
128
|
+
color: "grey4"
|
|
129
|
+
}, sizeInfo)), /*#__PURE__*/React.createElement(Stack, {
|
|
130
|
+
sx: {
|
|
131
|
+
minWidth: "300px",
|
|
132
|
+
backgroundColor: "waxwing.main",
|
|
133
|
+
maxHeight: "250px",
|
|
134
|
+
justifyContent: "center",
|
|
135
|
+
alignItems: "center"
|
|
136
|
+
}
|
|
137
|
+
}, !image ? /*#__PURE__*/React.createElement("div", {
|
|
138
|
+
style: {
|
|
139
|
+
width: "100%",
|
|
140
|
+
height: size.width > 600 ? "300px" : "200px",
|
|
141
|
+
cursor: "pointer",
|
|
142
|
+
display: "flex",
|
|
143
|
+
justifyContent: "center",
|
|
144
|
+
alignItems: "center"
|
|
145
|
+
},
|
|
146
|
+
onClick: () => {
|
|
147
|
+
var _inputRef$current;
|
|
148
|
+
|
|
149
|
+
return (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.click();
|
|
150
|
+
},
|
|
151
|
+
onDragOver: e => {
|
|
152
|
+
e.preventDefault();
|
|
153
|
+
setDropzoneHovered(true);
|
|
154
|
+
},
|
|
155
|
+
onDragLeave: () => setDropzoneHovered(false),
|
|
156
|
+
onDrop: e => {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
handleImageDrop(Array.from(e.dataTransfer.files));
|
|
159
|
+
}
|
|
160
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
161
|
+
ref: inputRef,
|
|
162
|
+
type: "file",
|
|
163
|
+
hidden: true,
|
|
164
|
+
accept: "image/*",
|
|
165
|
+
onChange: e => handleImageDrop(Array.from(e.target.files))
|
|
166
|
+
}), dropzoneHovered ? /*#__PURE__*/React.createElement(Icon, {
|
|
167
|
+
path: paths.photo,
|
|
168
|
+
size: "100%",
|
|
169
|
+
sx: {
|
|
170
|
+
color: "white"
|
|
171
|
+
}
|
|
172
|
+
}) : /*#__PURE__*/React.createElement(Text, {
|
|
173
|
+
sx: {
|
|
174
|
+
textAlign: "center",
|
|
175
|
+
width: "80%"
|
|
176
|
+
}
|
|
177
|
+
}, "Click or drop image here to upload.")) : image.type !== "image/gif" ? /*#__PURE__*/React.createElement(ImageEditor, {
|
|
178
|
+
ref: imageEditorRef,
|
|
179
|
+
width: !isCircularImage && !isSquareImage ? 650 : 250,
|
|
180
|
+
height: !isCircularImage && !isSquareImage ? 225 : 250,
|
|
181
|
+
borderRadius: isCircularImage ? 125 : 0,
|
|
182
|
+
image: image,
|
|
183
|
+
scale: zoom / 50,
|
|
184
|
+
crossOrigin: "anonymous"
|
|
185
|
+
}) : /*#__PURE__*/React.createElement("img", {
|
|
186
|
+
src: URL.createObjectURL(image),
|
|
187
|
+
width: "250px",
|
|
188
|
+
alt: "gif preview"
|
|
189
|
+
})), image && image.type !== "image/gif" && /*#__PURE__*/React.createElement(Stack, {
|
|
190
|
+
direction: "row",
|
|
191
|
+
width: "250px",
|
|
192
|
+
alignItems: "center"
|
|
193
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
194
|
+
component: "input",
|
|
195
|
+
type: "range",
|
|
196
|
+
min: "35",
|
|
197
|
+
max: "100",
|
|
198
|
+
value: zoom,
|
|
199
|
+
onChange: e => setZoom(e.target.value),
|
|
200
|
+
sx: {
|
|
201
|
+
width: "100%",
|
|
202
|
+
"&::-webkit-slider-thumb": {
|
|
203
|
+
background: theme.colors.ibisRed
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
})), /*#__PURE__*/React.createElement(Stack, {
|
|
207
|
+
alignItems: "center"
|
|
208
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
209
|
+
variant: "text",
|
|
210
|
+
onClick: () => setImage(null)
|
|
211
|
+
}, image ? "Change Image" : "Cancel"), /*#__PURE__*/React.createElement(Button, {
|
|
212
|
+
variant: "contained",
|
|
213
|
+
onClick: handleUploadClick
|
|
214
|
+
}, "Save Image")));
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export { ImageUploadModal as default };
|