@roeehrl/tinode-sdk 0.25.1-sqlite.10 → 0.25.1-sqlite.11
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/package.json +1 -1
- package/src/large-file.native.js +81 -79
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roeehrl/tinode-sdk",
|
|
3
3
|
"description": "Tinode SDK fork with Storage interface for SQLite persistence in React Native",
|
|
4
|
-
"version": "0.25.1-sqlite.
|
|
4
|
+
"version": "0.25.1-sqlite.11",
|
|
5
5
|
"types": "./types/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"format": "js-beautify -r src/*.js",
|
package/src/large-file.native.js
CHANGED
|
@@ -112,21 +112,30 @@ export default class LargeFileHelperNative {
|
|
|
112
112
|
const url = this._buildUploadUrl(baseUrl);
|
|
113
113
|
const headers = this._buildHeaders();
|
|
114
114
|
|
|
115
|
+
// Log upload details
|
|
116
|
+
this._tinode.logger("Starting upload to:", url);
|
|
117
|
+
this._tinode.logger("Upload file:", { uri, filename, mimetype, size });
|
|
118
|
+
|
|
115
119
|
// Create AbortController for cancellation
|
|
116
120
|
const abortController = new AbortController();
|
|
117
121
|
this._abortControllers.push(abortController);
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
// Use fetch instead of XHR - React Native XHR has issues with FormData uploads
|
|
124
|
+
// where the response body is not accessible. Fetch works correctly.
|
|
125
|
+
// Note: We lose upload progress tracking with fetch, but the upload works.
|
|
126
|
+
return (async () => {
|
|
120
127
|
try {
|
|
121
128
|
// Build FormData with file URI (React Native specific)
|
|
122
129
|
const formData = new FormData();
|
|
123
130
|
|
|
124
131
|
// React Native FormData accepts objects with uri, type, and name
|
|
125
|
-
|
|
132
|
+
const fileObj = {
|
|
126
133
|
uri: uri,
|
|
127
134
|
type: mimetype,
|
|
128
135
|
name: filename,
|
|
129
|
-
}
|
|
136
|
+
};
|
|
137
|
+
instance._tinode.logger("FormData file object:", fileObj);
|
|
138
|
+
formData.append('file', fileObj);
|
|
130
139
|
|
|
131
140
|
formData.append('id', this._tinode.getNextUniqueId());
|
|
132
141
|
|
|
@@ -134,103 +143,96 @@ export default class LargeFileHelperNative {
|
|
|
134
143
|
formData.append('topic', avatarFor);
|
|
135
144
|
}
|
|
136
145
|
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
|
|
146
|
+
// Signal progress start (we can't track actual progress with fetch)
|
|
147
|
+
if (onProgress) {
|
|
148
|
+
onProgress(0.1); // Indicate upload started
|
|
149
|
+
}
|
|
150
|
+
if (instance.onProgress) {
|
|
151
|
+
instance.onProgress(0.1);
|
|
152
|
+
}
|
|
140
153
|
|
|
141
|
-
|
|
154
|
+
instance._tinode.logger("Sending fetch request...");
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
156
|
+
const response = await fetch(url, {
|
|
157
|
+
method: 'POST',
|
|
158
|
+
headers: headers,
|
|
159
|
+
body: formData,
|
|
160
|
+
signal: abortController.signal,
|
|
146
161
|
});
|
|
147
162
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
163
|
+
instance._tinode.logger("Fetch response:", {
|
|
164
|
+
status: response.status,
|
|
165
|
+
statusText: response.statusText,
|
|
166
|
+
ok: response.ok,
|
|
151
167
|
});
|
|
152
168
|
|
|
153
|
-
//
|
|
154
|
-
if (onProgress
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
// Signal progress near completion
|
|
170
|
+
if (onProgress) {
|
|
171
|
+
onProgress(0.9);
|
|
172
|
+
}
|
|
173
|
+
if (instance.onProgress) {
|
|
174
|
+
instance.onProgress(0.9);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const responseText = await response.text();
|
|
178
|
+
instance._tinode.logger("Response text:", responseText.substring(0, 200));
|
|
179
|
+
|
|
180
|
+
let pkt;
|
|
181
|
+
try {
|
|
182
|
+
pkt = JSON.parse(responseText);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
instance._tinode.logger("ERROR: Failed to parse server response:", responseText);
|
|
185
|
+
pkt = {
|
|
186
|
+
ctrl: {
|
|
187
|
+
code: response.status,
|
|
188
|
+
text: response.statusText || 'Unknown error'
|
|
173
189
|
}
|
|
174
190
|
};
|
|
175
191
|
}
|
|
176
192
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
ctrl: {
|
|
185
|
-
code: this.status,
|
|
186
|
-
text: this.statusText
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
}
|
|
193
|
+
// Signal completion
|
|
194
|
+
if (onProgress) {
|
|
195
|
+
onProgress(1);
|
|
196
|
+
}
|
|
197
|
+
if (instance.onProgress) {
|
|
198
|
+
instance.onProgress(1);
|
|
199
|
+
}
|
|
190
200
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
} else if (this.status >= 400) {
|
|
198
|
-
const error = new CommError(pkt.ctrl.text, pkt.ctrl.code);
|
|
199
|
-
reject(error);
|
|
200
|
-
if (onFailure) {
|
|
201
|
-
onFailure(pkt.ctrl);
|
|
202
|
-
}
|
|
203
|
-
} else {
|
|
204
|
-
instance._tinode.logger("ERROR: Unexpected server response status", this.status, this.response);
|
|
205
|
-
reject(new Error(`Unexpected status: ${this.status}`));
|
|
201
|
+
if (response.ok && pkt.ctrl && pkt.ctrl.params && pkt.ctrl.params.url) {
|
|
202
|
+
const uploadUrl = pkt.ctrl.params.url;
|
|
203
|
+
instance._tinode.logger("Upload success, URL:", uploadUrl);
|
|
204
|
+
if (onSuccess) {
|
|
205
|
+
onSuccess(pkt.ctrl);
|
|
206
206
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const
|
|
211
|
-
|
|
207
|
+
return uploadUrl;
|
|
208
|
+
} else if (response.status >= 400) {
|
|
209
|
+
const errorCode = pkt.ctrl?.code || response.status;
|
|
210
|
+
const errorText = pkt.ctrl?.text || 'Upload failed';
|
|
211
|
+
instance._tinode.logger("Upload error:", errorCode, errorText);
|
|
212
|
+
const error = new CommError(errorText, errorCode);
|
|
212
213
|
if (onFailure) {
|
|
213
|
-
onFailure(
|
|
214
|
+
onFailure(pkt.ctrl);
|
|
214
215
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
throw error;
|
|
217
|
+
} else {
|
|
218
|
+
instance._tinode.logger("ERROR: Unexpected response - status:", response.status, "response:", responseText);
|
|
219
|
+
throw new Error(`Unexpected status: ${response.status}, response: ${responseText ? responseText.substring(0, 100) : 'empty'}`);
|
|
220
|
+
}
|
|
221
|
+
} catch (err) {
|
|
222
|
+
if (err.name === 'AbortError') {
|
|
223
|
+
instance._tinode.logger("Upload aborted");
|
|
220
224
|
if (onFailure) {
|
|
221
225
|
onFailure(null);
|
|
222
226
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
} catch (err) {
|
|
228
|
-
reject(err);
|
|
227
|
+
throw new Error("Upload cancelled by user");
|
|
228
|
+
}
|
|
229
|
+
instance._tinode.logger("Upload error:", err.message);
|
|
229
230
|
if (onFailure) {
|
|
230
231
|
onFailure(null);
|
|
231
232
|
}
|
|
233
|
+
throw err;
|
|
232
234
|
}
|
|
233
|
-
});
|
|
235
|
+
})();
|
|
234
236
|
}
|
|
235
237
|
|
|
236
238
|
/**
|