Gitea-Fix
Dieser Commit ist enthalten in:
@ -884,6 +884,99 @@ class ApiClient {
|
||||
async serverGitCheckout(branch) {
|
||||
return this.post('/git/server/checkout', { branch });
|
||||
}
|
||||
|
||||
// =====================
|
||||
// BROWSER-UPLOAD ENDPOINTS
|
||||
// =====================
|
||||
|
||||
async prepareBrowserUpload() {
|
||||
return this.post('/git/browser-upload-prepare', {});
|
||||
}
|
||||
|
||||
async cancelBrowserUpload(sessionId) {
|
||||
return this.delete(`/git/browser-upload/${sessionId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt Dateien vom Browser hoch und pusht sie ins Gitea
|
||||
* @param {Object} options - Upload-Optionen
|
||||
* @param {File[]} options.files - Array von File-Objekten mit relativePath Property
|
||||
* @param {string} options.repoUrl - Gitea Repository URL
|
||||
* @param {string} options.branch - Ziel-Branch
|
||||
* @param {string} options.commitMessage - Commit-Nachricht
|
||||
* @param {string} options.sessionId - Session-ID vom prepare-Aufruf
|
||||
* @param {Function} options.onProgress - Progress-Callback (optional)
|
||||
*/
|
||||
async browserUploadAndPush(options) {
|
||||
const { files, repoUrl, branch, commitMessage, sessionId, onProgress } = options;
|
||||
|
||||
const url = `${this.baseUrl}/git/browser-upload`;
|
||||
const formData = new FormData();
|
||||
|
||||
// Metadaten hinzufügen
|
||||
formData.append('repoUrl', repoUrl);
|
||||
formData.append('branch', branch || 'main');
|
||||
formData.append('commitMessage', commitMessage);
|
||||
formData.append('sessionId', sessionId);
|
||||
|
||||
// Dateien hinzufügen (mit relativem Pfad als Dateiname)
|
||||
files.forEach(fileInfo => {
|
||||
// Erstelle neues File-Objekt mit relativem Pfad als Namen
|
||||
const file = new File([fileInfo.file], fileInfo.relativePath, {
|
||||
type: fileInfo.file.type
|
||||
});
|
||||
formData.append('files', file);
|
||||
});
|
||||
|
||||
const token = this.getToken();
|
||||
const csrfToken = this.getCsrfToken();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('POST', url);
|
||||
|
||||
if (token) {
|
||||
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
|
||||
}
|
||||
|
||||
if (csrfToken) {
|
||||
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
|
||||
}
|
||||
|
||||
if (onProgress) {
|
||||
xhr.upload.addEventListener('progress', (e) => {
|
||||
if (e.lengthComputable) {
|
||||
const percentage = Math.round((e.loaded / e.total) * 100);
|
||||
onProgress(percentage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
xhr.addEventListener('load', () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
try {
|
||||
resolve(JSON.parse(xhr.responseText));
|
||||
} catch {
|
||||
resolve({ success: true });
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const error = JSON.parse(xhr.responseText);
|
||||
reject(new Error(error.error || 'Upload fehlgeschlagen'));
|
||||
} catch {
|
||||
reject(new Error('Upload fehlgeschlagen'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('error', () => {
|
||||
reject(new Error('Netzwerkfehler beim Upload'));
|
||||
});
|
||||
|
||||
xhr.send(formData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Custom API Error Class
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren