Event handling with the Upload files flow function
How to get and use the data from events sent by the Upload files flow function.

Setup the receive event logic node to get the event's data

To use any custom event that is triggered from a flow function, you need to add a Receive event logic node to the logic canvas, then select Advanced custom event from the dropdown menu on the right hand side of the screen. After selecting it, there should be an popup that asks for the name of the event. In this case, it is onFileUploadProgress. You should also name your event node to something descriptive, like "On file upload progress".

How to store the data from the event

After you have setup the Receive event logic node, we'll use a variable to store the data from the latest event, so we can e.g. use it as basis for a progress bar or similar.
Currently there is no easy way to know what the event object has inside it, so it is easier to use Any value type as the variable type, to prevent incompatible schemas. Alternatively, you can make the variable have the same schema as the event object – the schema for the file upload event is described below. After you have the variable setup, you can set its value to be the output of the Receive event node, by using the Set app variable or Set page variable flow functions, depending on which one you chose. In your flow function, set the binding type of Assigned value to be a formula, and then set the formula's value to be outputs["On file upload progress"].event.
This way, we get the whole event object assigned to the variable.
Schema for the event object:
jobId: Number // Describes the unique job ID, useful if you have multiple concurrent file uploads ongoing
totalSize: Number // Total size of all the files to be uploaded in bytes
bytesUploaded: Number // Total bytes uploaded
files: List of Files // List of files being uploaded, if you want to track individual progress
Schema for the File object:
mimeType: Text // MIME type of the uploaded file
name: Text // Filename of the uploaded file
size: Number // Size in bytes of the uploaded file
storageKey: Text // Unique storage key, used when uploading to AppGyver-managed S3
bytesUploaded: Number // Bytes uploaded for this file
uploadStatus: Text // Either 'pending', 'uploading', 'completed' or 'errored'

Reading the data

Now that you have the event object stored inside a variable, you can use it like any other variable that you might have.
If you didn't define the explicit schema though, Composer doesn't know the fields that are available, and trying to e.g. use a formula like pageVars.uploadEvent.bytesUploaded can cause Composer to complain about mismatching schema, even though the actual data is correct.
You can for e.g. use a paragraph to see what's inside of the variable that you stored the event in, by binding the paragraph's Content field to a formula function and setting the formula function to be ENCODE_JSON(pageVars.yourVarName).
Now if you upload something, you can see the variable contents change as new events arrive and change its value.

Upload percentage

If you take the bytesUploaded and divide it by the totalSize of the files that you are uploading, and then you multiply that by 100, and you get a 0-100 number that represents the percentages of files uploaded.
For that equation the formula function would look something like this ROUND(NUMBER(pageVars.yourVarName.bytesUploaded) / NUMBER(pageVars.yourVarName.totalSize) * 100)
You need to remember that if you do use a variable with type Any value, the formula editor does not know what your variable has inside of it, so it can't automatically show you what fields your variable has inside of it, but you can always check the documentation!