forge/arma/client/addons/org/functions/fnc_initOrgUIBridge.sqf
Jacob Schmidt 9cd7278746 Add org leave/disband bridge flow across client and server
- Introduce `OrgUIBridge` to centralize UI event/request/response handling
- Add leave and disband org requests with server handlers and client bridge events
- Enforce portal permissions for leaving/disbanding and protect owner/self from member removal
2026-03-09 23:06:26 -05:00

174 lines
5.8 KiB
Plaintext

#include "..\script_component.hpp"
/*
* File: fnc_initOrgUIBridge.sqf
* Author: IDSolutions
* Date: 2026-03-10
* Last Update: 2026-03-10
* Public: No
*
* Description:
* Initializes the org UI bridge for browser control state and event routing.
*
* Arguments:
* None
*
* Return Value:
* Org UI bridge object [HASHMAP OBJECT]
*
* Examples:
* call forge_client_org_fnc_initOrgUIBridge
*/
#pragma hemtt ignore_variables ["_self"]
GVAR(OrgUIBridgeBaseClass) = compileFinal createHashMapFromArray [
["#type", "OrgUIBridgeBaseClass"],
["#create", compileFinal {
_self set ["pendingBrowserControl", controlNull];
}],
["setPendingBrowserControl", compileFinal {
params [["_control", controlNull, [controlNull]]];
_self set ["pendingBrowserControl", _control];
_control
}],
["consumePendingBrowserControl", compileFinal {
private _control = _self getOrDefault ["pendingBrowserControl", controlNull];
_self set ["pendingBrowserControl", controlNull];
_control
}],
["getActiveBrowserControl", compileFinal {
private _display = uiNamespace getVariable ["RscOrg", displayNull];
if (isNull _display) exitWith { controlNull };
_display displayCtrl 1003
}],
["execBridge", compileFinal {
params [
["_control", controlNull, [controlNull]],
["_fnName", "", [""]],
["_payload", createHashMap, [createHashMap]]
];
if (isNull _control || { _fnName isEqualTo "" }) exitWith { false };
private _json = toJSON _payload;
_control ctrlWebBrowserAction ["ExecJS", format ["OrgUIBridge.%1(%2)", _fnName, _json]];
true
}],
["sendBridgeEvent", compileFinal {
params [
["_event", "", [""]],
["_data", createHashMap, [createHashMap]],
["_control", controlNull, [controlNull]]
];
if (_event isEqualTo "") exitWith { false };
private _targetControl = _control;
if (isNull _targetControl) then {
_targetControl = _self call ["getActiveBrowserControl", []];
};
if (isNull _targetControl) exitWith { false };
_self call ["execBridge", [_targetControl, "receive", createHashMapFromArray [
["event", _event],
["data", _data]
]]]
}],
["handleLoginRequest", compileFinal {
params [["_control", controlNull, [controlNull]]];
private _orgData = GVAR(OrgClass) get "org";
private _orgId = _orgData getOrDefault ["id", ""];
private _orgName = _orgData getOrDefault ["name", ""];
if (_orgId isEqualTo "" && { _orgName isEqualTo "" }) exitWith {
_self call ["execBridge", [_control, "receiveLoginFailure", createHashMapFromArray [
["message", "No organization data is available for this player."]
]]];
};
_self call ["execBridge", [_control, "receiveLoginSuccess", GVAR(OrgClass) call ["buildPortalPayload", []]]];
}],
["handleCreateRequest", compileFinal {
params [
["_control", controlNull, [controlNull]],
["_data", createHashMap, [createHashMap]]
];
private _orgName = _data getOrDefault ["orgName", ""];
if (_orgName isEqualTo "") exitWith {
_self call ["execBridge", [_control, "receiveCreateFailure", createHashMapFromArray [
["message", "Enter an organization name."]
]]];
};
_self call ["setPendingBrowserControl", [_control]];
[SRPC(org,requestCreateOrg), [getPlayerUID player, _orgName]] call CFUNC(serverEvent);
}],
["handleCreateResponse", compileFinal {
params [["_payload", createHashMap, [createHashMap]]];
private _control = _self call ["consumePendingBrowserControl", []];
private _success = _payload getOrDefault ["success", false];
if (!_success) exitWith {
if (isNull _control) exitWith {};
_self call ["execBridge", [_control, "receiveCreateFailure", createHashMapFromArray [
["message", _payload getOrDefault ["message", "Organization registration failed."]]
]]];
};
private _orgData = _payload getOrDefault ["org", createHashMap];
GVAR(OrgClass) call ["sync", [_orgData, true]];
if (isNull _control) exitWith {};
_self call ["execBridge", [_control, "receiveCreateSuccess", GVAR(OrgClass) call ["buildPortalPayload", []]]];
}],
["handleDisbandResponse", compileFinal {
params [["_payload", createHashMap, [createHashMap]]];
private _eventName = if (_payload getOrDefault ["success", false]) then {
["org::portal::revoked", "org::disband::success"] select (_payload getOrDefault ["requester", false])
} else {
"org::disband::failure"
};
_self call ["sendBridgeEvent", [_eventName, _payload]];
}],
["handleLeaveResponse", compileFinal {
params [["_payload", createHashMap, [createHashMap]]];
private _eventName = [
"org::leave::failure",
"org::leave::success"
] select (_payload getOrDefault ["success", false]);
_self call ["sendBridgeEvent", [_eventName, _payload]];
}],
["requestDisband", compileFinal {
[SRPC(org,requestDisbandOrg), [getPlayerUID player]] call CFUNC(serverEvent);
}],
["requestLeave", compileFinal {
[SRPC(org,requestLeaveOrg), [getPlayerUID player]] call CFUNC(serverEvent);
}],
["handleReady", compileFinal {
params [["_control", controlNull, [controlNull]]];
_self call ["sendBridgeEvent", [
"org::ready",
createHashMapFromArray [
["loaded", true]
],
_control
]];
}]
];
GVAR(OrgUIBridge) = createHashMapObject [GVAR(OrgUIBridgeBaseClass)];
GVAR(OrgUIBridge)