contentful / create-contentful-app

Bootstrap a Contentful App
https://contentful.com/developers/docs/extensibility/app-framework/create-contentful-app/
MIT License
107 stars 24 forks source link

Impossible to monitor file upload progress using sdk.cma.upload #1882

Open brootle opened 8 months ago

brootle commented 8 months ago

I currently have a problem that I have no way to monitor file upload when using sdk.cma.upload The only available methods are these

upload: {
    get(params: OptionalDefaults<GetSpaceParams & {
        uploadId: string;
    }>): Promise<any>;
    create(params: OptionalDefaults<GetSpaceParams>, data: {
        file: string | ArrayBuffer | Stream;
    }): Promise<any>;
    delete(params: OptionalDefaults<GetSpaceParams & {
        uploadId: string;
    }>): Promise<any>;
};
brootle commented 8 months ago

I had to use API directly, the downside is that I need to get CMA token from the user for this to work. You can get CMA token from a user during your app installation for example. Contentful SDK doesn't have a method to get access token which it is using to sign all the requests.

  async function customUploadMethod(file, accessToken, spaceId, environmentId, onProgress) {
    // Define the URL for Contentful's upload API
    const uploadUrl = `https://upload.contentful.com/spaces/${spaceId}/uploads`;

    // Use XMLHttpRequest for upload to listen to progress events
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.open('POST', uploadUrl, true);

      // Set the Authorization header with the access token
      xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`);

      // Set the Content-Type header to application/octet-stream
      xhr.setRequestHeader('Content-Type', 'application/octet-stream');

      // Listen for progress events
      xhr.upload.onprogress = function(event) {
        if (event.lengthComputable) {
          let percentComplete = (event.loaded / event.total) * 100;
          let roundedPercentComplete = Math.round(percentComplete);
          console.log(`Upload progress: ${roundedPercentComplete}%`);
          onProgress(roundedPercentComplete); // Call the onProgress callback with the progress percentage
        }
      };

      // Handle the response
      xhr.onload = function() {
        if (xhr.status >= 200 && xhr.status < 300) {
          // Parse the JSON response
          const response = JSON.parse(xhr.responseText);
          resolve(response);
        } else {
          reject(new Error('Upload failed with status: ' + xhr.status));
        }
      };

      // Handle network errors
      xhr.onerror = function() {
        reject(new Error('Network error occurred during upload'));
      };

      // Send the request with the file data directly
      xhr.send(file);
    });
  }