diff --git a/src/DialogueEditor/components/Checkbox/init.luau b/src/DialogueEditor/components/Checkbox/init.luau index fe09dd5b..bc088eac 100644 --- a/src/DialogueEditor/components/Checkbox/init.luau +++ b/src/DialogueEditor/components/Checkbox/init.luau @@ -4,6 +4,7 @@ local root = script.Parent.Parent.Parent; local React = require(root.roblox_packages.react); local useStudioColors = require(root.DialogueEditor.hooks.useStudioColors); local useStudioIcons = require(root.DialogueEditor.hooks.useStudioIcons); +local VirtualService = require(root.VirtualService); export type CheckboxProperties = { text: string; @@ -22,6 +23,34 @@ local function Checkbox(properties: CheckboxProperties) local onChanged = properties.onChanged; local colors = useStudioColors(); local icons = useStudioIcons(); + local buttonRef = React.useRef(nil :: TextButton?); + + React.useEffect(function() + + local button = buttonRef.current; + assert(button, "Button reference should not be nil."); + + local activatedConnection = VirtualService.events.GuiButton.Activated:getSignal(button):Connect(function() + + if not isDisabled then + + onChanged(not isChecked); + + end; + + end); + + return function() + + if activatedConnection then + + activatedConnection:Disconnect(); + + end; + + end; + + end, {onChanged}); return React.createElement("Frame", { AutomaticSize = Enum.AutomaticSize.XY; @@ -41,13 +70,10 @@ local function Checkbox(properties: CheckboxProperties) BackgroundTransparency = if isDisabled then 0.5 else 0; LayoutOrder = 1; Text = ""; - [React.Event.Activated] = function() - - if not isDisabled then + ref = buttonRef; + [React.Event.Activated] = function(self) - onChanged(not isChecked); - - end; + VirtualService.events.GuiButton.Activated:fireEvent(self); end; }, { diff --git a/src/DialogueEditor/components/Explorer/components/Preview/components/AutoTriggerCheckbox/AutoTriggerCheckbox.test.luau b/src/DialogueEditor/components/Explorer/components/Preview/components/AutoTriggerCheckbox/AutoTriggerCheckbox.test.luau new file mode 100644 index 00000000..3751510b --- /dev/null +++ b/src/DialogueEditor/components/Explorer/components/Preview/components/AutoTriggerCheckbox/AutoTriggerCheckbox.test.luau @@ -0,0 +1,145 @@ +--!strict + +local root = script.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent; +local AutoTriggerCheckbox = require(script.Parent); +local VirtualService = require(root.VirtualService); +local React = require(root.roblox_packages.react); +local ReactErrorBoundary = require(root.roblox_packages.ReactErrorBoundary); +local ErrorBoundary = ReactErrorBoundary.ErrorBoundary; +local ReactRoblox = require(root.roblox_packages["react-roblox"]); +local IJW = require(root.roblox_packages.ijw); +local expect = IJW.expect; +local describe = IJW.describe; +local it = IJW.it; + +local screenGui: ScreenGui?; +local reactRoot: ReactRoblox.RootType?; +local propagatedErrorMessage; + +return { + + describe("DialogueGroupContainer", function() + + local function MockComponent(properties: any) + + local selectedScript = properties.selectedScript; + local onErrored = properties.onErrored or function() end; + local onRendered = properties.onRendered or function() end; + + React.useEffect(function() + + onRendered(); + + end, {onRendered}); + + return React.createElement(ErrorBoundary, { + FallbackComponent = React.Fragment; + onError = onErrored; + }, { + React.createElement(AutoTriggerCheckbox, { + selectedScript = selectedScript; + layoutOrder = 1; + }) + }); + + end; + + local function verifyReactStatus() + + if propagatedErrorMessage then + + error(propagatedErrorMessage); + + end; + + end; + + local function createDialogueScript(name: string) + + local dialogueScript = Instance.new("ModuleScript"); + dialogueScript:AddTag("DialogueMakerConversationScript"); + return dialogueScript; + + end; + + local function render(): ModuleScript + + assert(reactRoot, "React root should be initialized before running tests."); + + local selectedScript = createDialogueScript("TestDialogueScript"); + local didRender = false; + local element = React.createElement(MockComponent, { + selectedScript = selectedScript; + onErrored = function(errorMessage) + + propagatedErrorMessage = errorMessage; + + end; + onRendered = function() + + didRender = true; + + end; + }); + + reactRoot:render(element); + repeat task.wait() until didRender or propagatedErrorMessage; + + return selectedScript; + + end; + + return { + + it(`can add "ShouldAutoTriggerConversation" tag to selected script`, function() + + expect(function() + + -- Render the component and wait for it to finish rendering. + assert(screenGui, "ScreenGui should be initialized before running tests."); + local selectedScript = render(); + verifyReactStatus(); + + -- Verify that the checkbox is unchecked. + local checkboxFrame = screenGui:FindFirstChildOfClass("Frame"); + assert(checkboxFrame, "Frame should be present in the ScreenGui."); + + local checkbox = checkboxFrame:FindFirstChild("Checkbox"); + assert(checkbox and checkbox:IsA("TextButton"), "Checkbox should be present in the frame."); + + VirtualService.events.GuiButton.Activated:fireEvent(checkbox); + expect(selectedScript:GetAttribute("ShouldAutoTriggerConversation")).toBe(true); + + end).toFinishBeforeSeconds(1); + + end); + + } + + end, { + beforeEach = function() + + local newScreenGui = Instance.new("ScreenGui"); + screenGui = newScreenGui; + reactRoot = ReactRoblox.createRoot(newScreenGui); + + end; + afterEach = function() + + if reactRoot then + + reactRoot:unmount(); + + end; + + if screenGui then + + screenGui:Destroy(); + + end; + + propagatedErrorMessage = nil; + + end; + }) +}; \ No newline at end of file