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

  1. Place the folder in your resources directory:

  2. 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

Fields:

  • escapeKey.label Text shown in the UI as the cancel hint (for example “H to Cancel”).

  • escapeKey.id Control hash used as cancel key. Default is 0x24978A28 (mapped to H in the included locale: “H to Cancel”).

  • debug When true, enables the /testprogressbar command.

  • Notify (optional, function) If you uncomment and define this, all internal notifications will use your custom function:


5.2. config/locale.lua

  • Locale Active language code, e.g. "en" or "fr".

  • Locales[...] Per-language text table.

Keys used:

  • escape Text rendered in the top-right of the progress bar (“H to Cancel” etc.).

  • cancelled Text 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:

  1. Using the exported function

  2. Using client events

7.1. Export: Progress(action, finishCallback)

From another client script:

The finishCallback(cancelled) parameter receives a boolean:

  • true if the player cancelled (with cancel key)

  • false if the action completed fully


7.2. Export: 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 DisableControlAction for 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" Uses TaskStartScenarioInPlaceHash.

    • 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 to

    • pos: 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 from react-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). Receives cancelled boolean.

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 timer

  • Showing the label/title text

  • Showing the percentage text

  • Showing the cancel hint using locale.escape

  • Displaying the icon if provided

  • Applying the color and position options

  • Calling FinishAction (NUI callback) when it reaches 100%, which triggers ActionCleanup() on the Lua side.

When the Lua side sends stopAction, NUI:

  • Shows the locale.cancelled text

  • Resets 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: FaSmoking

    • Color: #A78E77

    • Position: bottom-center

  • Calls Progress(action, callback)

  • Uses exports['cas-notification']:addNotification in 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-progressbar

  • Make sure the UI files built correctly (the web/build folder exists).

  • Ensure there is no other NUI resource blocking focus.

  • Try the debug command /testprogressbar with Config.debug = true.

Cancel key does not work

  • Confirm Config.escapeKey.id matches the desired control hash.

  • Check Config.escapeKey.label and Locales[Locale].escape text to ensure consistency.

Notifications not appearing

  • If you rely on your own notify system, make sure Config.Notify is defined.

Multiple actions at the same time

  • The script tracks inprogress internally 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-progressbar

  • Author: Code After S*x

  • UI: React + TypeScript + Tailwind + Framer Motion

  • Game support: RedM

Last updated