Progressbar
Advanced Progress Bar for RedM
1. Introduction
cas-progressbar is a modern, NUI-based progress bar system for RedM.
It is built with a React + TypeScript frontend and a lightweight Lua client, designed to be:
Easy to integrate in any script
Highly configurable (label, duration, position, color, icon)
Visually polished with smooth animations
Flexible enough to attach props and play animations while the action runs
2. Features Overview
Clean, animated NUI progress bar
Duration-based percentage fill
Custom text label
Custom color
Icon support (React Icons, Fa6)
Multiple screen positions (top, center, bottom, left/right combos)
Cancel support via key (default H)
Optional control disabling:
Movement
Vehicle movement
Mouse look
Combat
Optional animation playback:
Scenario-based
AnimDict + Anim
Optional prop attaching to the player
Locale support (EN, FR included)
Simple debug test command (
/testprogressbar)Export-based API and event-based API
“Busy” state helper function
3. Requirements
RedM
Game build supporting NUI
Any framework (or no framework).
4. Installation
4.1. Resource setup
Place the folder in your resources directory:
In
server.cfg:
There is no server-side Lua for this resource. Everything runs on the client (plus NUI).
5. Configuration
All configuration is done on the client side in the config folder.
5.1. config/client_config.lua
config/client_config.luaFields:
escapeKey.labelText shown in the UI as the cancel hint (for example “H to Cancel”).escapeKey.idControl hash used as cancel key. Default is0x24978A28(mapped to H in the included locale: “H to Cancel”).debugWhentrue, enables the/testprogressbarcommand.Notify(optional, function) If you uncomment and define this, all internal notifications will use your custom function:
5.2. config/locale.lua
config/locale.luaLocaleActive language code, e.g."en"or"fr".Locales[...]Per-language text table.
Keys used:
escapeText rendered in the top-right of the progress bar (“H to Cancel” etc.).cancelledText shown when the progress bar is stopped/cancelled.
To add a new language:
Then set:
Icons
Icons are taken from the react-icons Font Awesome 6 set. Browse icons on the React Icons website and use their exact component names (e.g. FaSmoking, FaHammer) as the icon value.
https://react-icons.github.io/react-icons/icons/fa6/
6. How It Works (Client Logic)
The core logic is in client/client.lua.
Important points:
toggleNuiFrame(shouldShow)Manages focus and visibility of the NUI.StartProgress(action, onStart, onTick, onFinish)Internal function that:Validates action options
Applies animations and props
Sends the progress configuration to NUI
Starts a loop that:
Disables controls when requested
Handles cancel key
Calls callbacks
Waits for NUI to finish the action
ActionCleanup()Resets internal state, stops animations, deletes prop, and clears “busy” state.NUI communication:
SendReactMessage('setVisible', true/false)Show/hide UI.SendReactMessage('setProgress', { timer, text, icon, color, position })Configure and start the bar.RegisterNUICallback("FinishAction", ...)Called from NUI when the bar reaches 100%.SendNUIMessage({ action = "stopAction" })Stops the bar and shows “cancelled” message.
Locale + Config injection to NUI:
RegisterNUICallback("cas_progressbar:getLocaleAndConfig", ...)NUI calls this once at load. It returns:
7. Public API
You can use the script in two main ways:
Using the exported function
Using client events
7.1. Export: Progress(action, finishCallback)
Progress(action, finishCallback)From another client script:
The finishCallback(cancelled) parameter receives a boolean:
trueif the player cancelled (with cancel key)falseif the action completed fully
7.2. Export: isDoingSomething()
isDoingSomething()You can check if a progress bar is currently active:
7.3. Events
The script also exposes events:
Start progress (event)
This does exactly the same as calling the export.
Cancel progress (event)
This will cancel any current progress, clean up, and tell NUI to stop.
Toggle busyness flag (event)
Normally you do not need to call this directly, because the script maintains it internally, but it is available if you want to integrate it with other systems.
8. Action Object Reference
Below is a full reference of the action table fields accepted by the script.
Field descriptions:
name(string) Internal name for the action. Can be anything.duration(number, ms) How long the bar should run, in milliseconds. Example:5000= 5 seconds.label(string) Text displayed in the progress bar as the action title.canCancel(bool, default: true) Whether the player can cancel with the cancel key.useWhileDead(bool, default: false) If false and the player is dead, the action will immediately cancel.useWhileMounted(bool, default: true) If false and the player is on a mount/horse/vehicle, the action will immediately cancel.cancelKey(number, control hash) Control used to cancel (default:Config.escapeKey.id).controlDisables(table, optional)disableMovement(bool)disableVehicleMovement(bool)disableMouse(bool)disableCombat(bool)
The script calls
DisableControlActionfor multiple control hashes depending on these flags, effectively freezing movement/combat while the bar is active.animation(table, optional)Option 1:
scenario = "WORLD_HUMAN_SMOKE_CARRYING"UsesTaskStartScenarioInPlaceHash.Option 2:
The script requests the dict, waits for it to load, then plays the animation.
prop(table, optional)model: model name or hash (string or number)bone: bone index to attach topos: offset table{x, y, z}rot: rotation table{x, y, z}
The script loads the model, creates the object, and attaches it to the player. On cleanup, it deletes the object.
icon(string, optional) Icon name fromreact-icons/fa6. Example:"FaSmoking","FaHammer","FaWrench". If empty or not found, no icon is shown.color(string, optional) Progress bar color (hex). Default is"#A78E77".position(string, optional) Where to show the bar on screen. Supported values include:"top","top-center""top-left","top-right""center","middle""left","center-left""right","center-right"Any other value defaults to bottom-center style.
onStart(function, optional) Called once when the progress begins.onTick(function, optional) Called every frame while progress is active.onFinish(cancelled)(function, optional) Called when the action ends (either finished or cancelled). Receivescancelledboolean.
Note: you can also use the finish callback passed into Progress(action, finish). Both are supported; they will be called one after another.
9. NUI Behavior
The frontend (React) handles:
Displaying and hiding the progress container
Animating the progress bar from 0 to 100 based on
timerShowing the label/title text
Showing the percentage text
Showing the cancel hint using
locale.escapeDisplaying the icon if provided
Applying the color and position options
Calling
FinishAction(NUI callback) when it reaches 100%, which triggersActionCleanup()on the Lua side.
When the Lua side sends stopAction, NUI:
Shows the
locale.cancelledtextResets the progress
Fades the bar out
10. Debug / Test Command
If Config.debug = true, the script registers:
This command:
Builds a sample
action:Duration: 5000 ms
Label: "Preparing the smoke"
Animation: smoking scenario
Prop: cigarette model attached to the hand
Icon:
FaSmokingColor:
#A78E77Position:
bottom-center
Calls
Progress(action, callback)Uses
exports['cas-notification']:addNotificationin the callback as a sample integration for success/cancel messages.
You can use this to visually test that NUI is working.
11. Troubleshooting
Progress bar does not appear
Check that the resource is started:
ensure cas-progressbarMake sure the UI files built correctly (the
web/buildfolder exists).Ensure there is no other NUI resource blocking focus.
Try the debug command
/testprogressbarwithConfig.debug = true.
Cancel key does not work
Confirm
Config.escapeKey.idmatches the desired control hash.Check
Config.escapeKey.labelandLocales[Locale].escapetext to ensure consistency.
Notifications not appearing
If you rely on your own notify system, make sure
Config.Notifyis defined.
Multiple actions at the same time
The script tracks
inprogressinternally and prevents starting a new action while one is active.Use
exports["cas-progressbar"]:isDoingSomething()to safely check before starting a new action.
12. Credits
Script:
cas-progressbarAuthor: Code After S*x
UI: React + TypeScript + Tailwind + Framer Motion
Game support: RedM
Last updated