@monygroupcorp/micro-web3 1.2.3 → 1.3.0
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/micro-web3.cjs +2 -2
- package/dist/micro-web3.cjs.map +1 -1
- package/dist/micro-web3.esm.js +2 -2
- package/dist/micro-web3.esm.js.map +1 -1
- package/dist/micro-web3.umd.js +2 -2
- package/dist/micro-web3.umd.js.map +1 -1
- package/package.json +2 -2
- package/src/components/BondingCurve/BondingCurve.js +80 -116
- package/src/components/Display/BalanceDisplay.js +37 -61
- package/src/components/Display/PriceDisplay.js +43 -71
- package/src/components/FloatingWalletButton/FloatingWalletButton.js +106 -151
- package/src/components/Ipfs/IpfsImage.js +83 -107
- package/src/components/Modal/ApprovalModal.js +92 -149
- package/src/components/SettingsModal/SettingsModal.js +364 -341
- package/src/components/Swap/SwapButton.js +9 -45
- package/src/components/Swap/SwapInputs.js +46 -108
- package/src/components/Swap/SwapInterface.js +216 -597
- package/src/components/Swap/TransactionOptions.js +70 -179
- package/src/components/SyncProgressBar/SyncProgressBar.js +183 -215
- package/src/components/Util/MessagePopup.js +26 -24
- package/src/components/Wallet/WalletModal.js +45 -44
- package/src/components/WalletButton/WalletButton.js +193 -185
- package/src/services/WalletService.js +53 -20
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Component } from '@monygroupcorp/microact';
|
|
1
|
+
import { Component, h } from '@monygroupcorp/microact';
|
|
2
2
|
import { isIpfsUri, resolveIpfsToHttp, getAvailableGateways } from '../../services/IpfsService.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* IpfsImage Component
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* Renders images with IPFS support, including gateway rotation on failure.
|
|
8
8
|
* Falls back gracefully if all gateways fail.
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* Props:
|
|
11
11
|
* - src: Image URL (HTTP or IPFS)
|
|
12
12
|
* - alt: Alt text for image
|
|
@@ -20,41 +20,35 @@ import { isIpfsUri, resolveIpfsToHttp, getAvailableGateways } from '../../servic
|
|
|
20
20
|
*/
|
|
21
21
|
export class IpfsImage extends Component {
|
|
22
22
|
constructor(props = {}) {
|
|
23
|
-
super();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// State for gateway rotation and loading
|
|
27
|
-
this.setState({
|
|
23
|
+
super(props);
|
|
24
|
+
|
|
25
|
+
this.state = {
|
|
28
26
|
gatewayIndex: 0,
|
|
29
27
|
isLoading: true,
|
|
30
28
|
hasError: false,
|
|
31
29
|
currentSrc: null
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Bind methods
|
|
35
|
-
this.handleImageLoad = this.handleImageLoad.bind(this);
|
|
36
|
-
this.handleImageError = this.handleImageError.bind(this);
|
|
30
|
+
};
|
|
37
31
|
}
|
|
38
|
-
|
|
32
|
+
|
|
39
33
|
/**
|
|
40
34
|
* Get current HTTP URL based on src and gateway index
|
|
41
35
|
*/
|
|
42
36
|
getCurrentUrl() {
|
|
43
37
|
const { src } = this.props;
|
|
44
|
-
|
|
38
|
+
|
|
45
39
|
if (!src) {
|
|
46
40
|
return null;
|
|
47
41
|
}
|
|
48
|
-
|
|
42
|
+
|
|
49
43
|
// If not IPFS, return as-is
|
|
50
44
|
if (!isIpfsUri(src)) {
|
|
51
45
|
return src;
|
|
52
46
|
}
|
|
53
|
-
|
|
47
|
+
|
|
54
48
|
// Resolve IPFS to HTTP using current gateway
|
|
55
49
|
return resolveIpfsToHttp(src, this.state.gatewayIndex);
|
|
56
50
|
}
|
|
57
|
-
|
|
51
|
+
|
|
58
52
|
/**
|
|
59
53
|
* Handle successful image load
|
|
60
54
|
*/
|
|
@@ -63,143 +57,126 @@ export class IpfsImage extends Component {
|
|
|
63
57
|
isLoading: false,
|
|
64
58
|
hasError: false
|
|
65
59
|
});
|
|
66
|
-
|
|
60
|
+
|
|
67
61
|
// Call user's onLoad callback if provided
|
|
68
62
|
if (this.props.onLoad) {
|
|
69
63
|
this.props.onLoad(event);
|
|
70
64
|
}
|
|
71
65
|
}
|
|
72
|
-
|
|
66
|
+
|
|
73
67
|
/**
|
|
74
68
|
* Handle image load error - try next gateway
|
|
75
69
|
*/
|
|
76
70
|
handleImageError(event) {
|
|
77
71
|
const gateways = getAvailableGateways();
|
|
78
72
|
const { src } = this.props;
|
|
79
|
-
|
|
73
|
+
|
|
80
74
|
// If not IPFS or out of gateways, show error
|
|
81
75
|
if (!isIpfsUri(src) || this.state.gatewayIndex >= gateways.length - 1) {
|
|
82
76
|
this.setState({
|
|
83
77
|
isLoading: false,
|
|
84
78
|
hasError: true
|
|
85
79
|
});
|
|
86
|
-
|
|
80
|
+
|
|
87
81
|
// Log error for debugging
|
|
88
82
|
console.error('[IpfsImage] Failed to load image:', src, {
|
|
89
83
|
triedGateways: this.state.gatewayIndex + 1,
|
|
90
84
|
totalGateways: gateways.length
|
|
91
85
|
});
|
|
92
|
-
|
|
86
|
+
|
|
93
87
|
// Call user's onError callback if provided
|
|
94
88
|
if (this.props.onError) {
|
|
95
89
|
this.props.onError(event);
|
|
96
90
|
}
|
|
97
|
-
|
|
91
|
+
|
|
98
92
|
return;
|
|
99
93
|
}
|
|
100
|
-
|
|
94
|
+
|
|
101
95
|
// Try next gateway
|
|
102
96
|
const nextIndex = this.state.gatewayIndex + 1;
|
|
103
97
|
this.setState({
|
|
104
98
|
gatewayIndex: nextIndex
|
|
105
99
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Convert style object to CSS style object for h()
|
|
104
|
+
*/
|
|
105
|
+
normalizeStyle(style) {
|
|
106
|
+
if (!style || typeof style !== 'object') {
|
|
107
|
+
return {};
|
|
114
108
|
}
|
|
109
|
+
return style;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Escape HTML for safe rendering in attributes
|
|
114
|
+
*/
|
|
115
|
+
escapeHtml(text) {
|
|
116
|
+
if (!text) return '';
|
|
117
|
+
const div = document.createElement('div');
|
|
118
|
+
div.textContent = text;
|
|
119
|
+
return div.innerHTML;
|
|
115
120
|
}
|
|
116
|
-
|
|
121
|
+
|
|
117
122
|
/**
|
|
118
123
|
* Render component
|
|
119
124
|
*/
|
|
120
125
|
render() {
|
|
121
|
-
const {
|
|
122
|
-
src,
|
|
123
|
-
alt = '',
|
|
124
|
-
className = '',
|
|
126
|
+
const {
|
|
127
|
+
src,
|
|
128
|
+
alt = '',
|
|
129
|
+
className = '',
|
|
125
130
|
style = {},
|
|
126
131
|
loading = 'lazy',
|
|
127
132
|
placeholder,
|
|
128
133
|
errorPlaceholder
|
|
129
134
|
} = this.props;
|
|
130
|
-
|
|
135
|
+
|
|
131
136
|
const { isLoading, hasError } = this.state;
|
|
132
|
-
|
|
137
|
+
|
|
133
138
|
if (!src) {
|
|
134
|
-
return '
|
|
139
|
+
return h('div', { className: 'ipfs-image-empty' });
|
|
135
140
|
}
|
|
136
|
-
|
|
141
|
+
|
|
137
142
|
const currentUrl = this.getCurrentUrl();
|
|
138
|
-
|
|
143
|
+
|
|
139
144
|
// Error state - show placeholder
|
|
140
145
|
if (hasError) {
|
|
141
146
|
if (errorPlaceholder) {
|
|
142
147
|
return errorPlaceholder;
|
|
143
148
|
}
|
|
144
|
-
|
|
149
|
+
|
|
145
150
|
// Default error placeholder
|
|
146
|
-
return
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
return h('div', {
|
|
152
|
+
className: `ipfs-image-error ${className}`,
|
|
153
|
+
style: this.normalizeStyle(style)
|
|
154
|
+
},
|
|
155
|
+
h('div', { className: 'ipfs-image-error-icon' }, '\u26A0\uFE0F'),
|
|
156
|
+
h('div', { className: 'ipfs-image-error-text' }, 'IPFS image unavailable')
|
|
157
|
+
);
|
|
152
158
|
}
|
|
153
|
-
|
|
159
|
+
|
|
154
160
|
// Loading or loaded state - show image
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
mount(element) {
|
|
173
|
-
super.mount(element);
|
|
174
|
-
|
|
175
|
-
// Attach load/error handlers to img element
|
|
176
|
-
const img = this.element?.querySelector('img');
|
|
177
|
-
if (img) {
|
|
178
|
-
img.addEventListener('load', this.handleImageLoad);
|
|
179
|
-
img.addEventListener('error', this.handleImageError);
|
|
180
|
-
|
|
181
|
-
// Register cleanup
|
|
182
|
-
this.registerCleanup(() => {
|
|
183
|
-
img.removeEventListener('load', this.handleImageLoad);
|
|
184
|
-
img.removeEventListener('error', this.handleImageError);
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Convert style object to string
|
|
191
|
-
*/
|
|
192
|
-
styleToString(style) {
|
|
193
|
-
if (!style || typeof style !== 'object') {
|
|
194
|
-
return '';
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return Object.entries(style)
|
|
198
|
-
.map(([key, value]) => {
|
|
199
|
-
const cssKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
200
|
-
return `${cssKey}: ${value};`;
|
|
161
|
+
const imageStyle = isLoading
|
|
162
|
+
? { opacity: 0 }
|
|
163
|
+
: { opacity: 1, transition: 'opacity 0.3s' };
|
|
164
|
+
|
|
165
|
+
return h('div', {
|
|
166
|
+
className: `ipfs-image-container ${className}`,
|
|
167
|
+
style: this.normalizeStyle(style)
|
|
168
|
+
},
|
|
169
|
+
isLoading && placeholder,
|
|
170
|
+
h('img', {
|
|
171
|
+
src: currentUrl || '',
|
|
172
|
+
alt: alt,
|
|
173
|
+
loading: loading,
|
|
174
|
+
className: `ipfs-image ${isLoading ? 'ipfs-image-loading' : 'ipfs-image-loaded'}`,
|
|
175
|
+
style: imageStyle,
|
|
176
|
+
onLoad: this.bind(this.handleImageLoad),
|
|
177
|
+
onError: this.bind(this.handleImageError)
|
|
201
178
|
})
|
|
202
|
-
|
|
179
|
+
);
|
|
203
180
|
}
|
|
204
181
|
}
|
|
205
182
|
|
|
@@ -211,23 +188,23 @@ IpfsImage.styles = `
|
|
|
211
188
|
width: 100%;
|
|
212
189
|
height: 100%;
|
|
213
190
|
}
|
|
214
|
-
|
|
191
|
+
|
|
215
192
|
.ipfs-image {
|
|
216
193
|
display: block;
|
|
217
194
|
width: 100%;
|
|
218
195
|
height: 100%;
|
|
219
196
|
object-fit: cover;
|
|
220
197
|
}
|
|
221
|
-
|
|
198
|
+
|
|
222
199
|
.ipfs-image-loading {
|
|
223
200
|
opacity: 0;
|
|
224
201
|
}
|
|
225
|
-
|
|
202
|
+
|
|
226
203
|
.ipfs-image-loaded {
|
|
227
204
|
opacity: 1;
|
|
228
205
|
transition: opacity 0.3s ease-in;
|
|
229
206
|
}
|
|
230
|
-
|
|
207
|
+
|
|
231
208
|
.ipfs-image-error {
|
|
232
209
|
display: flex;
|
|
233
210
|
flex-direction: column;
|
|
@@ -239,27 +216,26 @@ IpfsImage.styles = `
|
|
|
239
216
|
padding: 1rem;
|
|
240
217
|
text-align: center;
|
|
241
218
|
}
|
|
242
|
-
|
|
219
|
+
|
|
243
220
|
.ipfs-image-error-icon {
|
|
244
221
|
font-size: 2rem;
|
|
245
222
|
margin-bottom: 0.5rem;
|
|
246
223
|
}
|
|
247
|
-
|
|
224
|
+
|
|
248
225
|
.ipfs-image-error-text {
|
|
249
226
|
font-size: 0.875rem;
|
|
250
227
|
}
|
|
251
|
-
|
|
228
|
+
|
|
252
229
|
.ipfs-image-empty {
|
|
253
230
|
display: block;
|
|
254
231
|
width: 100%;
|
|
255
232
|
height: 100%;
|
|
256
233
|
background-color: transparent;
|
|
257
234
|
}
|
|
258
|
-
|
|
235
|
+
|
|
259
236
|
/* Dark mode support */
|
|
260
237
|
html[data-theme='dark'] .ipfs-image-error {
|
|
261
238
|
background-color: #2a2a2a;
|
|
262
239
|
color: #aaa;
|
|
263
240
|
}
|
|
264
241
|
`;
|
|
265
|
-
|