-- Compiled with roblox-ts v1.2.7 local TS = _G[script] local Roact = TS.import(script, TS.getModule(script, "@rbxts", "roact").src) local _flipper = TS.import(script, TS.getModule(script, "@rbxts", "flipper").src) local SingleMotor = _flipper.SingleMotor local Spring = _flipper.Spring local connect = TS.import(script, TS.getModule(script, "@rbxts", "roact-rodux").src).connect local DEFAULT_FILTER = TS.import(script, script.Parent.Parent, "Store", "_reducers", "ConsoleReducer").DEFAULT_FILTER local ZirconSyntaxTextBox = TS.import(script, script.Parent.Parent.Parent, "Components", "SyntaxTextBox").default local _Icon = TS.import(script, script.Parent.Parent.Parent, "Components", "Icon") local ZirconIcon = _Icon.default local ZirconIconButton = _Icon.ZirconIconButton local Remotes = TS.import(script, script.Parent.Parent.Parent.Parent, "Shared", "Remotes").default local ZirconOutput = TS.import(script, script.Parent.Parent.Parent, "Components", "Output").default local ThemeContext = TS.import(script, script.Parent.Parent.Parent, "UIKit", "ThemeContext").default local ZirconLogLevel = TS.import(script, script.Parent.Parent.Parent, "Types").ZirconLogLevel local Dropdown = TS.import(script, script.Parent.Parent.Parent, "Components", "Dropdown").default local Workspace = TS.import(script, TS.getModule(script, "@rbxts", "services")).Workspace local Padding = TS.import(script, script.Parent.Parent.Parent, "Components", "Padding").default local SearchTextBox = TS.import(script, script.Parent.Parent.Parent, "Components", "SearchTextBox").default local MultiSelectDropdown = TS.import(script, script.Parent.Parent.Parent, "Components", "MultiSelectDropdown").default local GetCommandService = TS.import(script, script.Parent.Parent.Parent.Parent, "Services").GetCommandService local MAX_SIZE = 28 * 10 --[[ * * The console ]] local ZirconConsoleComponent do ZirconConsoleComponent = Roact.Component:extend("ZirconConsoleComponent") function ZirconConsoleComponent:init(props) self.state = { isVisible = props.isVisible, isFullView = false, filterVisible = false, levelFilter = props.levelFilter, historyIndex = 0, searchQuery = props.searchQuery, source = "", sizeY = MAX_SIZE, context = not props.executionEnabled and 1 or 0, } -- Initialization self.positionYMotor = SingleMotor.new(0) self.sizeYMotor = SingleMotor.new(MAX_SIZE) self.filterSettingsSizeY = SingleMotor.new(0) self.outputTransparencyMotor = SingleMotor.new(0.1) local setPositionY local setSizeY local setOutputTransparency local setFilterSizeY -- Bindings self.positionY, setPositionY = Roact.createBinding(self.positionYMotor:getValue()) self.sizeY, setSizeY = Roact.createBinding(self.sizeYMotor:getValue()) self.filterSizeY, setFilterSizeY = Roact.createBinding(self.filterSettingsSizeY:getValue()) self.outputTransparency, setOutputTransparency = Roact.createBinding(self.outputTransparencyMotor:getValue()) -- Binding updates self.filterSettingsSizeY:onStep(function(value) return setFilterSizeY(value) end) self.positionYMotor:onStep(function(value) return setPositionY(value) end) self.sizeYMotor:onStep(function(value) return setSizeY(value) end) self.outputTransparencyMotor:onStep(function(value) return setOutputTransparency(value) end) local DispatchToServer = Remotes.Client:WaitFor("ZrSiO4/DispatchToServer"):expect() self.dispatch = DispatchToServer end function ZirconConsoleComponent:didMount() end function ZirconConsoleComponent:didUpdate(prevProps, prevState) if prevProps.isVisible ~= self.props.isVisible or (prevState.isFullView ~= self.state.isFullView or prevState.filterVisible ~= self.state.filterVisible) then local fullScreenViewSize = Workspace.CurrentCamera.ViewportSize local size = self.state.isFullView and fullScreenViewSize.Y - 40 or MAX_SIZE self.positionYMotor:setGoal(Spring.new(self.props.isVisible and size + 40 or 0)) self.outputTransparencyMotor:setGoal(Spring.new(self.state.isFullView and 0.35 or 0.1)) self.filterSettingsSizeY:setGoal(Spring.new((self.state.isFullView or self.state.filterVisible) and 40 or 0)) self.sizeYMotor:setGoal(Spring.new(size)) self:setState({ isVisible = self.props.isVisible, }) end if prevProps.clientExecutionEnabled ~= self.props.clientExecutionEnabled then if not self.props.executionEnabled then self:setState({ context = 1, }) end end if prevProps.executionEnabled ~= self.props.executionEnabled then self:setState({ context = self.props.executionEnabled and 0 or 1, }) end if prevProps.levelFilter ~= self.props.levelFilter then self:setState({ levelFilter = self.props.levelFilter, }) end if prevProps.searchQuery ~= self.props.searchQuery then self:setState({ searchQuery = self.props.searchQuery, }) end end function ZirconConsoleComponent:renderNonExecutionBox() return Roact.createElement(ThemeContext.Consumer, { render = function(theme) return Roact.createElement("Frame", { BorderColor3 = theme.SecondaryBackgroundColor3, BackgroundColor3 = theme.PrimaryBackgroundColor3, Size = UDim2.new(1, 0, 0, 28), Position = UDim2.new(0, 0, 1, -28), }, { Roact.createElement("UIListLayout", { FillDirection = "Horizontal", HorizontalAlignment = "Right", }), Roact.createElement(ZirconIconButton, { Icon = self.state.isFullView and "UpDoubleArrow" or "DownDoubleArrow", Size = UDim2.new(0, 32, 0, 28), OnClick = function() self:setState({ isFullView = not self.state.isFullView, }) end, }), }) end, }) end function ZirconConsoleComponent:renderExecutionBox() local showDropdown = self.props.executionEnabled return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { BorderColor3 = theme.PrimaryBackgroundColor3, BackgroundColor3 = theme.SecondaryBackgroundColor3, Size = UDim2.new(1, 0, 0, 28), Position = UDim2.new(0, 0, 1, -28), } local _children = { Roact.createElement("UIListLayout", { FillDirection = "Horizontal", }), } local _length = #_children local _child = showDropdown and (Roact.createElement(Dropdown, { Disabled = not self.props.clientExecutionEnabled or not self.props.executionEnabled, Items = { { Id = 0, Text = "Server", Icon = "ContextServer", }, { Id = 1, Text = "Client", Icon = "ContextClient", } }, SelectedItemId = self.state.context, Position = UDim2.new(1, -150, 0, 0), Size = UDim2.new(0, 100, 1, 0), ItemSelected = function(value) return self:setState({ context = value.Id, }) end, })) if _child then if _child.elements ~= nil or _child.props ~= nil and _child.component ~= nil then _children[_length + 1] = _child else for _k, _v in ipairs(_child) do _children[_length + _k] = _v end end end _length = #_children _children[_length + 1] = Roact.createElement(ZirconIcon, { Size = UDim2.new(0, 16, 0, 28), Icon = "RightArrow", }) _children[_length + 2] = Roact.createElement(ZirconSyntaxTextBox, { RefocusOnSubmit = self.props.autoFocus, AutoFocus = self.props.autoFocus, CancelKeyCodes = self.props.toggleKeys, OnCancel = self.props.close, PlaceholderText = "Enter script to execute", Size = UDim2.new(1, -16 - 32 - (showDropdown and 100 or 0), 1, 0), Position = UDim2.new(0, 16, 0, 0), Focused = self.state.isVisible, Source = self.state.source, OnControlKey = function(key, io) if key == Enum.KeyCode.E then if not self.props.clientExecutionEnabled or not self.props.executionEnabled then return nil end if self.state.context == 1 then self:setState({ context = 0, }) else self:setState({ context = 1, }) end end end, OnEnterSubmit = function(input) self.props.addMessage(input) local _exp = self.state.context repeat if _exp == 0 then self.dispatch:SendToServer(input) break end if _exp == 1 then GetCommandService("ClientDispatchService").ExecuteScript(input) break end until true self:setState({ historyIndex = 0, source = "", }) end, OnHistoryTraversal = function(direction) local index = self.state.historyIndex local history = self.props.history local text = "" if direction == -1 then if index <= 0 then index = #history - 1 else index = index - 1 end text = history[index + 1] elseif direction == 1 then if index >= #history - 1 then index = 0 else index = index + 1 end text = history[index + 1] end self:setState({ historyIndex = index, source = text, }) end, }) _children[_length + 3] = Roact.createElement(ZirconIconButton, { Icon = self.state.isFullView and "UpDoubleArrow" or "DownDoubleArrow", Size = UDim2.new(0, 32, 0, 28), OnClick = function() self:setState({ isFullView = not self.state.isFullView, }) end, }) return Roact.createElement("Frame", _attributes, _children) end, }) end function ZirconConsoleComponent:render() local canExec = self.props.clientExecutionEnabled or self.props.executionEnabled local sizePositionBinding = Roact.joinBindings({ Size = self.sizeY, Position = self.positionY, }) return Roact.createElement(ThemeContext.Consumer, { render = function(theme) local _attributes = { ZIndexBehavior = "Sibling", DisplayOrder = 10000, ResetOnSpawn = false, IgnoreGuiInset = true, } local _children = {} local _length = #_children local _attributes_1 = { Active = self.state.isFullView, BorderSizePixel = 0, } local _condition = theme.Dock.Transparency if _condition == nil then _condition = self.outputTransparency end _attributes_1.BackgroundTransparency = _condition _attributes_1.BackgroundColor3 = theme.PrimaryBackgroundColor3 _attributes_1.ClipsDescendants = true _attributes_1.Size = sizePositionBinding:map(function(v) return UDim2.new(1, 0, 0, v.Size) end) _attributes_1.Position = sizePositionBinding:map(function(v) return UDim2.new(0, 0, 0, -v.Size + v.Position) end) local _children_1 = { Roact.createElement("Frame", { Position = self.filterSizeY:map(function(v) return UDim2.new(0, 0, 0, self.state.isFullView and v or 0) end), Size = self.filterSizeY:map(function(v) return UDim2.new(1, 0, 1, self.state.isFullView and v - 30 or -30) end), BackgroundTransparency = 1, }, { Roact.createElement(ZirconOutput), }), Roact.createElement("Frame", { Size = UDim2.new(0, 100, 0, 30), Position = UDim2.new(1, -100, 0, 5), BackgroundTransparency = 1, }, { Roact.createElement("UIListLayout", { FillDirection = "Horizontal", HorizontalAlignment = "Right", Padding = UDim.new(0, 5), }), Roact.createElement(Padding, { Padding = { Right = 25, }, }), Roact.createElement(ZirconIconButton, { Icon = "Funnel", ZIndex = 2, Floating = true, Size = UDim2.new(0, 30, 0, 30), OnClick = function() return self:setState({ filterVisible = true, }) end, }), }), } local _length_1 = #_children_1 local _attributes_2 = { Size = self.filterSizeY:map(function(v) return UDim2.new(1, 0, 0, v) end), ClipsDescendants = true, BackgroundColor3 = theme.PrimaryBackgroundColor3, BorderSizePixel = 1, BorderColor3 = theme.SecondaryBackgroundColor3, } local _children_2 = { LeftContent = Roact.createElement("Frame", { BackgroundTransparency = 1, Size = UDim2.new(0.5, 0, 1, 0), }, { Roact.createElement("UIListLayout", { FillDirection = "Horizontal", HorizontalAlignment = "Left", Padding = UDim.new(0, 10), }), Roact.createElement(Padding, { Padding = { Horizontal = 20, Vertical = 5, }, }), Roact.createElement(Dropdown, { Items = { { SelectedText = "(Context)", Text = "All Contexts", Id = nil, TextColor3 = Color3.fromRGB(150, 150, 150), }, { Text = "Server", Id = 0, Icon = "ContextServer", }, { Text = "Client", Icon = "ContextClient", Id = 1, } }, SelectedItemId = nil, ItemSelected = function(item) self.props.updateContextFilter(item.Id) end, }), Roact.createElement(MultiSelectDropdown, { Label = "Level Filter", SelectedItemIds = self.state.levelFilter, Items = { { Id = ZirconLogLevel.Verbose, Text = "Verbose", }, { Id = ZirconLogLevel.Debug, Text = "Debugging", }, { Id = ZirconLogLevel.Info, Text = "Information", }, { Id = ZirconLogLevel.Warning, Text = "Warnings", }, { Id = ZirconLogLevel.Error, Text = "Errors", }, { Id = ZirconLogLevel.Wtf, Text = "Fatal Errors", } }, ItemsSelected = function(items) return self.props.updateLevelFilter(items) end, }), }), } local _length_2 = #_children_2 local _attributes_3 = { Size = UDim2.new(0.5, 0, 1, 0), Position = UDim2.new(0.5, 0, 0, 0), BackgroundTransparency = 1, } local _children_3 = { Roact.createElement("UIListLayout", { FillDirection = "Horizontal", HorizontalAlignment = "Right", Padding = UDim.new(0, 10), }), Roact.createElement(Padding, { Padding = { Horizontal = 25, Vertical = 5, }, }), Roact.createElement(SearchTextBox, { Value = self.state.searchQuery, TextChanged = function(value) self.props.updateSearchFilter(value) end, }), } local _length_3 = #_children_3 local _child = not self.state.isFullView and (Roact.createElement(ZirconIconButton, { Icon = "UpDoubleArrow", Floating = true, Size = UDim2.new(0, 30, 0, 30), OnClick = function() return self:setState({ filterVisible = false, }) end, })) if _child then if _child.elements ~= nil or _child.props ~= nil and _child.component ~= nil then _children_3[_length_3 + 1] = _child else for _k, _v in ipairs(_child) do _children_3[_length_3 + _k] = _v end end end _children_2.RightContent = Roact.createElement("Frame", _attributes_3, _children_3) _children_1.FilterLayout = Roact.createElement("Frame", _attributes_2, _children_2) local _child_1 = canExec and self:renderExecutionBox() if _child_1 then if _child_1.elements ~= nil or _child_1.props ~= nil and _child_1.component ~= nil then _children_1[_length_1 + 1] = _child_1 else for _k, _v in ipairs(_child_1) do _children_1[_length_1 + _k] = _v end end end _length_1 = #_children_1 local _child_2 = not canExec and self:renderNonExecutionBox() if _child_2 then if _child_2.elements ~= nil or _child_2.props ~= nil and _child_2.component ~= nil then _children_1[_length_1 + 1] = _child_2 else for _k, _v in ipairs(_child_2) do _children_1[_length_1 + _k] = _v end end end _children.ZirconViewport = Roact.createElement("Frame", _attributes_1, _children_1) return Roact.createElement("ScreenGui", _attributes, _children) end, }) end end local mapStateToProps = function(state) local _object = { isVisible = state.visible, autoFocus = state.autoFocusTextBox, toggleKeys = state.bindingKeys, } local _left = "levelFilter" local _condition = state.filter.Levels if _condition == nil then _condition = DEFAULT_FILTER end _object[_left] = _condition _object.executionEnabled = state.executionEnabled local _left_1 = "searchQuery" local _condition_1 = state.filter.SearchQuery if _condition_1 == nil then _condition_1 = "" end _object[_left_1] = _condition_1 _object.clientExecutionEnabled = state.canExecuteLocalScripts _object.history = state.history return _object end local mapPropsToDispatch = function(dispatch) return { addMessage = function(source) dispatch({ type = "AddHistory", message = source, }) dispatch({ type = "AddOutput", message = { type = "zr:execute", source = source, }, }) end, updateSearchFilter = function(query) dispatch({ type = "UpdateFilter", SearchQuery = query, }) end, updateContextFilter = function(Context) if Context ~= nil then dispatch({ type = "UpdateFilter", Context = Context, }) else dispatch({ type = "RemoveFilter", filter = "Context", }) end end, updateLevelFilter = function(Levels) if Levels ~= nil then dispatch({ type = "UpdateFilter", Levels = Levels, }) else dispatch({ type = "RemoveFilter", filter = "Levels", }) end end, close = function() return dispatch({ type = "SetConsoleVisible", visible = false, }) end, } end --[[ * * A docked console ]] local ZirconDockedConsole = connect(mapStateToProps, mapPropsToDispatch)(ZirconConsoleComponent) local default = ZirconDockedConsole return { default = default, }