Add promise:new() for qb/esx progressbars

This stops them instantly returning `false` and actually waits for the results

This fixes issues with players being unable to complete tasks determined by progressbars eg. installing items on a vehicle and it fails instantly
This commit is contained in:
Jim Shield
2025-08-30 12:15:09 +01:00
parent 1e5d4800fc
commit be5449b100

View File

@@ -4,220 +4,236 @@ local storedPID = nil
local progressFunc = { local progressFunc = {
ox = { ox = {
start = function(data) start =
local options = { function(data)
duration = debugMode and 1000 or data.time, local options = {
label = data.label, duration = debugMode and 1000 or data.time,
position = data.position or "bottom", label = data.label,
useWhileDead = data.dead or false, position = data.position or "bottom",
canCancel = data.cancel or true, useWhileDead = data.dead or false,
anim = { canCancel = data.cancel or true,
dict = data.dict, anim = {
clip = data.anim, dict = data.dict,
flag = (data.flag == 8 and 32 or data.flag) or nil, clip = data.anim,
scenario = data.task flag = (data.flag == 8 and 32 or data.flag) or nil,
}, scenario = data.task
disable = { },
combat = data.combat or true, disable = {
move = data.disableMovement or false, combat = data.combat or true,
car = data.disableMovement or false, move = data.disableMovement or false,
mouse = data.mouse or false car = data.disableMovement or false,
}, mouse = data.mouse or false
} },
if data.prop and data.prop.model then
options.prop = {
model = data.prop.model,
pos = data.prop.pos or vec3(0, 0, 0),
rot = data.prop.rot or vec3(0, 0, 0),
bone = data.prop.bone or 0
} }
end if data.prop and data.prop.model then
if data.propTwo and data.propTwo.model then options.prop = {
options.propTwo = { model = data.prop.model,
model = data.propTwo.model, pos = data.prop.pos or vec3(0, 0, 0),
pos = data.propTwo.pos or vec3(0, 0, 0), rot = data.prop.rot or vec3(0, 0, 0),
rot = data.propTwo.rot or vec3(0, 0, 0), bone = data.prop.bone or 0
bone = data.propTwo.bone or 0 }
}
end
if data.progressType == "circle" then
if exports[OXLibExport]:progressCircle(options) then
return true
else
return false
end end
end if data.propTwo and data.propTwo.model then
if not data.progressType or data.progressType == "bar" then options.propTwo = {
if exports[OXLibExport]:progressBar(options) then model = data.propTwo.model,
return true pos = data.propTwo.pos or vec3(0, 0, 0),
else rot = data.propTwo.rot or vec3(0, 0, 0),
return false bone = data.propTwo.bone or 0
}
end end
end if data.progressType == "circle" then
end, if exports[OXLibExport]:progressCircle(options) then
stop = function() return true
exports[OXLibExport]:cancelProgress() else
end, return false
end
end
if not data.progressType or data.progressType == "bar" then
if exports[OXLibExport]:progressBar(options) then
return true
else
print("^1progressBar was not successful")
end
end
end,
stop =
function()
exports[OXLibExport]:cancelProgress()
end,
}, },
qb = { qb = {
start = function(data) start =
Core.Functions.Progressbar("progbar", function(data)
data.label, local p = promise.new()
debugMode and 1000 or data.time, Core.Functions.Progressbar("progbar",
data.dead or false, data.label,
data.cancel or true, debugMode and 1000 or data.time,
{ data.dead or false,
disableMovement = data.disableMovement or false, data.cancel or true,
disableCarMovement = data.disableMovement or false, {
disableMouse = data.disableMouse or false, disableMovement = data.disableMovement or false,
disableCombat = data.disableCombat or true, disableCarMovement = data.disableMovement or false,
}, disableMouse = data.disableMouse or false,
{ disableCombat = data.disableCombat or true,
animDict = data.dict, },
anim = data.anim, {
flags = data.flag or 32, animDict = data.dict,
task = data.task anim = data.anim,
}, flags = data.flag or 32,
{}, {}, task = data.task
function() },
return true {}, {},
end, function() function() p:resolve(true) end,
return false function() p:resolve(false) end,
end, data.icon) data.icon)
return Citizen.Await(p)
end,
stop =
function()
TriggerEvent("progressbar:client:cancel")
end, end,
stop = function()
TriggerEvent("progressbar:client:cancel")
end,
}, },
qs = { qs = {
start = function(data) start =
if exports['qs-interface']:ProgressBar({ function(data)
duration = debugMode and 1000 or data.time, if exports['qs-interface']:ProgressBar({
label = data.label, duration = debugMode and 1000 or data.time,
position = 'bottom', label = data.label,
useWhileDead = data.dead or false, position = 'bottom',
canCancel = data.cancel or true, useWhileDead = data.dead or false,
disable = data.disableMovement or false, canCancel = data.cancel or true,
anim = { disable = data.disableMovement or false,
dict = data.dict, anim = {
clip = data.anim, dict = data.dict,
flag = data.flag or 32 clip = data.anim,
}, flag = data.flag or 32
prop = nil },
}) then prop = nil
return true }) then
else return true
return false else
end return false
end, end
stop = function() end,
--?? stop =
TriggerEvent("progressbar:client:cancel") function()
end, --??
TriggerEvent("progressbar:client:cancel")
end,
}, },
esx = { esx = {
start = function(data) start =
ESX.Progressbar(data.label, debugMode and 1000 or data.time, { function(data)
FreezePlayer = true, local p = promise.new()
animation = { ESX.Progressbar(data.label, debugMode and 1000 or data.time, {
type = data.anim, FreezePlayer = true,
dict = data.dict, animation = {
scenario = data.task, type = data.anim,
}, dict = data.dict,
onFinish = function() scenario = data.task,
return true },
end, onFinish = function()
onCancel = function() p:resolve(true)
return false end,
end onCancel = function()
}) p:resolve(false)
end, return false
stop = function() end
ESX.CancelProgressbar() })
end, return Citizen.Await(p)
end,
stop =
function()
ESX.CancelProgressbar()
end,
}, },
lation = { lation = {
start = function(data) start =
if exports.lation_ui:progressBar({ function(data)
label = data.label, if exports.lation_ui:progressBar({
description = nil, label = data.label,
duration = debugMode and 1000 or data.time, description = nil,
icon = data.icon, duration = debugMode and 1000 or data.time,
useWhileDead = data.dead or false, icon = data.icon,
disable = { useWhileDead = data.dead or false,
combat = data.combat or true, disable = {
move = data.disableMovement or false, combat = data.combat or true,
car = data.disableMovement or false, move = data.disableMovement or false,
}, car = data.disableMovement or false,
anim = { },
dict = data.dict, anim = {
clip = data.anim, dict = data.dict,
flag = data.flag clip = data.anim,
}, flag = data.flag
prop = { },
model = data.prop and data.prop.model, prop = {
pos = data.prop and (data.prop.pos or vec3(0, 0, 0)), model = data.prop and data.prop.model,
rot = data.prop and (data.prop.rot or vec3(0, 0, 0)), pos = data.prop and (data.prop.pos or vec3(0, 0, 0)),
bone = data.prop and (data.prop.bone or 0) rot = data.prop and (data.prop.rot or vec3(0, 0, 0)),
} bone = data.prop and (data.prop.bone or 0)
}) then }
return true }) then
else return true
return false else
end return false
end, end
stop = function() end,
exports.lation_ui:cancelProgress() stop =
end, function()
exports.lation_ui:cancelProgress()
end,
}, },
red = { red = {
start = function(data) start =
if exports.jim_bridge:redProgressBar({ function(data)
label = data.label, if exports.jim_bridge:redProgressBar({
time = debugMode and 1000 or data.time, label = data.label,
dict = data.dict, time = debugMode and 1000 or data.time,
anim = data.anim, dict = data.dict,
flag = data.flag or 32, anim = data.anim,
task = data.task, flag = data.flag or 32,
disableMovement = data.disableMovement or false, task = data.task,
cancel = data.cancel or true, disableMovement = data.disableMovement or false,
}) then cancel = data.cancel or true,
return true }) then
else return true
return false else
end return false
end, end
stop = function() end,
exports.jim_bridge:stopProgressBar() stop =
end, function()
exports.jim_bridge:stopProgressBar()
end,
}, },
gta = { gta = {
start = function(data) start =
function(data)
if exports.jim_bridge:gtaProgressBar({ if exports.jim_bridge:gtaProgressBar({
label = data.label, label = data.label,
time = debugMode and 1000 or data.time, time = debugMode and 1000 or data.time,
dict = data.dict, dict = data.dict,
anim = data.anim, anim = data.anim,
flag = data.flag or 32, flag = data.flag or 32,
task = data.task, task = data.task,
disableMovement = data.disableMovement or false, disableMovement = data.disableMovement or false,
cancel = data.cancel or true, cancel = data.cancel or true,
}) then }) then
return true return true
else else
return false return false
end end
end, end,
stop = function() stop =
exports.jim_bridge:stopProgressBar() function()
end, exports.jim_bridge:stopProgressBar()
end,
}, },
} }
@@ -254,7 +270,11 @@ local progressFunc = {
--- cancel = true, --- cancel = true,
--- }) --- })
--- ``` --- ```
local progresssBarActive = false
function progressBar(data) function progressBar(data)
if progresssBarActive then return else progresssBarActive = true end
local ped = PlayerPedId() local ped = PlayerPedId()
if data.shared then if data.shared then
debugPrint("^6Bridge^7: ^6Sharing progressBar to player^7: ^6"..data.shared.pid.."^7") debugPrint("^6Bridge^7: ^6Sharing progressBar to player^7: ^6"..data.shared.pid.."^7")
@@ -294,6 +314,7 @@ function progressBar(data)
TriggerServerEvent(getScript()..":clearAuthToken") TriggerServerEvent(getScript()..":clearAuthToken")
currentToken = triggerCallback(AuthEvent) currentToken = triggerCallback(AuthEvent)
end end
progresssBarActive = false
return result return result
end end
@@ -302,6 +323,7 @@ end
--- This function cancels the progress bar based on the configured progress bar system, handling any necessary cleanup. --- This function cancels the progress bar based on the configured progress bar system, handling any necessary cleanup.
function stopProgressBar() function stopProgressBar()
progressFunc[Config.System.ProgressBar].stop() progressFunc[Config.System.ProgressBar].stop()
progresssBarActive = false
end end
-- System to handle sending/sharing progress bars between players -- -- System to handle sending/sharing progress bars between players --