add gs
This commit is contained in:
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(open)
|
||||
return {
|
||||
open = open,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(canChat)
|
||||
return {
|
||||
canChat = canChat,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(enabled)
|
||||
return {
|
||||
enabled = enabled,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(open)
|
||||
return {
|
||||
open = open,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameName)
|
||||
return {
|
||||
gameName = gameName,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(inputType)
|
||||
return {
|
||||
inputType = inputType,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(inspectMenuOpen)
|
||||
return {
|
||||
inspectMenuOpen = inspectMenuOpen,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(isDead)
|
||||
return {
|
||||
isDead = isDead,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(open)
|
||||
return {
|
||||
open = open,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(menuOpen)
|
||||
return {
|
||||
menuOpen = menuOpen,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(open)
|
||||
return {
|
||||
open = open,
|
||||
}
|
||||
end)
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(respawnEnabled, respawnCallback)
|
||||
return {
|
||||
respawnEnabled = respawnEnabled,
|
||||
customCallback = respawnCallback,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(screenSize)
|
||||
return {
|
||||
screenSize = screenSize,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(isSmallTouchDevice)
|
||||
return {
|
||||
isSmallTouchDevice = isSmallTouchDevice,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(enabled)
|
||||
return {
|
||||
enabled = enabled,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(messages)
|
||||
return {
|
||||
messages = messages,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(visible)
|
||||
return {
|
||||
visible = visible,
|
||||
}
|
||||
end)
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(coreGuiType, enabled)
|
||||
return {
|
||||
coreGuiType = coreGuiType,
|
||||
enabled = enabled,
|
||||
}
|
||||
end)
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Action = require(CorePackages.AppTempCommon.Common.Action)
|
||||
|
||||
return Action(script.Name, function(health, maxHealth)
|
||||
return {
|
||||
health = health,
|
||||
maxHealth = maxHealth,
|
||||
}
|
||||
end)
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local UpdateChatVisible = require(TopBar.Actions.UpdateChatVisible)
|
||||
local UpdateChatMessages = require(TopBar.Actions.UpdateChatMessages)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local ChatSelector = require(RobloxGui.Modules.ChatSelector)
|
||||
|
||||
local GameSettings = UserSettings().GameSettings
|
||||
|
||||
local ChatConnector = Roact.PureComponent:extend("ChatConnector")
|
||||
|
||||
ChatConnector.validateProps = t.strictInterface({
|
||||
isSmallTouchScreen = t.boolean,
|
||||
|
||||
updateChatVisible = t.callback,
|
||||
updateChatMessages = t.callback,
|
||||
})
|
||||
|
||||
function ChatConnector:didMount()
|
||||
local willEnableChat = GameSettings.ChatVisible
|
||||
if self.props.isSmallTouchScreen then
|
||||
willEnableChat = false
|
||||
end
|
||||
ChatSelector:SetVisible(willEnableChat)
|
||||
|
||||
self.props.updateChatMessages(ChatSelector:GetMessageCount())
|
||||
self.props.updateChatVisible(ChatSelector:GetVisibility())
|
||||
|
||||
self.chatVisibleConnection = ChatSelector.VisibilityStateChanged:connect(function(visible)
|
||||
self.props.updateChatVisible(visible)
|
||||
end)
|
||||
|
||||
self.chatMessagesConnection = ChatSelector.MessagesChanged:connect(function(messages)
|
||||
self.props.updateChatMessages(messages)
|
||||
end)
|
||||
end
|
||||
|
||||
function ChatConnector:render()
|
||||
return nil
|
||||
end
|
||||
|
||||
function ChatConnector:willUnmount()
|
||||
self.chatVisibleConnection:disconnect()
|
||||
self.chatMessagesConnection:disconnect()
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
isSmallTouchScreen = state.displayOptions.isSmallTouchDevice,
|
||||
}
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
updateChatVisible = function(visible)
|
||||
return dispatch(UpdateChatVisible(visible))
|
||||
end,
|
||||
|
||||
updateChatMessages = function(messages)
|
||||
return dispatch(UpdateChatMessages(messages))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, mapDispatchToProps)(ChatConnector)
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local StarterGui = game:GetService("StarterGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local UpdateCoreGuiEnabled = require(TopBar.Actions.UpdateCoreGuiEnabled)
|
||||
|
||||
local EventConnection = require(TopBar.Parent.Common.EventConnection)
|
||||
|
||||
local CoreGuiConnector = Roact.PureComponent:extend("CoreGuiConnector")
|
||||
|
||||
CoreGuiConnector.validateProps = t.strictInterface({
|
||||
updateCoreGuiEnabled = t.callback,
|
||||
})
|
||||
|
||||
function CoreGuiConnector:didMount()
|
||||
local initalCoreGuiTypes = Enum.CoreGuiType:GetEnumItems()
|
||||
for _, coreGuiType in ipairs(initalCoreGuiTypes) do
|
||||
if coreGuiType ~= Enum.CoreGuiType.All then
|
||||
self.props.updateCoreGuiEnabled(coreGuiType, StarterGui:GetCoreGuiEnabled(coreGuiType))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CoreGuiConnector:render()
|
||||
return Roact.createFragment({
|
||||
CoreGuiChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = StarterGui.CoreGuiChangedSignal,
|
||||
callback = function(coreGuiType, enabled)
|
||||
self.props.updateCoreGuiEnabled(coreGuiType, enabled)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
updateCoreGuiEnabled = function(coreGuiType, enabled)
|
||||
return dispatch(UpdateCoreGuiEnabled(coreGuiType, enabled))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(nil, mapDispatchToProps)(CoreGuiConnector)
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local ChatSelector = require(RobloxGui.Modules.ChatSelector)
|
||||
local BackpackModule = require(RobloxGui.Modules.BackpackScript)
|
||||
local EmotesModule = require(RobloxGui.Modules.EmotesMenu.EmotesMenuMaster)
|
||||
local PlayerListMaster = require(RobloxGui.Modules.PlayerList.PlayerListManager)
|
||||
|
||||
local EnabledNotifier = Roact.PureComponent:extend("CoreGuiCEnabledNotifieronnector")
|
||||
|
||||
EnabledNotifier.validateProps = t.strictInterface({
|
||||
topBarEnabled = t.boolean,
|
||||
})
|
||||
|
||||
function EnabledNotifier:notifyEnabled()
|
||||
PlayerListMaster:SetTopBarEnabled(self.props.topBarEnabled)
|
||||
ChatSelector:TopbarEnabledChanged(self.props.topBarEnabled)
|
||||
BackpackModule:TopbarEnabledChanged(self.props.topBarEnabled)
|
||||
EmotesModule:setTopBarEnabled(self.props.topBarEnabled)
|
||||
end
|
||||
|
||||
function EnabledNotifier:didMount()
|
||||
self:notifyEnabled()
|
||||
end
|
||||
|
||||
function EnabledNotifier:render()
|
||||
return nil
|
||||
end
|
||||
|
||||
function EnabledNotifier:didUpdate(prevProps, prevState)
|
||||
if self.props.topBarEnabled ~= prevProps.topBarEnabled then
|
||||
self:notifyEnabled()
|
||||
end
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
topBarEnabled = state.displayOptions.topbarEnabled,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(EnabledNotifier)
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local SetIsDead = require(TopBar.Actions.SetIsDead)
|
||||
local UpdateHealth = require(TopBar.Actions.UpdateHealth)
|
||||
|
||||
local EventConnection = require(TopBar.Parent.Common.EventConnection)
|
||||
|
||||
local LocalPlayer = Players.LocalPlayer
|
||||
while not LocalPlayer do
|
||||
Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
|
||||
LocalPlayer = Players.LocalPlayer
|
||||
end
|
||||
|
||||
local HealthConnector = Roact.PureComponent:extend("HealthConnector")
|
||||
|
||||
HealthConnector.validateProps = t.strictInterface({
|
||||
setIsDead = t.callback,
|
||||
updateHealth = t.callback,
|
||||
})
|
||||
|
||||
function HealthConnector:init()
|
||||
local character = LocalPlayer.Character
|
||||
local humanoid = nil
|
||||
if character then
|
||||
humanoid = character:FindFirstChildOfClass("Humanoid")
|
||||
end
|
||||
|
||||
self:setState({
|
||||
character = character,
|
||||
humanoid = humanoid,
|
||||
})
|
||||
end
|
||||
|
||||
function HealthConnector:didMount()
|
||||
if self.state.humanoid then
|
||||
self.props.updateHealth(self.state.humanoid.Health, self.state.humanoid.MaxHealth)
|
||||
end
|
||||
end
|
||||
|
||||
function HealthConnector:render()
|
||||
local eventConnections = {}
|
||||
|
||||
if self.state.humanoid then
|
||||
eventConnections["HealthChangedConnection"] = Roact.createElement(EventConnection, {
|
||||
event = self.state.humanoid.HealthChanged,
|
||||
callback = function(health)
|
||||
self.props.updateHealth(self.state.humanoid.Health, self.state.humanoid.MaxHealth)
|
||||
end,
|
||||
})
|
||||
|
||||
eventConnections["HumanoidDiedConnection"] = Roact.createElement(EventConnection, {
|
||||
event = self.state.humanoid.Died,
|
||||
callback = function()
|
||||
self.props.setIsDead(true)
|
||||
end,
|
||||
})
|
||||
elseif self.state.character then
|
||||
eventConnections["ChildAddedConnection"] = Roact.createElement(EventConnection, {
|
||||
event = self.state.character.ChildAdded,
|
||||
callback = function(child)
|
||||
if child:IsA("Humanoid") then
|
||||
self:setState({
|
||||
humanoid = child,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
eventConnections["CharacterAddedConnection"] = Roact.createElement(EventConnection, {
|
||||
event = LocalPlayer.CharacterAdded,
|
||||
callback = function(character)
|
||||
self:setState({
|
||||
humanoid = character:FindFirstChildOfClass("Humanoid"),
|
||||
character = character,
|
||||
})
|
||||
self.props.setIsDead(false)
|
||||
end,
|
||||
})
|
||||
|
||||
eventConnections["CharacterRemovingConnection"] = Roact.createElement(EventConnection, {
|
||||
event = LocalPlayer.CharacterRemoving,
|
||||
callback = function()
|
||||
self:setState({
|
||||
humanoid = Roact.None,
|
||||
character = Roact.None,
|
||||
})
|
||||
end,
|
||||
})
|
||||
|
||||
return Roact.createFragment(eventConnections)
|
||||
end
|
||||
|
||||
function HealthConnector:didUpdate(prevProps, prevState)
|
||||
if self.state.humanoid == nil then
|
||||
self.props.updateHealth(0, 0)
|
||||
elseif self.state.humanoid ~= prevState.humanoid then
|
||||
self.props.setIsDead(false)
|
||||
self.props.updateHealth(self.state.humanoid.Health, self.state.humanoid.MaxHealth)
|
||||
end
|
||||
if self.state.character and self.state.character ~= prevState.character then
|
||||
local humanoid = self.state.character:FindFirstChildWhichIsA("Humanoid")
|
||||
if humanoid then
|
||||
self:setState({
|
||||
humanoid = Roact.None,
|
||||
character = Roact.None,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
setIsDead = function(isDead)
|
||||
return dispatch(SetIsDead(isDead))
|
||||
end,
|
||||
|
||||
updateHealth = function(health, maxHealth)
|
||||
return dispatch(UpdateHealth(health, maxHealth))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(nil, mapDispatchToProps)(HealthConnector)
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local EventConnection = require(TopBar.Parent.Common.EventConnection)
|
||||
|
||||
local SetInputType = require(TopBar.Actions.SetInputType)
|
||||
local Constants = require(TopBar.Constants)
|
||||
|
||||
local InputType = Constants.InputType
|
||||
|
||||
local LastInputTypeConnector = Roact.PureComponent:extend("LastInputTypeConnector")
|
||||
|
||||
local inputTypeMap = {
|
||||
[Enum.UserInputType.MouseButton2] = InputType.MouseAndKeyBoard,
|
||||
[Enum.UserInputType.MouseButton3] = InputType.MouseAndKeyBoard,
|
||||
[Enum.UserInputType.MouseWheel] = InputType.MouseAndKeyBoard,
|
||||
[Enum.UserInputType.MouseMovement] = InputType.MouseAndKeyBoard,
|
||||
[Enum.UserInputType.Keyboard] = InputType.MouseAndKeyBoard,
|
||||
|
||||
[Enum.UserInputType.Gamepad1] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad2] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad3] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad4] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad5] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad6] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad7] = InputType.Gamepad,
|
||||
[Enum.UserInputType.Gamepad8] = InputType.Gamepad,
|
||||
|
||||
[Enum.UserInputType.Touch] = InputType.Touch,
|
||||
}
|
||||
|
||||
function LastInputTypeConnector:didMount()
|
||||
local initalInputType = inputTypeMap[UserInputService:GetLastInputType()]
|
||||
if initalInputType then
|
||||
self.props.setInputType(initalInputType)
|
||||
end
|
||||
end
|
||||
|
||||
function LastInputTypeConnector:render()
|
||||
return Roact.createElement(EventConnection, {
|
||||
event = UserInputService.LastInputTypeChanged,
|
||||
callback = function(lastInputType)
|
||||
local inputType = inputTypeMap[lastInputType]
|
||||
if inputType then
|
||||
self.props.setInputType(inputType)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(nil, function(dispatch)
|
||||
return {
|
||||
setInputType = function(inputType)
|
||||
return dispatch(SetInputType(inputType))
|
||||
end,
|
||||
}
|
||||
end)(LastInputTypeConnector)
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local SetMenuOpen = require(TopBar.Actions.SetMenuOpen)
|
||||
local SetRespawnBehaviour = require(TopBar.Actions.SetRespawnBehaviour)
|
||||
|
||||
local EventConnection = require(TopBar.Parent.Common.EventConnection)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local isNewInGameMenuEnabled = require(RobloxGui.Modules.isNewInGameMenuEnabled)
|
||||
|
||||
local isNewGamepadMenuEnabled = require(RobloxGui.Modules.Flags.isNewGamepadMenuEnabled)
|
||||
|
||||
local MenuConnector = Roact.PureComponent:extend("MenuConnector")
|
||||
|
||||
MenuConnector.validateProps = t.strictInterface({
|
||||
setMenuOpen = t.callback,
|
||||
|
||||
setRespawnBehaviour = isNewGamepadMenuEnabled() and t.callback or nil,
|
||||
})
|
||||
|
||||
function MenuConnector:didMount()
|
||||
if isNewInGameMenuEnabled() then
|
||||
local InGameMenu = require(RobloxGui.Modules.InGameMenu)
|
||||
self.props.setMenuOpen(InGameMenu.getOpen())
|
||||
|
||||
if isNewGamepadMenuEnabled() then
|
||||
local isEnabled, customCallback = InGameMenu.getRespawnBehaviour()
|
||||
self.props.setRespawnBehaviour(isEnabled, customCallback)
|
||||
end
|
||||
else
|
||||
local SettingsHub = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
self.props.setMenuOpen(SettingsHub:GetVisibility())
|
||||
|
||||
if isNewGamepadMenuEnabled() then
|
||||
local isEnabled, customCallback = SettingsHub:GetRespawnBehaviour()
|
||||
self.props.setRespawnBehaviour(isEnabled, customCallback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuConnector:render()
|
||||
if isNewInGameMenuEnabled() then
|
||||
--TODO: Move require the top of the script when removing isNewInGameMenuEnabled
|
||||
local InGameMenu = require(RobloxGui.Modules.InGameMenu)
|
||||
local inGameMenuOpenChangedEvent = InGameMenu.getOpenChangedEvent()
|
||||
|
||||
local respawnBehaviourChangedEvent
|
||||
if isNewGamepadMenuEnabled() then
|
||||
respawnBehaviourChangedEvent = InGameMenu.getRespawnBehaviourChangedEvent()
|
||||
end
|
||||
|
||||
return Roact.createFragment({
|
||||
MenuOpenChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = inGameMenuOpenChangedEvent.Event,
|
||||
callback = function(open)
|
||||
self.props.setMenuOpen(open)
|
||||
end,
|
||||
}),
|
||||
|
||||
RespawnBehaviourConnection = isNewGamepadMenuEnabled() and Roact.createElement(EventConnection, {
|
||||
event = respawnBehaviourChangedEvent.Event,
|
||||
callback = function(isEnabled, customCallback)
|
||||
self.props.setRespawnBehaviour(isEnabled, customCallback)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
else
|
||||
local SettingsHub = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
local settingsHubOpenedEvent = SettingsHub.SettingsShowEvent
|
||||
|
||||
local respawnBehaviourChangedEvent
|
||||
if isNewGamepadMenuEnabled() then
|
||||
respawnBehaviourChangedEvent = SettingsHub.RespawnBehaviourChangedEvent
|
||||
end
|
||||
|
||||
return Roact.createFragment({
|
||||
MenuOpenChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = settingsHubOpenedEvent.Event,
|
||||
callback = function(open)
|
||||
self.props.setMenuOpen(open)
|
||||
end,
|
||||
}),
|
||||
|
||||
RespawnBehaviourConnection = isNewGamepadMenuEnabled() and Roact.createElement(EventConnection, {
|
||||
event = respawnBehaviourChangedEvent.Event,
|
||||
callback = function(isEnabled, customCallback)
|
||||
self.props.setRespawnBehaviour(isEnabled, customCallback)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
setMenuOpen = function(open)
|
||||
return dispatch(SetMenuOpen(open))
|
||||
end,
|
||||
|
||||
setRespawnBehaviour = isNewGamepadMenuEnabled() and function(isEnabled, customCallback)
|
||||
return dispatch(SetRespawnBehaviour(isEnabled, customCallback))
|
||||
end or nil,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(nil, mapDispatchToProps)(MenuConnector)
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local SetBackpackOpen = require(TopBar.Actions.SetBackpackOpen)
|
||||
local SetEmotesOpen = require(TopBar.Actions.SetEmotesOpen)
|
||||
local SetLeaderboardOpen = require(TopBar.Actions.SetLeaderboardOpen)
|
||||
local SetEmotesEnabled = require(TopBar.Actions.SetEmotesEnabled)
|
||||
|
||||
local EventConnection = require(TopBar.Parent.Common.EventConnection)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local BackpackModule = require(RobloxGui.Modules.BackpackScript)
|
||||
local EmotesMenuMaster = require(RobloxGui.Modules.EmotesMenu.EmotesMenuMaster)
|
||||
local PlayerListMaster = require(RobloxGui.Modules.PlayerList.PlayerListManager)
|
||||
|
||||
local OpenUIConnector = Roact.PureComponent:extend("OpenUIConnector")
|
||||
|
||||
OpenUIConnector.validateProps = t.strictInterface({
|
||||
setBackpackOpen = t.callback,
|
||||
setEmotesOpen = t.callback,
|
||||
setLeaderboardOpen = t.callback,
|
||||
|
||||
setEmotesEnabled = t.callback,
|
||||
})
|
||||
|
||||
function OpenUIConnector:didMount()
|
||||
self.props.setLeaderboardOpen(PlayerListMaster:GetSetVisible())
|
||||
|
||||
self.props.setBackpackOpen(BackpackModule.IsOpen)
|
||||
self.props.setEmotesOpen(EmotesMenuMaster:isOpen())
|
||||
self.props.setEmotesEnabled(EmotesMenuMaster.MenuIsVisible)
|
||||
end
|
||||
|
||||
function OpenUIConnector:render()
|
||||
local leaderboardEvent = PlayerListMaster:GetSetVisibleChangedEvent()
|
||||
|
||||
return Roact.createFragment({
|
||||
LeaderboardOpenChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = leaderboardEvent.Event,
|
||||
callback = function(open)
|
||||
self.props.setLeaderboardOpen(open)
|
||||
end,
|
||||
}),
|
||||
|
||||
BackpackOpenChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = BackpackModule.StateChanged.Event,
|
||||
callback = function(open)
|
||||
self.props.setBackpackOpen(open)
|
||||
end,
|
||||
}),
|
||||
|
||||
EmotesOpenChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = EmotesMenuMaster.EmotesMenuToggled.Event,
|
||||
callback = function(open)
|
||||
self.props.setEmotesOpen(open)
|
||||
end,
|
||||
}),
|
||||
|
||||
EmotesEnabledChangedConnection = Roact.createElement(EventConnection, {
|
||||
event = EmotesMenuMaster.MenuVisibilityChanged.Event,
|
||||
callback = function(enabled)
|
||||
self.props.setEmotesEnabled(enabled)
|
||||
end,
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
setBackpackOpen = function(open)
|
||||
return dispatch(SetBackpackOpen(open))
|
||||
end,
|
||||
|
||||
setEmotesOpen = function(open)
|
||||
return dispatch(SetEmotesOpen(open))
|
||||
end,
|
||||
|
||||
setLeaderboardOpen = function(open)
|
||||
return dispatch(SetLeaderboardOpen(open))
|
||||
end,
|
||||
|
||||
setEmotesEnabled = function(enabled)
|
||||
return dispatch(SetEmotesEnabled(enabled))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(nil, mapDispatchToProps)(OpenUIConnector)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
|
||||
local CoreGuiConnector = require(script.CoreGuiConnector)
|
||||
local MenuConnector = require(script.MenuConnector)
|
||||
local ChatConnector = require(script.ChatConnector)
|
||||
local HealthConnector = require(script.HealthConnector)
|
||||
local EnabledNotifier = require(script.EnabledNotifier)
|
||||
local OpenUIConnector = require(script.OpenUIConnector)
|
||||
local LastInputTypeConnector = require(script.LastInputTypeConnector)
|
||||
|
||||
local Connection = Roact.PureComponent:extend("Connection")
|
||||
|
||||
function Connection:render()
|
||||
return Roact.createFragment({
|
||||
CoreGuiConnector = Roact.createElement(CoreGuiConnector),
|
||||
MenuConnector = Roact.createElement(MenuConnector),
|
||||
ChatConnector = Roact.createElement(ChatConnector),
|
||||
HealthConnector = Roact.createElement(HealthConnector),
|
||||
EnabledNotifier = Roact.createElement(EnabledNotifier),
|
||||
OpenUIConnector = Roact.createElement(OpenUIConnector),
|
||||
LastInputTypeConnector = Roact.createElement(LastInputTypeConnector),
|
||||
})
|
||||
end
|
||||
|
||||
return Connection
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Badge = UIBlox.App.Indicator.Badge
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local ChatSelector = require(RobloxGui.Modules.ChatSelector)
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
|
||||
local IconButton = require(script.Parent.IconButton)
|
||||
|
||||
local GameSettings = UserSettings().GameSettings
|
||||
|
||||
local ChatIcon = Roact.PureComponent:extend("ChatIcon")
|
||||
|
||||
local CHAT_ICON_AREA_WIDTH = 44
|
||||
|
||||
local ICON_SIZE = 20
|
||||
local BADGE_OFFSET_X = 18
|
||||
local BADGE_OFFSET_Y = 2
|
||||
|
||||
ChatIcon.validateProps = t.strictInterface({
|
||||
layoutOrder = t.integer,
|
||||
|
||||
chatVisible = t.boolean,
|
||||
unreadMessages = t.integer,
|
||||
|
||||
topBarEnabled = t.boolean,
|
||||
chatEnabled = t.boolean,
|
||||
})
|
||||
|
||||
function ChatIcon:init()
|
||||
self.chatIconActivated = function()
|
||||
ChatSelector:ToggleVisibility()
|
||||
GameSettings.ChatVisible = ChatSelector:GetVisibility()
|
||||
end
|
||||
end
|
||||
|
||||
function ChatIcon:render()
|
||||
return withStyle(function(style)
|
||||
local chatEnabled = self.props.topBarEnabled and self.props.chatEnabled and not TenFootInterface:IsEnabled()
|
||||
|
||||
local chatIcon = "rbxasset://textures/ui/TopBar/chatOn.png"
|
||||
if not self.props.chatVisible then
|
||||
chatIcon = "rbxasset://textures/ui/TopBar/chatOff.png"
|
||||
end
|
||||
|
||||
return Roact.createElement("TextButton", {
|
||||
Text = "",
|
||||
Visible = chatEnabled,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, CHAT_ICON_AREA_WIDTH, 1, 0),
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
}, {
|
||||
Background = Roact.createElement(IconButton, {
|
||||
icon = chatIcon,
|
||||
iconSize = ICON_SIZE,
|
||||
|
||||
onActivated = self.chatIconActivated,
|
||||
}),
|
||||
|
||||
BadgeContainer = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
ZIndex = 2,
|
||||
}, {
|
||||
Badge = self.props.unreadMessages > 0 and Roact.createElement(Badge, {
|
||||
position = UDim2.fromOffset(BADGE_OFFSET_X, BADGE_OFFSET_Y),
|
||||
anchorPoint = Vector2.new(0, 0),
|
||||
|
||||
hasShadow = false,
|
||||
value = self.props.unreadMessages,
|
||||
})
|
||||
})
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
chatVisible = state.chat.visible,
|
||||
unreadMessages = state.chat.unreadMessages,
|
||||
|
||||
topBarEnabled = state.displayOptions.topbarEnabled,
|
||||
chatEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Chat],
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(ChatIcon)
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
|
||||
local ButtonHint = require(script.Parent.ButtonHint)
|
||||
|
||||
local BOTTOMBAR_HEIGHT = 72
|
||||
local SCREENSIDE_PADDING = 24
|
||||
local PADDING = 40
|
||||
|
||||
local BottomBar = Roact.PureComponent:extend("BottomBar")
|
||||
|
||||
BottomBar.validateProps = t.strictInterface({
|
||||
respawnEnabled = t.boolean,
|
||||
})
|
||||
|
||||
function BottomBar:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
BackgroundTransparency = theme.BackgroundUIContrast.Transparency,
|
||||
BackgroundColor3 = theme.BackgroundUIContrast.Color,
|
||||
Size = UDim2.new(1, 0, 0, BOTTOMBAR_HEIGHT),
|
||||
Position = UDim2.fromScale(0, 1),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
}, {
|
||||
Padding = Roact.createElement("UIPadding", {
|
||||
PaddingLeft = UDim.new(0, SCREENSIDE_PADDING),
|
||||
PaddingRight = UDim.new(0, SCREENSIDE_PADDING),
|
||||
}),
|
||||
|
||||
LeftFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(0.5, 1),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
Padding = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
LeaveHint = Roact.createElement(ButtonHint, {
|
||||
localizationKey = "CoreScripts.TopBar.Back",
|
||||
keyLabel = "B",
|
||||
}),
|
||||
}),
|
||||
|
||||
RightFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(0.5, 1),
|
||||
Position = UDim2.fromScale(1, 0),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Right,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
Padding = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
LeaveHint = Roact.createElement(ButtonHint, {
|
||||
layoutOrder = 2,
|
||||
localizationKey = "CoreScripts.TopBar.Leave",
|
||||
keyLabel = "X",
|
||||
}),
|
||||
|
||||
RespawnHint = self.props.respawnEnabled and Roact.createElement(ButtonHint, {
|
||||
layoutOrder = 1,
|
||||
localizationKey = "CoreScripts.TopBar.Respawn",
|
||||
keyLabel = "Y",
|
||||
}),
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
respawnEnabled = state.respawn.enabled,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(BottomBar)
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local TextService = game:GetService("TextService")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local RobloxTranslator = require(RobloxGui.Modules.RobloxTranslator)
|
||||
|
||||
local ICON_SIZE = 28
|
||||
local PADDING = 12
|
||||
|
||||
local ICON_RING_IMAGE = Images["component_assets/circle_29_stroke_1"]
|
||||
|
||||
local ButtonHint = Roact.PureComponent:extend("ButtonHint")
|
||||
|
||||
ButtonHint.validateProps = t.strictInterface({
|
||||
layoutOrder = t.optional(t.integer),
|
||||
localizationKey = t.string,
|
||||
keyLabel = t.string,
|
||||
})
|
||||
|
||||
function ButtonHint:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
local font = style.Font
|
||||
|
||||
local text = RobloxTranslator:FormatByKey(self.props.localizationKey)
|
||||
|
||||
local fontSize = font.BaseSize * font.Header1.RelativeSize
|
||||
local textWidth = TextService:GetTextSize(text, fontSize, font.Header1.Font, Vector2.new(1000, 1000)).X
|
||||
local buttonHintWidth = ICON_SIZE + PADDING + textWidth
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, buttonHintWidth, 1, 0),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
Padding = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
Icon = Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 1,
|
||||
Size = UDim2.fromOffset(ICON_SIZE, ICON_SIZE),
|
||||
Image = ICON_RING_IMAGE,
|
||||
ImageTransparency = theme.UIDefault.Transparency,
|
||||
ImageColor3 = theme.UIDefault.Color,
|
||||
}, {
|
||||
Text = Roact.createElement("TextLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
Text = self.props.keyLabel,
|
||||
Font = font.Header2.Font,
|
||||
TextSize = font.BaseSize * font.Header2.RelativeSize,
|
||||
TextColor3 = theme.UIDefault.Color,
|
||||
TextTransparency = theme.UIDefault.TextTransparency,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
TextYAlignment = Enum.TextYAlignment.Center,
|
||||
}),
|
||||
}),
|
||||
|
||||
Text = Roact.createElement("TextLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, textWidth, 0, 1),
|
||||
LayoutOrder = 2,
|
||||
|
||||
Font = font.Header1.Font,
|
||||
Text = text,
|
||||
TextSize = fontSize,
|
||||
TextColor3 = theme.TextEmphasis.Color,
|
||||
TextTransparency = theme.TextEmphasis.TextTransparency,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Center,
|
||||
})
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return ButtonHint
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
local Badge = UIBlox.App.Indicator.Badge
|
||||
|
||||
local CHAT_ON = Images["icons/menu/chat_on"]
|
||||
local CHAT_OFF = Images["icons/menu/chat_off"]
|
||||
|
||||
local ChatIcon = Roact.PureComponent:extend("ChatIcon")
|
||||
|
||||
ChatIcon.validateProps = t.strictInterface({
|
||||
chatVisible = t.boolean,
|
||||
unreadMessages = t.integer,
|
||||
})
|
||||
|
||||
function ChatIcon:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
|
||||
local chatIcon = CHAT_ON
|
||||
if not self.props.chatVisible then
|
||||
chatIcon = CHAT_OFF
|
||||
end
|
||||
|
||||
return Roact.createElement(ImageSetLabel, {
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
BackgroundTransparency = 1,
|
||||
Image = chatIcon,
|
||||
ImageColor3 = theme.IconEmphasis.Color,
|
||||
ImageTransparency = theme.IconEmphasis.Transparency,
|
||||
ZIndex = 2,
|
||||
}, {
|
||||
Badge = self.props.unreadMessages > 0 and Roact.createElement(Badge, {
|
||||
position = UDim2.new(0, 24, 0.5, 0),
|
||||
anchorPoint = Vector2.new(0, 0.5),
|
||||
|
||||
hasShadow = false,
|
||||
value = self.props.unreadMessages,
|
||||
})
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
chatVisible = state.chat.visible,
|
||||
unreadMessages = state.chat.unreadMessages,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(ChatIcon)
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local RobloxTranslator = require(RobloxGui.Modules.RobloxTranslator)
|
||||
|
||||
local ICON_SIZE = 36
|
||||
local BORDER_SIZE = 2
|
||||
local PADDING = 12
|
||||
local DIVIDER_SIZE = 1
|
||||
|
||||
local MenuCell = Roact.PureComponent:extend("MenuCell")
|
||||
|
||||
MenuCell.validateProps = t.strictInterface({
|
||||
layoutOrder = t.integer,
|
||||
icon = t.optional(t.union(t.table, t.string)),
|
||||
iconComponent = t.optional(t.table),
|
||||
localizationKey = t.string,
|
||||
|
||||
height = t.numberPositive,
|
||||
|
||||
hasDivider = t.boolean,
|
||||
isSelected = t.boolean,
|
||||
})
|
||||
|
||||
function MenuCell:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
local font = style.Font
|
||||
|
||||
local text = RobloxTranslator:FormatByKey(self.props.localizationKey)
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, self.props.height),
|
||||
}, {
|
||||
SelectedFrame = self.props.isSelected and Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, BORDER_SIZE * 2, 1, BORDER_SIZE * 2),
|
||||
Position = UDim2.fromScale(0.5, 0.5),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
}, {
|
||||
TopBorder = Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 0, BORDER_SIZE),
|
||||
BackgroundTransparency = theme.SystemPrimaryOnHover.Transparency,
|
||||
BackgroundColor3 = theme.SystemPrimaryOnHover.Color,
|
||||
}),
|
||||
|
||||
LeftBorder = Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(0, BORDER_SIZE, 1, 0),
|
||||
BackgroundTransparency = theme.SystemPrimaryOnHover.Transparency,
|
||||
BackgroundColor3 = theme.SystemPrimaryOnHover.Color,
|
||||
}),
|
||||
|
||||
RightBorder = Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(0, BORDER_SIZE, 1, 0),
|
||||
Position = UDim2.fromScale(1, 0),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
BackgroundTransparency = theme.SystemPrimaryOnHover.Transparency,
|
||||
BackgroundColor3 = theme.SystemPrimaryOnHover.Color,
|
||||
}),
|
||||
|
||||
BottomBorder = Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 0, BORDER_SIZE),
|
||||
Position = UDim2.fromScale(0, 1),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
BackgroundTransparency = theme.SystemPrimaryOnHover.Transparency,
|
||||
BackgroundColor3 = theme.SystemPrimaryOnHover.Color,
|
||||
}),
|
||||
}),
|
||||
|
||||
CellContents = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
Padding = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
Padding = Roact.createElement("UIPadding", {
|
||||
PaddingLeft = UDim.new(0, PADDING),
|
||||
PaddingRight = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
IconFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 1,
|
||||
Size = UDim2.fromOffset(ICON_SIZE, ICON_SIZE),
|
||||
}, {
|
||||
IconLabel = self.props.icon ~= nil and Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
Image = self.props.icon,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
ImageTransparency = theme.IconEmphasis.Transparency,
|
||||
ImageColor3 = theme.IconEmphasis.Color,
|
||||
}),
|
||||
|
||||
IconComponent = self.props.iconComponent ~= nil and Roact.createElement(self.props.iconComponent),
|
||||
}),
|
||||
|
||||
Text = Roact.createElement("TextLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 2,
|
||||
Size = UDim2.new(1, -(PADDING + ICON_SIZE), 1, 0),
|
||||
|
||||
Text = text,
|
||||
Font = font.Header2.Font,
|
||||
TextSize = font.BaseSize * font.Header2.RelativeSize,
|
||||
TextColor3 = theme.TextEmphasis.Color,
|
||||
TextTransparency = theme.TextEmphasis.TextTransparency,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Center,
|
||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||
})
|
||||
}),
|
||||
|
||||
Divider = self.props.hasDivider and Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 0, DIVIDER_SIZE),
|
||||
Position = UDim2.fromScale(0, 1),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
BackgroundTransparency = theme.Divider.Transparency,
|
||||
BackgroundColor3 = theme.Divider.Color,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return MenuCell
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
|
||||
local ICON_SIZE = 80
|
||||
local PLACEHOLDER_ICON_SIZE = 44
|
||||
local PADDING = 20
|
||||
|
||||
local TEXT_PADDING_TOP = 25
|
||||
local TEXT_PADDING_BOTTOM = 20
|
||||
|
||||
local DIVIDER_SIZE = 1
|
||||
|
||||
local GAME_ICON_REQUEST_SIZE = 128
|
||||
|
||||
local IMAGE_UNAVAILABLE = Images["icons/imageUnavailable"]
|
||||
local ROUNDED_BACKGROUND_ASSET = Images["component_assets/circle_17"]
|
||||
local ROUNDED_SLICE_CENTER = Rect.new(8, 8, 9, 9)
|
||||
|
||||
local MenuHeader = Roact.PureComponent:extend("MenuHeader")
|
||||
|
||||
MenuHeader.validateProps = t.strictInterface({
|
||||
gameName = t.string,
|
||||
|
||||
layoutOrder = t.integer,
|
||||
height = t.numberPositive,
|
||||
})
|
||||
|
||||
function MenuHeader:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
local font = style.Font
|
||||
|
||||
local gameIconComponent
|
||||
if game.GameId == 0 then
|
||||
gameIconComponent = Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
Image = ROUNDED_BACKGROUND_ASSET,
|
||||
SliceCenter = ROUNDED_SLICE_CENTER,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
Size = UDim2.fromOffset(ICON_SIZE, ICON_SIZE),
|
||||
ImageColor3 = style.Theme.PlaceHolder.Color,
|
||||
ImageTransparency = style.Theme.PlaceHolder.Transparency,
|
||||
}, {
|
||||
PlaceholderIcon = Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromOffset(PLACEHOLDER_ICON_SIZE, PLACEHOLDER_ICON_SIZE),
|
||||
Position = UDim2.fromScale(0.5, 0.5),
|
||||
Image = IMAGE_UNAVAILABLE,
|
||||
ImageColor3 = style.Theme.UIDefault.Color,
|
||||
ImageTransparency = style.Theme.UIDefault.Transparency,
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
}),
|
||||
})
|
||||
else
|
||||
local iconUrl = ("rbxthumb://type=GameIcon&id=%d&w=%d&h=%d"):format(
|
||||
game.GameId,
|
||||
GAME_ICON_REQUEST_SIZE,
|
||||
GAME_ICON_REQUEST_SIZE
|
||||
)
|
||||
|
||||
gameIconComponent = Roact.createElement("ImageLabel", {
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromOffset(ICON_SIZE, ICON_SIZE),
|
||||
Image = iconUrl,
|
||||
})
|
||||
end
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, self.props.height),
|
||||
}, {
|
||||
ContentsFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
Padding = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
Padding = Roact.createElement("UIPadding", {
|
||||
PaddingLeft = UDim.new(0, PADDING),
|
||||
PaddingRight = UDim.new(0, PADDING),
|
||||
}),
|
||||
|
||||
GameIcon = gameIconComponent,
|
||||
|
||||
TextFrame = Roact.createElement("Frame", {
|
||||
LayoutOrder = 2,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -(ICON_SIZE + PADDING), 1, 0),
|
||||
}, {
|
||||
TextLabel = Roact.createElement("TextLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 1, -(TEXT_PADDING_TOP + TEXT_PADDING_BOTTOM)),
|
||||
Position = UDim2.fromOffset(0, TEXT_PADDING_TOP),
|
||||
|
||||
Font = font.Header1.Font,
|
||||
Text = self.props.gameName,
|
||||
TextSize = font.BaseSize * font.Header1.RelativeSize,
|
||||
TextColor3 = theme.TextEmphasis.Color,
|
||||
TextTransparency = theme.TextEmphasis.TextTransparency,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
TextTruncate = Enum.TextTruncate.AtEnd,
|
||||
TextWrapped = true,
|
||||
}),
|
||||
})
|
||||
}),
|
||||
|
||||
Divider = Roact.createElement("Frame", {
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 0, DIVIDER_SIZE),
|
||||
Position = UDim2.fromScale(0, 1),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
BackgroundTransparency = theme.Divider.Transparency,
|
||||
BackgroundColor3 = theme.Divider.Color,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
gameName = state.gameInfo.name,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(MenuHeader)
|
||||
+549
@@ -0,0 +1,549 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local ContextActionService = game:GetService("ContextActionService")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local Cryo = require(CorePackages.Cryo)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
|
||||
local MenuHeader = require(script.MenuHeader)
|
||||
local ChatIcon = require(script.ChatIcon)
|
||||
local MenuCell = require(script.MenuCell)
|
||||
local BottomBar = require(script.BottomBar)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
local BackpackModule = require(RobloxGui.Modules.BackpackScript)
|
||||
local EmotesModule = require(RobloxGui.Modules.EmotesMenu.EmotesMenuMaster)
|
||||
local ChatModule = require(RobloxGui.Modules.ChatSelector)
|
||||
local PlayerListMaster = require(RobloxGui.Modules.PlayerList.PlayerListManager)
|
||||
|
||||
local isNewInGameMenuEnabled = require(RobloxGui.Modules.isNewInGameMenuEnabled)
|
||||
local InGameMenuConstants = require(RobloxGui.Modules.InGameMenu.Resources.Constants)
|
||||
|
||||
local TOGGLE_GAMEPAD_MENU_ACTION = "TopBarGamepadToggleGamepadMenu"
|
||||
local FREEZE_CONTROLLER_ACTION_NAME = "TopBarGamepadFreezeController"
|
||||
local CLOSEMENU_ACTION_NAME = "TopBarGamepadCloseMenu"
|
||||
local LEAVE_GAME_ACTION_NAME = "TopBarGamepadLeaveGame"
|
||||
local RESPAWN_ACTION_NAME = "TopBarGamepadRespawnAction"
|
||||
local MOVE_SLECTION_ACTION_NAME = "TopBarGamepadMoveSelection"
|
||||
local ACTIVATE_SELECTION_ACTION_NAME = "TopBarGamepadActivateSelection"
|
||||
local GO_TO_TOP_ACTION_NAME = "TopBarGamepadMoveSelectionTop"
|
||||
local GO_TO_BOTTOM_ACTION_NAME = "TopBarGamepadMoveSelectionBottom"
|
||||
|
||||
local THUMBSTICK_MOVE_COOLDOWN = 0.15
|
||||
|
||||
local MENU_ICON = Images["icons/logo/block"]
|
||||
local LEADERBOARD_ICON_ON = "rbxasset://textures/ui/TopBar/leaderboardOn.png"
|
||||
local LEADERBOARD_ICON_OFF = "rbxasset://textures/ui/TopBar/leaderboardOff.png"
|
||||
local EMOTES_ICON_ON = "rbxasset://textures/ui/TopBar/emotesOn.png"
|
||||
local EMOTES_ICON_OFF = "rbxasset://textures/ui/TopBar/emotesOff.png"
|
||||
local INVENTORY_ICON_ON = "rbxasset://textures/ui/TopBar/inventoryOn.png"
|
||||
local INVENTORY_ICON_OFF = "rbxasset://textures/ui/TopBar/inventoryOff.png"
|
||||
local RESPAWN_ICON = Images["icons/actions/respawn"]
|
||||
local LEAVE_ICON = Images["icons/navigation/close"]
|
||||
|
||||
local MENU_BACKGROUND_ASSET = Images["component_assets/circle_17"]
|
||||
local MENU_SLICE_CENTER = Rect.new(8, 8, 9, 9)
|
||||
|
||||
local MENU_SIZE_X = 336
|
||||
local HEADER_HEIGHT = 120
|
||||
local CELL_HEIGHT = 56
|
||||
|
||||
local GAMEPAD_MENU_MOUNT_TAG = "gamepadMenuMount"
|
||||
local GAMEPAD_MENU_UPDATE_TAG = "gamepadMenuUpdate"
|
||||
|
||||
local GAMEPAD_MENU_KEY = "GamepadMenu"
|
||||
|
||||
local GamepadMenu = Roact.PureComponent:extend("GamepadMenu")
|
||||
|
||||
GamepadMenu.validateProps = t.strictInterface({
|
||||
chatEnabled = t.boolean,
|
||||
leaderboardEnabled = t.boolean,
|
||||
emotesEnabled = t.boolean,
|
||||
backpackEnabled = t.boolean,
|
||||
|
||||
respawnEnabled = t.boolean,
|
||||
|
||||
leaderboardOpen = t.boolean,
|
||||
backpackOpen = t.boolean,
|
||||
emotesOpen = t.boolean,
|
||||
})
|
||||
|
||||
function GamepadMenu:init()
|
||||
debug.profilebegin(GAMEPAD_MENU_MOUNT_TAG)
|
||||
|
||||
self:setState({
|
||||
visible = false,
|
||||
|
||||
selectedIndex = 1,
|
||||
menuActions = {}
|
||||
})
|
||||
|
||||
self.boundMenuOpenActions = false
|
||||
|
||||
self.toggleMenuVisibleAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
self:setState({
|
||||
visible = not self.state.visible,
|
||||
})
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
|
||||
self.closeMenuAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
self:setState({
|
||||
visible = false,
|
||||
})
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
|
||||
self.leaveGameMenuAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
GamepadMenu.leaveGame()
|
||||
|
||||
self:setState({
|
||||
visible = false,
|
||||
})
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
|
||||
self.respawnMenuAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
GamepadMenu.respawnCharacter()
|
||||
|
||||
self:setState({
|
||||
visible = false,
|
||||
})
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
|
||||
self.lastThumbStickMove = 0
|
||||
|
||||
self.moveSelectionAction = function(actionName, userInputState, input)
|
||||
if userInputState == Enum.UserInputState.Begin then
|
||||
if input.KeyCode == Enum.KeyCode.DPadUp then
|
||||
if self.state.selectedIndex > 1 then
|
||||
self:setState({
|
||||
selectedIndex = self.state.selectedIndex - 1,
|
||||
})
|
||||
end
|
||||
return Enum.ContextActionResult.Sink
|
||||
elseif input.KeyCode == Enum.KeyCode.DPadDown then
|
||||
if self.state.selectedIndex < #self.state.menuActions then
|
||||
self:setState({
|
||||
selectedIndex = self.state.selectedIndex + 1,
|
||||
})
|
||||
end
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
elseif input.KeyCode == Enum.KeyCode.Thumbstick1 then
|
||||
if tick() - self.lastThumbStickMove < THUMBSTICK_MOVE_COOLDOWN then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
if input.Position.Y > 0.8 then
|
||||
if self.state.selectedIndex > 1 then
|
||||
self:setState({
|
||||
selectedIndex = self.state.selectedIndex - 1,
|
||||
})
|
||||
self.lastThumbStickMove = tick()
|
||||
end
|
||||
return Enum.ContextActionResult.Pass
|
||||
elseif input.Position.Y < -0.8 then
|
||||
if self.state.selectedIndex < #self.state.menuActions then
|
||||
self:setState({
|
||||
selectedIndex = self.state.selectedIndex + 1,
|
||||
})
|
||||
self.lastThumbStickMove = tick()
|
||||
end
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
end
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
self.goToTopAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
self:setState({
|
||||
selectedIndex = 1,
|
||||
})
|
||||
end
|
||||
|
||||
self.goToBottomAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
self:setState({
|
||||
selectedIndex = #self.state.menuActions,
|
||||
})
|
||||
end
|
||||
|
||||
self.activateSelectionAction = function(actionName, userInputState, input)
|
||||
if userInputState ~= Enum.UserInputState.Begin then
|
||||
return Enum.ContextActionResult.Pass
|
||||
end
|
||||
|
||||
local action = self.state.menuActions[self.state.selectedIndex]
|
||||
action.onActivated()
|
||||
|
||||
self:setState({
|
||||
visible = false,
|
||||
})
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
|
||||
self.overlayDismiss = function()
|
||||
self:setState({
|
||||
visible = false,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function GamepadMenu.openSettingsMenu()
|
||||
if isNewInGameMenuEnabled() then
|
||||
-- todo: move InGameMenu to a script global when removing isNewInGameMenuEnabled
|
||||
local InGameMenu = require(RobloxGui.Modules.InGameMenu)
|
||||
InGameMenu.openGameSettingsPage()
|
||||
else
|
||||
local MenuModule = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
MenuModule:SetVisibility(true, nil, MenuModule.Instance.GameSettingsPage, true,
|
||||
InGameMenuConstants.AnalyticsMenuOpenTypes.SettingsTriggered)
|
||||
end
|
||||
end
|
||||
|
||||
function GamepadMenu.toggleChatVisible()
|
||||
ChatModule:ToggleVisibility()
|
||||
end
|
||||
|
||||
function GamepadMenu.toggleLeaderboard()
|
||||
PlayerListMaster:SetVisibility(not PlayerListMaster:GetSetVisible())
|
||||
end
|
||||
|
||||
function GamepadMenu.toggleEmotesMenu()
|
||||
if EmotesModule:isOpen() then
|
||||
EmotesModule:close()
|
||||
else
|
||||
EmotesModule:open()
|
||||
end
|
||||
end
|
||||
|
||||
function GamepadMenu.toggleBackpack()
|
||||
BackpackModule:OpenClose()
|
||||
end
|
||||
|
||||
function GamepadMenu.leaveGame()
|
||||
local MenuModule = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
MenuModule:SetVisibility(true, false, MenuModule.Instance.LeaveGamePage, true,
|
||||
InGameMenuConstants.AnalyticsMenuOpenTypes.GamepadLeaveGame)
|
||||
end
|
||||
|
||||
function GamepadMenu.respawnCharacter()
|
||||
local MenuModule = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
MenuModule:SetVisibility(true, false, MenuModule.Instance.ResetCharacterPage, true,
|
||||
InGameMenuConstants.AnalyticsMenuOpenTypes.GamepadResetCharacter)
|
||||
end
|
||||
|
||||
function GamepadMenu.getMenuActionsFromProps(props)
|
||||
local menuActions = {}
|
||||
|
||||
table.insert(menuActions, {
|
||||
name = "Menu",
|
||||
icon = MENU_ICON,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Menu",
|
||||
onActivated = GamepadMenu.openSettingsMenu,
|
||||
})
|
||||
|
||||
if props.chatEnabled and not TenFootInterface:IsEnabled() then
|
||||
table.insert(menuActions, {
|
||||
name = "Chat",
|
||||
icon = nil,
|
||||
iconComponent = ChatIcon,
|
||||
localizationKey = "CoreScripts.TopBar.Chat",
|
||||
onActivated = GamepadMenu.toggleChatVisible,
|
||||
})
|
||||
end
|
||||
|
||||
if props.leaderboardEnabled or TenFootInterface:IsEnabled() then
|
||||
local icon
|
||||
if props.leaderboardOpen then
|
||||
icon = LEADERBOARD_ICON_ON
|
||||
else
|
||||
icon = LEADERBOARD_ICON_OFF
|
||||
end
|
||||
|
||||
table.insert(menuActions, {
|
||||
name = "Leaderboard",
|
||||
icon = icon,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Leaderboard",
|
||||
onActivated = GamepadMenu.toggleLeaderboard,
|
||||
})
|
||||
end
|
||||
|
||||
if props.emotesEnabled then
|
||||
local icon
|
||||
if props.emotesOpen then
|
||||
icon = EMOTES_ICON_ON
|
||||
else
|
||||
icon = EMOTES_ICON_OFF
|
||||
end
|
||||
|
||||
table.insert(menuActions, {
|
||||
name = "Emotes",
|
||||
icon = icon,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Emotes",
|
||||
onActivated = GamepadMenu.toggleEmotesMenu,
|
||||
})
|
||||
end
|
||||
|
||||
if props.backpackEnabled then
|
||||
local icon
|
||||
if props.backpackOpen then
|
||||
icon = INVENTORY_ICON_ON
|
||||
else
|
||||
icon = INVENTORY_ICON_OFF
|
||||
end
|
||||
|
||||
table.insert(menuActions, {
|
||||
name = "Inventory",
|
||||
icon = icon,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Inventory",
|
||||
onActivated = GamepadMenu.toggleBackpack,
|
||||
})
|
||||
end
|
||||
|
||||
if props.respawnEnabled then
|
||||
table.insert(menuActions, {
|
||||
name = "Respawn",
|
||||
icon = RESPAWN_ICON,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Respawn",
|
||||
onActivated = GamepadMenu.respawnCharacter,
|
||||
})
|
||||
end
|
||||
|
||||
table.insert(menuActions, {
|
||||
name = "Leave",
|
||||
icon = LEAVE_ICON,
|
||||
iconComponent = nil,
|
||||
localizationKey = "CoreScripts.TopBar.Leave",
|
||||
onActivated = GamepadMenu.leaveGame,
|
||||
})
|
||||
|
||||
return menuActions
|
||||
end
|
||||
|
||||
function GamepadMenu.getDerivedStateFromProps(nextProps, prevState)
|
||||
local menuActions = GamepadMenu.getMenuActionsFromProps(nextProps)
|
||||
|
||||
local selectedIndex = prevState.selectedIndex or 1
|
||||
if selectedIndex > #menuActions then
|
||||
selectedIndex = #menuActions
|
||||
end
|
||||
|
||||
return Cryo.Dictionary.join(prevState, {
|
||||
selectedIndex = selectedIndex,
|
||||
menuActions = menuActions
|
||||
})
|
||||
end
|
||||
|
||||
function GamepadMenu:render()
|
||||
return withStyle(function(style)
|
||||
local theme = style.Theme
|
||||
|
||||
local menuChildren = {}
|
||||
|
||||
menuChildren.Layout = Roact.createElement("UIListLayout", {
|
||||
FillDirection = Enum.FillDirection.Vertical,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Center,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Top,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
})
|
||||
|
||||
menuChildren.MenuHeader = Roact.createElement(MenuHeader, {
|
||||
layoutOrder = 1,
|
||||
height = HEADER_HEIGHT,
|
||||
})
|
||||
|
||||
for index, action in ipairs(self.state.menuActions) do
|
||||
menuChildren[action.name] = Roact.createElement(MenuCell, {
|
||||
layoutOrder = index + 1,
|
||||
|
||||
icon = action.icon,
|
||||
iconComponent = action.iconComponent,
|
||||
localizationKey = action.localizationKey,
|
||||
|
||||
height = CELL_HEIGHT,
|
||||
|
||||
hasDivider = index ~= #self.state.menuActions,
|
||||
isSelected = index == self.state.selectedIndex,
|
||||
})
|
||||
end
|
||||
|
||||
local menuHeight = HEADER_HEIGHT + (#self.state.menuActions * CELL_HEIGHT)
|
||||
|
||||
return Roact.createElement("TextButton", {
|
||||
Visible = self.state.visible,
|
||||
Text = "",
|
||||
BackgroundTransparency = theme.Overlay.Transparency,
|
||||
BackgroundColor3 = theme.Overlay.Color,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
BorderSizePixel = 0,
|
||||
ZIndex = 10,
|
||||
|
||||
[Roact.Event.Activated] = self.overlayDismiss,
|
||||
}, {
|
||||
Menu = Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
Image = MENU_BACKGROUND_ASSET,
|
||||
SliceCenter = MENU_SLICE_CENTER,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
ImageTransparency = theme.BackgroundUIContrast.Transparency,
|
||||
ImageColor3 = theme.BackgroundUIContrast.Color,
|
||||
Size = UDim2.fromOffset(MENU_SIZE_X, menuHeight),
|
||||
Position = UDim2.fromScale(0.5, 0.5),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
}, menuChildren),
|
||||
|
||||
BottomBar = Roact.createElement(BottomBar),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
function GamepadMenu:didMount()
|
||||
ContextActionService:BindCoreAction(
|
||||
TOGGLE_GAMEPAD_MENU_ACTION, self.toggleMenuVisibleAction, false, Enum.KeyCode.ButtonStart)
|
||||
|
||||
debug.profileend(GAMEPAD_MENU_MOUNT_TAG)
|
||||
end
|
||||
|
||||
function GamepadMenu:bindMenuOpenActions()
|
||||
self.boundMenuOpenActions = true
|
||||
|
||||
ContextActionService:BindCoreAction(FREEZE_CONTROLLER_ACTION_NAME, function() end, false, Enum.UserInputType.Gamepad1)
|
||||
ContextActionService:BindCoreAction(CLOSEMENU_ACTION_NAME, self.closeMenuAction, false, Enum.KeyCode.ButtonB)
|
||||
ContextActionService:BindCoreAction(LEAVE_GAME_ACTION_NAME, self.leaveGameMenuAction, false, Enum.KeyCode.ButtonX)
|
||||
ContextActionService:BindCoreAction(RESPAWN_ACTION_NAME, self.respawnMenuAction, false, Enum.KeyCode.ButtonY)
|
||||
ContextActionService:BindCoreAction(
|
||||
ACTIVATE_SELECTION_ACTION_NAME, self.activateSelectionAction, false, Enum.KeyCode.ButtonA)
|
||||
ContextActionService:BindCoreAction(
|
||||
MOVE_SLECTION_ACTION_NAME,
|
||||
self.moveSelectionAction,
|
||||
false,
|
||||
Enum.KeyCode.Thumbstick1,
|
||||
Enum.KeyCode.DPadUp,
|
||||
Enum.KeyCode.DPadDown
|
||||
)
|
||||
ContextActionService:BindCoreAction(GO_TO_TOP_ACTION_NAME, self.goToTopAction, false, Enum.KeyCode.ButtonL2)
|
||||
ContextActionService:BindCoreAction(GO_TO_BOTTOM_ACTION_NAME, self.goToBottomAction, false, Enum.KeyCode.ButtonR2)
|
||||
ContextActionService:BindCoreAction(
|
||||
TOGGLE_GAMEPAD_MENU_ACTION, self.toggleMenuVisibleAction, false, Enum.KeyCode.ButtonStart)
|
||||
end
|
||||
|
||||
function GamepadMenu:unbindMenuOpenActions()
|
||||
self.boundMenuOpenActions = false
|
||||
|
||||
ContextActionService:UnbindCoreAction(FREEZE_CONTROLLER_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(CLOSEMENU_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(ACTIVATE_SELECTION_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(LEAVE_GAME_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(RESPAWN_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(MOVE_SLECTION_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(GO_TO_TOP_ACTION_NAME)
|
||||
ContextActionService:UnbindCoreAction(GO_TO_BOTTOM_ACTION_NAME)
|
||||
end
|
||||
|
||||
function GamepadMenu:unbindAllActions()
|
||||
if self.boundMenuOpenActions then
|
||||
self:unbindMenuOpenActions()
|
||||
end
|
||||
|
||||
ContextActionService:UnbindCoreAction(TOGGLE_GAMEPAD_MENU_ACTION)
|
||||
end
|
||||
|
||||
function GamepadMenu:willUpdate()
|
||||
debug.profilebegin(GAMEPAD_MENU_UPDATE_TAG)
|
||||
end
|
||||
|
||||
function GamepadMenu:didUpdate(prevProps, prevState)
|
||||
if self.state.visible ~= prevState.visible then
|
||||
if self.state.visible then
|
||||
self:bindMenuOpenActions()
|
||||
|
||||
if self.state.selectedIndex ~= 1 then
|
||||
self:setState({
|
||||
selectedIndex = 1,
|
||||
})
|
||||
end
|
||||
|
||||
self.savedSelectedCoreObject = GuiService.SelectedCoreObject
|
||||
GuiService.SelectedCoreObject = nil
|
||||
self.savedSelectedObject = GuiService.SelectedObject
|
||||
GuiService.SelectedObject = nil
|
||||
|
||||
GuiService:SetMenuIsOpen(true, GAMEPAD_MENU_KEY)
|
||||
else
|
||||
self:unbindMenuOpenActions()
|
||||
|
||||
if GuiService.SelectedCoreObject == nil then
|
||||
GuiService.SelectedCoreObject = self.savedSelectedCoreObject
|
||||
end
|
||||
if GuiService.SelectedObject == nil then
|
||||
GuiService.SelectedObject = self.savedSelectedObject
|
||||
end
|
||||
|
||||
GuiService:SetMenuIsOpen(false, GAMEPAD_MENU_KEY)
|
||||
end
|
||||
end
|
||||
|
||||
debug.profileend(GAMEPAD_MENU_UPDATE_TAG)
|
||||
end
|
||||
|
||||
function GamepadMenu:willUnmount()
|
||||
self:unbindAllActions()
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
local topBarEnabled = state.displayOptions.topbarEnabled
|
||||
|
||||
return {
|
||||
chatEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Chat] and topBarEnabled,
|
||||
leaderboardEnabled = state.coreGuiEnabled[Enum.CoreGuiType.PlayerList] and topBarEnabled,
|
||||
emotesEnabled = state.moreMenu.emotesEnabled and state.coreGuiEnabled[Enum.CoreGuiType.EmotesMenu] and topBarEnabled,
|
||||
backpackEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Backpack] and topBarEnabled,
|
||||
|
||||
respawnEnabled = state.respawn.enabled,
|
||||
|
||||
leaderboardOpen = state.moreMenu.leaderboardOpen,
|
||||
backpackOpen = state.moreMenu.backpackOpen,
|
||||
emotesOpen = state.moreMenu.emotesOpen,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(GamepadMenu)
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
local Constants = require(TopBar.Constants)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
|
||||
local HEALTHBAR_SIZE = UDim2.new(0, 80, 0, 6)
|
||||
local HEALTHBAR_SIZE_TENFOOT = UDim2.new(0, 220, 0, 16)
|
||||
|
||||
local HEALTHBAR_OFFSET = 4
|
||||
local HEALTHBAR_OFFSET_TENFOOT = 0
|
||||
|
||||
local HealthBar = Roact.PureComponent:extend("HealthBar")
|
||||
|
||||
HealthBar.validateProps = t.strictInterface({
|
||||
layoutOrder = t.integer,
|
||||
|
||||
healthEnabled = t.boolean,
|
||||
health = t.number,
|
||||
maxHealth = t.number,
|
||||
})
|
||||
|
||||
local function color3ToVector3(color3)
|
||||
return Vector3.new(color3.r, color3.g, color3.b)
|
||||
end
|
||||
|
||||
local healthColorToPosition = {
|
||||
[color3ToVector3(Constants.HealthRedColor)] = 0.1,
|
||||
[color3ToVector3(Constants.HealthYellowColor)] = 0.5,
|
||||
[color3ToVector3(Constants.HealthGreenColor)] = 0.8,
|
||||
}
|
||||
local redHealthFraction = 0.1
|
||||
local redHealthColor = Constants.HealthRedColor
|
||||
local greenHealthFraction = 0.8
|
||||
local greenHealthColor = Constants.HealthGreenColor
|
||||
|
||||
local function getHealthBarColor(healthPercent)
|
||||
if healthPercent <= redHealthFraction then
|
||||
return redHealthColor
|
||||
elseif healthPercent >= greenHealthFraction then
|
||||
return greenHealthColor
|
||||
end
|
||||
|
||||
-- Shepard's Interpolation
|
||||
local numeratorSum = Vector3.new(0,0,0)
|
||||
local denominatorSum = 0
|
||||
for colorSampleValue, samplePoint in pairs(healthColorToPosition) do
|
||||
local distance = healthPercent - samplePoint
|
||||
if distance == 0 then
|
||||
-- If we are exactly on an existing sample value then we don't need to interpolate
|
||||
return Color3.new(colorSampleValue.x, colorSampleValue.y, colorSampleValue.z)
|
||||
else
|
||||
local wi = 1 / (distance*distance)
|
||||
numeratorSum = numeratorSum + wi * colorSampleValue
|
||||
denominatorSum = denominatorSum + wi
|
||||
end
|
||||
end
|
||||
local result = numeratorSum / denominatorSum
|
||||
return Color3.new(result.x, result.y, result.z)
|
||||
end
|
||||
|
||||
function HealthBar:render()
|
||||
local healthVisible = self.props.healthEnabled
|
||||
and self.props.health < self.props.maxHealth
|
||||
|
||||
local healthPercent = 1
|
||||
if self.props.isDead then
|
||||
healthPercent = 0
|
||||
elseif self.props.maxHealth > 0 then
|
||||
healthPercent = self.props.health / self.props.maxHealth
|
||||
end
|
||||
|
||||
local healthBarSize = HEALTHBAR_SIZE
|
||||
if TenFootInterface:IsEnabled() then
|
||||
healthBarSize = HEALTHBAR_SIZE_TENFOOT
|
||||
end
|
||||
|
||||
local healthBarOffset = HEALTHBAR_OFFSET
|
||||
if TenFootInterface:IsEnabled() then
|
||||
healthBarOffset = HEALTHBAR_OFFSET_TENFOOT
|
||||
end
|
||||
|
||||
local healthBarBase = "rbxasset://textures/ui/TopBar/HealthBarBase.png"
|
||||
local healthBar = "rbxasset://textures/ui/TopBar/HealthBar.png"
|
||||
local sliceCenter = Rect.new(3, 3, 4, 4)
|
||||
if TenFootInterface:IsEnabled() then
|
||||
healthBarBase = "rbxasset://textures/ui/TopBar/HealthBarBaseTV.png"
|
||||
healthBar = "rbxasset://textures/ui/TopBar/HealthBarTV.png"
|
||||
sliceCenter = Rect.new(8, 8, 9, 9)
|
||||
end
|
||||
|
||||
local healthBarColor = getHealthBarColor(healthPercent)
|
||||
return Roact.createElement("Frame", {
|
||||
Visible = healthVisible,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(healthBarSize.X, UDim.new(1, 0)),
|
||||
}, {
|
||||
Padding = Roact.createElement("UIPadding", {
|
||||
PaddingTop = UDim.new(0, healthBarOffset),
|
||||
}),
|
||||
|
||||
HealthBar = Roact.createElement("ImageLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Image = healthBarBase,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = sliceCenter,
|
||||
Size = healthBarSize,
|
||||
Position = UDim2.fromScale(0, 0.5),
|
||||
AnchorPoint = Vector2.new(0, 0.5),
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
}, {
|
||||
Fill = Roact.createElement("ImageLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Image = healthBar,
|
||||
ImageColor3 = healthBarColor,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = sliceCenter,
|
||||
Size = UDim2.fromScale(healthPercent, 1),
|
||||
}),
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
health = state.health.currentHealth,
|
||||
maxHealth = state.health.maxHealth,
|
||||
healthEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Health],
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(HealthBar)
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local Otter = require(CorePackages.Otter)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local PolicyService = require(RobloxGui.Modules.Common.PolicyService)
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
local Constants = require(TopBar.Constants)
|
||||
|
||||
local MOTOR_OPTIONS = {
|
||||
frequency = 0.75,
|
||||
dampingRatio = 1,
|
||||
}
|
||||
|
||||
local RED_OVERLAY_COLOR = Color3.fromRGB(187, 0, 4)
|
||||
local WHITE_OVERLAY_COLOR = Color3.new(1, 1, 1)
|
||||
|
||||
local HurtOverlay = Roact.PureComponent:extend("HurtOverlay")
|
||||
|
||||
HurtOverlay.validateProps = t.strictInterface({
|
||||
healthEnabled = t.boolean,
|
||||
health = t.number,
|
||||
maxHealth = t.number,
|
||||
isDead = t.boolean,
|
||||
})
|
||||
|
||||
function HurtOverlay:init()
|
||||
self.state = {
|
||||
isAnimating = false,
|
||||
}
|
||||
|
||||
self.animationBinding, self.animationBindingUpdate = Roact.createBinding(0)
|
||||
|
||||
self.positionBinding = self.animationBinding:map(function(animation)
|
||||
return UDim2.new(-10 * animation, 0, -10 * animation, 0)
|
||||
end)
|
||||
self.sizeBinding = self.animationBinding:map(function(animation)
|
||||
return UDim2.new(1 + 19 * animation, 0, 1 + 19 * animation, 0)
|
||||
end)
|
||||
|
||||
self.motor = Otter.createSingleMotor(0)
|
||||
self.motor:onStep(function(value)
|
||||
self.animationBindingUpdate(value)
|
||||
end)
|
||||
self.motor:onComplete(function()
|
||||
self:setState({
|
||||
isAnimating = false,
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
function HurtOverlay:render()
|
||||
local overlayVisible = self.props.healthEnabled and self.state.isAnimating
|
||||
|
||||
local hurtOverlayImage = "rbxasset://textures/ui/TopBar/WhiteOverlayAsset.png"
|
||||
local hurtOverlayColor = RED_OVERLAY_COLOR
|
||||
if PolicyService:IsSubjectToChinaPolicies() then
|
||||
hurtOverlayColor = WHITE_OVERLAY_COLOR
|
||||
end
|
||||
|
||||
return Roact.createElement("ImageLabel", {
|
||||
Visible = overlayVisible,
|
||||
BackgroundTransparency = 1,
|
||||
Image = hurtOverlayImage,
|
||||
ImageColor3 = hurtOverlayColor,
|
||||
Size = self.sizeBinding,
|
||||
Position = self.positionBinding,
|
||||
})
|
||||
end
|
||||
|
||||
function HurtOverlay:didUpdate(prevProps, prevState)
|
||||
if self.props.health < prevProps.health then
|
||||
if not (self.props.isDead and prevProps.isDead) then
|
||||
local healthChange = prevProps.health - self.props.health
|
||||
if healthChange / self.props.maxHealth >= Constants.HealthPercentForOverlay then
|
||||
self.motor:setGoal(Otter.instant(0))
|
||||
self.motor:step(0)
|
||||
self.motor:setGoal(Otter.spring(1, MOTOR_OPTIONS))
|
||||
self.motor:start()
|
||||
self:setState({
|
||||
isAnimating = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
health = state.health.currentHealth,
|
||||
maxHealth = state.health.maxHealth,
|
||||
isDead = state.health.isDead,
|
||||
healthEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Health],
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, nil)(HurtOverlay)
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local ImageSetLabel = UIBlox.Core.ImageSet.Label
|
||||
local withStyle = UIBlox.Core.Style.withStyle
|
||||
local Interactable = UIBlox.Core.Control.Interactable
|
||||
local ControlState = UIBlox.Core.Control.Enum.ControlState
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
|
||||
local IconButton = Roact.PureComponent:extend("IconButton")
|
||||
|
||||
local BACKGROUND_SIZE = 32
|
||||
|
||||
local OVERLAY_ASSET = Images["component_assets/circle_17"]
|
||||
|
||||
IconButton.validateProps = t.strictInterface({
|
||||
icon = t.union(t.string, t.table),
|
||||
iconSize = t.integer,
|
||||
|
||||
onActivated = t.callback,
|
||||
onHover = t.optional(t.callback),
|
||||
})
|
||||
|
||||
function IconButton:init()
|
||||
self:setState({
|
||||
controlState = ControlState.Default,
|
||||
})
|
||||
|
||||
self.controlStateUpdated = function(oldControlState, newControlState)
|
||||
if self.props.onHover and newControlState == ControlState.Hover then
|
||||
self.props.onHover()
|
||||
end
|
||||
self:setState({
|
||||
controlState = newControlState,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function IconButton:render()
|
||||
return withStyle(function(style)
|
||||
local overlayTheme = {
|
||||
Color = Color3.new(1, 1, 1),
|
||||
Transparency = 1,
|
||||
}
|
||||
|
||||
if self.state.controlState == ControlState.Pressed then
|
||||
overlayTheme = style.Theme.BackgroundOnPress
|
||||
elseif self.state.controlState == ControlState.Hover then
|
||||
overlayTheme = style.Theme.BackgroundOnHover
|
||||
end
|
||||
|
||||
return Roact.createElement(Interactable, {
|
||||
onStateChanged = self.controlStateUpdated,
|
||||
|
||||
ZIndex = 1,
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.fromScale(0, 1),
|
||||
AnchorPoint = Vector2.new(0, 1),
|
||||
Size = UDim2.fromOffset(BACKGROUND_SIZE, BACKGROUND_SIZE),
|
||||
Image = "rbxasset://textures/ui/TopBar/iconBase.png",
|
||||
|
||||
[Roact.Event.Activated] = self.props.onActivated,
|
||||
}, {
|
||||
Icon = Roact.createElement(ImageSetLabel, {
|
||||
Size = UDim2.fromOffset(self.props.iconSize, self.props.iconSize),
|
||||
Position = UDim2.fromScale(0.5, 0.5),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
BackgroundTransparency = 1,
|
||||
Image = self.props.icon,
|
||||
ImageColor3 = style.Theme.IconEmphasis.Color,
|
||||
ImageTransparency = style.Theme.IconEmphasis.Transparency,
|
||||
ZIndex = 1,
|
||||
}),
|
||||
|
||||
StateOverlay = Roact.createElement(ImageSetLabel, {
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
Image = OVERLAY_ASSET,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = Rect.new(8, 8, 8, 8),
|
||||
|
||||
ImageColor3 = overlayTheme.Color,
|
||||
ImageTransparency = overlayTheme.Transparency,
|
||||
Size = UDim2.fromScale(1, 1),
|
||||
ZIndex = 2,
|
||||
}),
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
return IconButton
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
local isNewInGameMenuEnabled = require(RobloxGui.Modules.isNewInGameMenuEnabled)
|
||||
local InGameMenuConstants = require(RobloxGui.Modules.InGameMenu.Resources.Constants)
|
||||
|
||||
local InGameMenu
|
||||
if isNewInGameMenuEnabled() then
|
||||
InGameMenu = require(RobloxGui.Modules.InGameMenu)
|
||||
end
|
||||
|
||||
local IconButton = require(script.Parent.IconButton)
|
||||
|
||||
local GetFFlagInGameMenuOpenOnHover = require(RobloxGui.Modules.Flags.GetFFlagInGameMenuOpenOnHover)
|
||||
local GetFFlagInGameMenuIconTooltip = require(RobloxGui.Modules.Flags.GetFFlagInGameMenuIconTooltip)
|
||||
|
||||
local MenuIcon = Roact.PureComponent:extend("MenuIcon")
|
||||
|
||||
local BACKGROUND_SIZE = 32
|
||||
local ICON_SIZE = 24
|
||||
|
||||
MenuIcon.validateProps = t.strictInterface({
|
||||
layoutOrder = t.integer,
|
||||
})
|
||||
|
||||
function MenuIcon:init()
|
||||
self.menuIconActivated = function()
|
||||
if isNewInGameMenuEnabled() then
|
||||
InGameMenu.openInGameMenu()
|
||||
else
|
||||
local SettingsHub = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
SettingsHub:ToggleVisibility(InGameMenuConstants.AnalyticsMenuOpenTypes.TopbarButton)
|
||||
end
|
||||
end
|
||||
self.menuIconOnHover = function()
|
||||
if isNewInGameMenuEnabled() then
|
||||
InGameMenu.openInGameMenu()
|
||||
if GetFFlagInGameMenuIconTooltip() then
|
||||
InGameMenu.setMenuIconTooltipOpen(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuIcon:render()
|
||||
return Roact.createElement("Frame", {
|
||||
Visible = not TenFootInterface:IsEnabled(),
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, BACKGROUND_SIZE, 1, 0),
|
||||
LayoutOrder = self.props.layoutOrder
|
||||
}, {
|
||||
Background = Roact.createElement(IconButton, {
|
||||
icon = "rbxasset://textures/ui/TopBar/coloredlogo.png",
|
||||
iconSize = ICON_SIZE,
|
||||
|
||||
onActivated = self.menuIconActivated,
|
||||
onHover = GetFFlagInGameMenuOpenOnHover() and self.menuIconOnHover or nil,
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
return MenuIcon
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local ContextActionService = game:GetService("ContextActionService")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local OverlayContextualMenu = UIBlox.App.Menu.OverlayContextualMenu
|
||||
local MenuDirection = UIBlox.App.Menu.MenuDirection
|
||||
|
||||
local Components = script.Parent.Parent
|
||||
local TopBar = Components.Parent
|
||||
|
||||
local Actions = TopBar.Actions
|
||||
local SetMoreMenuOpen = require(Actions.SetMoreMenuOpen)
|
||||
|
||||
local Constants = require(TopBar.Constants)
|
||||
local InputType = Constants.InputType
|
||||
|
||||
local IconButton = require(script.Parent.IconButton)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
|
||||
local EmotesMenuMaster = require(RobloxGui.Modules.EmotesMenu.EmotesMenuMaster)
|
||||
local BackpackModule = require(RobloxGui.Modules.BackpackScript)
|
||||
local ChatSelector = require(RobloxGui.Modules.ChatSelector)
|
||||
local PlayerListMaster = require(RobloxGui.Modules.PlayerList.PlayerListManager)
|
||||
|
||||
local EmotesConstants = require(RobloxGui.Modules.EmotesMenu.Constants)
|
||||
|
||||
local RobloxTranslator = require(RobloxGui.Modules.RobloxTranslator)
|
||||
|
||||
local MORE_BUTTON_SIZE = 32
|
||||
local ICON_SIZE = 24
|
||||
local MENU_GAP = 12
|
||||
|
||||
local MENU_DEFAULT_SIZE = 300
|
||||
local CONTEXT_MENU_DEFAULT_PADDING = 12
|
||||
local MENU_EXTRA_PADDING = 12
|
||||
local MENU_FULLSCREEN_THRESHOLD = 450
|
||||
|
||||
local CHAT_HIDE_THRESHOLD = 600
|
||||
|
||||
local ESCAPE_CLOSE_MENU_ACTION = "CloseMoreMenuAction"
|
||||
|
||||
local MoreMenu = Roact.PureComponent:extend("MoreMenu")
|
||||
|
||||
MoreMenu.validateProps = t.strictInterface({
|
||||
layoutOrder = t.integer,
|
||||
|
||||
moreMenuOpen = t.boolean,
|
||||
setMoreMenuOpen = t.callback,
|
||||
screenSize = t.Vector2,
|
||||
isSmallTouchDevice = t.boolean,
|
||||
|
||||
topBarEnabled = t.boolean,
|
||||
leaderboardEnabled = t.boolean,
|
||||
emotesEnabled = t.boolean,
|
||||
backpackEnabled = t.boolean,
|
||||
|
||||
leaderboardOpen = t.boolean,
|
||||
backpackOpen = t.boolean,
|
||||
emotesOpen = t.boolean,
|
||||
|
||||
inputType = t.string,
|
||||
})
|
||||
|
||||
function MoreMenu:init()
|
||||
self.chatWasHidden = false
|
||||
|
||||
self.boundAction = false
|
||||
|
||||
self.moreButtonActivated = function()
|
||||
self.props.setMoreMenuOpen(not self.props.moreMenuOpen)
|
||||
end
|
||||
end
|
||||
|
||||
function MoreMenu:render()
|
||||
local menuOptions = {}
|
||||
local hasOptions = false
|
||||
|
||||
local isUsingKeyBoard = self.props.inputType == InputType.MouseAndKeyBoard
|
||||
|
||||
if self.props.leaderboardEnabled and not self.props.isSmallTouchDevice then
|
||||
local leaderboardIcon = "rbxasset://textures/ui/TopBar/leaderboardOn.png"
|
||||
if not self.props.leaderboardOpen then
|
||||
leaderboardIcon = "rbxasset://textures/ui/TopBar/leaderboardOff.png"
|
||||
end
|
||||
|
||||
table.insert(menuOptions, {
|
||||
icon = leaderboardIcon,
|
||||
text = RobloxTranslator:FormatByKey("CoreScripts.TopBar.Leaderboard"),
|
||||
keyCodeLabel = isUsingKeyBoard and Enum.KeyCode.Tab or nil,
|
||||
onActivated = function()
|
||||
PlayerListMaster:SetVisibility(not PlayerListMaster:GetSetVisible())
|
||||
self.props.setMoreMenuOpen(false)
|
||||
end,
|
||||
})
|
||||
hasOptions = true
|
||||
end
|
||||
|
||||
if self.props.emotesEnabled then
|
||||
local emotesIcon = "rbxasset://textures/ui/TopBar/emotesOn.png"
|
||||
if not self.props.emotesOpen then
|
||||
emotesIcon = "rbxasset://textures/ui/TopBar/emotesOff.png"
|
||||
end
|
||||
|
||||
local emotesKeybind = EmotesConstants.EmoteMenuOpenKey
|
||||
|
||||
table.insert(menuOptions, {
|
||||
icon = emotesIcon,
|
||||
text = RobloxTranslator:FormatByKey("CoreScripts.TopBar.Emotes"),
|
||||
keyCodeLabel = isUsingKeyBoard and emotesKeybind or nil,
|
||||
onActivated = function()
|
||||
if EmotesMenuMaster:isOpen() then
|
||||
EmotesMenuMaster:close()
|
||||
else
|
||||
EmotesMenuMaster:open()
|
||||
end
|
||||
self.props.setMoreMenuOpen(false)
|
||||
end,
|
||||
})
|
||||
hasOptions = true
|
||||
end
|
||||
|
||||
if self.props.backpackEnabled then
|
||||
local backpackIcon = "rbxasset://textures/ui/TopBar/inventoryOn.png"
|
||||
if not self.props.backpackOpen then
|
||||
backpackIcon = "rbxasset://textures/ui/TopBar/inventoryOff.png"
|
||||
end
|
||||
|
||||
table.insert(menuOptions, {
|
||||
icon = backpackIcon,
|
||||
text = RobloxTranslator:FormatByKey("CoreScripts.TopBar.Inventory"),
|
||||
keyCodeLabel = isUsingKeyBoard and Enum.KeyCode.Backquote or nil,
|
||||
onActivated = function()
|
||||
BackpackModule:OpenClose()
|
||||
self.props.setMoreMenuOpen(false)
|
||||
end,
|
||||
})
|
||||
hasOptions = true
|
||||
end
|
||||
|
||||
local moreMenuSize = UDim2.new(0, MENU_DEFAULT_SIZE + CONTEXT_MENU_DEFAULT_PADDING * 2, 0, self.props.screenSize.Y)
|
||||
if self.props.screenSize.X < MENU_FULLSCREEN_THRESHOLD then
|
||||
moreMenuSize = UDim2.new(0, self.props.screenSize.X - (MENU_EXTRA_PADDING * 2), 0, self.props.screenSize.Y)
|
||||
end
|
||||
|
||||
local moreIcon = "rbxasset://textures/ui/TopBar/moreOn.png"
|
||||
if not self.props.moreMenuOpen then
|
||||
moreIcon = "rbxasset://textures/ui/TopBar/moreOff.png"
|
||||
end
|
||||
|
||||
local moreButtonVisible = not TenFootInterface:IsEnabled() and self.props.topBarEnabled and hasOptions
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
Visible = moreButtonVisible,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, MORE_BUTTON_SIZE, 1, 0),
|
||||
LayoutOrder = self.props.layoutOrder,
|
||||
}, {
|
||||
OpenButton = Roact.createElement(IconButton, {
|
||||
icon = moreIcon,
|
||||
iconSize = ICON_SIZE,
|
||||
|
||||
onActivated = self.moreButtonActivated,
|
||||
}),
|
||||
|
||||
MoreMenuContainer = Roact.createElement("Frame", {
|
||||
ZIndex = 3,
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
Position = UDim2.new(1, CONTEXT_MENU_DEFAULT_PADDING, 0, 0),
|
||||
Size = moreMenuSize,
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
}, {
|
||||
OverlayContextualMenu = Roact.createElement(OverlayContextualMenu, {
|
||||
buttonProps = menuOptions,
|
||||
|
||||
open = self.props.moreMenuOpen,
|
||||
menuDirection = MenuDirection.Down,
|
||||
openPositionY = UDim.new(0, Constants.TopBarHeight + MENU_GAP),
|
||||
|
||||
closeBackgroundVisible = false,
|
||||
screenSize = self.props.screenSize,
|
||||
|
||||
onDismiss = function()
|
||||
self.props.setMoreMenuOpen(false)
|
||||
PlayerListMaster:SetMinimized(false)
|
||||
end,
|
||||
}),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
function MoreMenu:updateActionBound()
|
||||
if self.props.moreMenuOpen then
|
||||
ContextActionService:BindCoreAction(
|
||||
ESCAPE_CLOSE_MENU_ACTION,
|
||||
function(actionName, inputState, inputObj)
|
||||
if inputState == Enum.UserInputState.Begin then
|
||||
self.props.setMoreMenuOpen(false)
|
||||
return Enum.ContextActionResult.Sink
|
||||
end
|
||||
return Enum.ContextActionResult.Pass
|
||||
end,
|
||||
false, Enum.KeyCode.Escape
|
||||
)
|
||||
|
||||
self.boundAction = true
|
||||
elseif self.boundAction then
|
||||
ContextActionService:UnbindCoreAction(ESCAPE_CLOSE_MENU_ACTION)
|
||||
|
||||
self.boundAction = false
|
||||
end
|
||||
end
|
||||
|
||||
function MoreMenu:didUpdate(prevProps, prevState)
|
||||
if self.props.moreMenuOpen ~= prevProps.moreMenuOpen then
|
||||
PlayerListMaster:SetMinimized(self.props.moreMenuOpen)
|
||||
|
||||
self:updateActionBound()
|
||||
|
||||
if self.props.screenSize.X < CHAT_HIDE_THRESHOLD then
|
||||
if self.props.moreMenuOpen and ChatSelector:GetVisibility() then
|
||||
self.chatWasHidden = true
|
||||
ChatSelector:SetVisible(false)
|
||||
elseif not self.props.moreMenuOpen and self.chatWasHidden then
|
||||
ChatSelector:SetVisible(true)
|
||||
self.chatWasHidden = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
return {
|
||||
screenSize = state.displayOptions.screenSize,
|
||||
moreMenuOpen = state.moreMenu.open,
|
||||
|
||||
isSmallTouchDevice = state.displayOptions.isSmallTouchDevice,
|
||||
topBarEnabled = state.displayOptions.topbarEnabled,
|
||||
|
||||
leaderboardEnabled = state.coreGuiEnabled[Enum.CoreGuiType.PlayerList],
|
||||
emotesEnabled = state.moreMenu.emotesEnabled and state.coreGuiEnabled[Enum.CoreGuiType.EmotesMenu],
|
||||
backpackEnabled = state.coreGuiEnabled[Enum.CoreGuiType.Backpack],
|
||||
|
||||
leaderboardOpen = state.moreMenu.leaderboardOpen,
|
||||
backpackOpen = state.moreMenu.backpackOpen,
|
||||
emotesOpen = state.moreMenu.emotesOpen,
|
||||
|
||||
inputType = state.displayOptions.inputType,
|
||||
}
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
setMoreMenuOpen = function(open)
|
||||
return dispatch(SetMoreMenuOpen(open))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, mapDispatchToProps)(MoreMenu)
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local t = require(CorePackages.Packages.t)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local ImageSetButton = UIBlox.Core.ImageSet.Button
|
||||
local Images = UIBlox.App.ImageSet.Images
|
||||
|
||||
local Presentation = script.Parent.Presentation
|
||||
local MenuIcon = require(Presentation.MenuIcon)
|
||||
local ChatIcon = require(Presentation.ChatIcon)
|
||||
local MoreMenu = require(Presentation.MoreMenu)
|
||||
local HealthBar = require(Presentation.HealthBar)
|
||||
local HurtOverlay = require(Presentation.HurtOverlay)
|
||||
local GamepadMenu = require(Presentation.GamepadMenu)
|
||||
|
||||
local Connection = require(script.Parent.Connection)
|
||||
|
||||
local TopBar = Presentation.Parent.Parent
|
||||
local Constants = require(TopBar.Constants)
|
||||
local SetScreenSize = require(TopBar.Actions.SetScreenSize)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
local isNewInGameMenuEnabled = require(RobloxGui.Modules.isNewInGameMenuEnabled)
|
||||
|
||||
local isNewGamepadMenuEnabled = require(RobloxGui.Modules.Flags.isNewGamepadMenuEnabled)
|
||||
|
||||
local CLOSE_MENU_ICON_SIZE = 30
|
||||
|
||||
local TopBarApp = Roact.PureComponent:extend("TopBarApp")
|
||||
|
||||
TopBarApp.validateProps = t.strictInterface({
|
||||
menuOpen = t.boolean,
|
||||
inspectMenuOpen = t.boolean,
|
||||
|
||||
setScreenSize = t.callback,
|
||||
})
|
||||
|
||||
function TopBarApp:render()
|
||||
local screenSideOffset = Constants.ScreenSideOffset
|
||||
local topBarHeight = Constants.TopBarHeight
|
||||
if TenFootInterface:IsEnabled() then
|
||||
screenSideOffset = Constants.ScreenSideOffsetTenFoot
|
||||
topBarHeight = Constants.TopBarHeightTenFoot
|
||||
end
|
||||
|
||||
local isTopBarVisible = not (self.props.menuOpen or self.props.inspectMenuOpen)
|
||||
|
||||
return Roact.createElement("ScreenGui", {
|
||||
IgnoreGuiInset = true,
|
||||
ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
|
||||
AutoLocalize = false,
|
||||
DisplayOrder = 6,
|
||||
|
||||
[Roact.Change.AbsoluteSize] = function(rbx)
|
||||
self.props.setScreenSize(rbx.AbsoluteSize)
|
||||
end,
|
||||
}, {
|
||||
Connection = Roact.createElement(Connection),
|
||||
|
||||
GamepadMenu = isNewGamepadMenuEnabled() and Roact.createElement(GamepadMenu) or nil,
|
||||
|
||||
FullScreenFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Visible = isTopBarVisible,
|
||||
}, {
|
||||
HurtOverlay = Roact.createElement(HurtOverlay),
|
||||
}),
|
||||
|
||||
--Remove with isNewInGameMenuEnabled
|
||||
LegacyCloseMenu = not isNewInGameMenuEnabled() and Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, screenSideOffset, 0, 0),
|
||||
Size = UDim2.new(1, 0, 0, topBarHeight),
|
||||
Visible = self.props.menuOpen,
|
||||
}, {
|
||||
CloseMenuButton = Roact.createElement(ImageSetButton, {
|
||||
Visible = not TenFootInterface:IsEnabled(),
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0.5, 0),
|
||||
AnchorPoint = Vector2.new(0, 0.5),
|
||||
Size = UDim2.new(0, CLOSE_MENU_ICON_SIZE, 0, CLOSE_MENU_ICON_SIZE),
|
||||
Image = Images["icons/controls/close-ingame"],
|
||||
|
||||
[Roact.Event.Activated] = function()
|
||||
local SettingsHub = require(RobloxGui.Modules.Settings.SettingsHub)
|
||||
SettingsHub:ToggleVisibility()
|
||||
end,
|
||||
})
|
||||
}),
|
||||
|
||||
TopBarFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, 0, 0, topBarHeight),
|
||||
Visible = isTopBarVisible,
|
||||
}, {
|
||||
LeftFrame = not TenFootInterface:IsEnabled() and Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0.5, -screenSideOffset, 1, 0),
|
||||
Position = UDim2.new(0, screenSideOffset, 0, 0),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
Padding = UDim.new(0, Constants.Padding),
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
}),
|
||||
|
||||
MenuIcon = Roact.createElement(MenuIcon, {
|
||||
layoutOrder = 1,
|
||||
}),
|
||||
|
||||
ChatIcon = Roact.createElement(ChatIcon, {
|
||||
layoutOrder = 2,
|
||||
}),
|
||||
}),
|
||||
|
||||
RightFrame = Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0.5, -screenSideOffset, 1, 0),
|
||||
Position = UDim2.new(1, -screenSideOffset, 0, 0),
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
}, {
|
||||
Layout = Roact.createElement("UIListLayout", {
|
||||
Padding = UDim.new(0, Constants.Padding),
|
||||
FillDirection = Enum.FillDirection.Horizontal,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Right,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
}),
|
||||
|
||||
HealthBar = Roact.createElement(HealthBar, {
|
||||
layoutOrder = 1,
|
||||
}),
|
||||
|
||||
MoreMenu = not TenFootInterface:IsEnabled() and Roact.createElement(MoreMenu, {
|
||||
layoutOrder = 2,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local function mapStateToProps(state)
|
||||
local inspectMenuOpen = state.displayOptions.inspectMenuOpen
|
||||
|
||||
return {
|
||||
menuOpen = state.displayOptions.menuOpen,
|
||||
inspectMenuOpen = inspectMenuOpen,
|
||||
}
|
||||
end
|
||||
|
||||
local function mapDispatchToProps(dispatch)
|
||||
return {
|
||||
setScreenSize = function(screenSize)
|
||||
return dispatch(SetScreenSize(screenSize))
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps, mapDispatchToProps)(TopBarApp)
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
return function()
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local RobloxReplicatedStorage = game:GetService("RobloxReplicatedStorage")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local AppDarkTheme = require(CorePackages.AppTempCommon.LuaApp.Style.Themes.DarkTheme)
|
||||
local AppFont = require(CorePackages.AppTempCommon.LuaApp.Style.Fonts.Gotham)
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
local Reducer = require(script.Parent.Parent.Reducer)
|
||||
|
||||
local appStyle = {
|
||||
Theme = AppDarkTheme,
|
||||
Font = AppFont,
|
||||
}
|
||||
|
||||
--Create dummy events in RobloxReplicatedStorage:
|
||||
local UpdatePlayerBlockList = Instance.new("RemoteEvent")
|
||||
UpdatePlayerBlockList.Name = "UpdatePlayerBlockList"
|
||||
UpdatePlayerBlockList.Parent = RobloxReplicatedStorage
|
||||
|
||||
local NewPlayerGroupDetails = Instance.new("RemoteEvent")
|
||||
NewPlayerGroupDetails.Name = "NewPlayerGroupDetails"
|
||||
NewPlayerGroupDetails.Parent = RobloxReplicatedStorage
|
||||
|
||||
local NewPlayerCanManageDetails = Instance.new("RemoteEvent")
|
||||
NewPlayerCanManageDetails.Name = "NewPlayerCanManageDetails"
|
||||
NewPlayerCanManageDetails.Parent = RobloxReplicatedStorage
|
||||
|
||||
local FollowRelationshipChanged
|
||||
local GetFollowRelationships
|
||||
local NewFollower
|
||||
|
||||
local Flags = script.Parent.Parent.Parent.Flags
|
||||
local GetFFlagRemoveInGameFollowingEvents = require(Flags.GetFFlagRemoveInGameFollowingEvents)
|
||||
|
||||
if not GetFFlagRemoveInGameFollowingEvents() then
|
||||
FollowRelationshipChanged = Instance.new("RemoteEvent")
|
||||
FollowRelationshipChanged.Name = "FollowRelationshipChanged"
|
||||
FollowRelationshipChanged.Parent = RobloxReplicatedStorage
|
||||
|
||||
GetFollowRelationships = Instance.new("RemoteFunction")
|
||||
GetFollowRelationships.Name = "GetFollowRelationships"
|
||||
GetFollowRelationships.Parent = RobloxReplicatedStorage
|
||||
|
||||
NewFollower = Instance.new("RemoteEvent")
|
||||
NewFollower.Name = "NewFollower"
|
||||
NewFollower.Parent = RobloxReplicatedStorage
|
||||
end
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local SendNotificationInfo = Instance.new("BindableEvent")
|
||||
SendNotificationInfo.Name = "SendNotificationInfo"
|
||||
SendNotificationInfo.Parent = RobloxGui
|
||||
|
||||
local Sounds = Instance.new("Folder")
|
||||
Sounds.Name = "Sounds"
|
||||
Sounds.Parent = CoreGui.RobloxGui
|
||||
|
||||
describe("TopBarApp", function()
|
||||
it("should create and destroy without errors", function()
|
||||
local TopBarApp = require(script.Parent.TopBarApp)
|
||||
|
||||
local store = Rodux.Store.new(Reducer, nil, {
|
||||
Rodux.thunkMiddleware,
|
||||
})
|
||||
|
||||
local element = Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = store,
|
||||
}, {
|
||||
ThemeProvider = Roact.createElement(UIBlox.Style.Provider, {
|
||||
style = appStyle,
|
||||
}, {
|
||||
TopBarApp = Roact.createElement(TopBarApp)
|
||||
})
|
||||
})
|
||||
|
||||
local instance = Roact.mount(element)
|
||||
Roact.unmount(instance)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
return {
|
||||
TopBarHeight = 36,
|
||||
TopBarHeightTenFoot = 72,
|
||||
|
||||
ScreenSideOffset = 16,
|
||||
ScreenSideOffsetTenFoot = 48,
|
||||
|
||||
Padding = 12,
|
||||
|
||||
HealthPercentForOverlay = 5 / 100,
|
||||
HealthRedColor = Color3.fromRGB(255, 28, 0),
|
||||
HealthYellowColor = Color3.fromRGB(250, 235, 0),
|
||||
HealthGreenColor = Color3.fromRGB(27, 252, 107),
|
||||
|
||||
InputType = {
|
||||
MouseAndKeyBoard = "MouseAndKeyboard",
|
||||
Touch = "Touch",
|
||||
Gamepad = "Gamepad",
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
return {
|
||||
propValidation = false,
|
||||
elementTracing = false,
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
local UpdateChatMessages = require(Actions.UpdateChatMessages)
|
||||
local UpdateChatVisible = require(Actions.UpdateChatVisible)
|
||||
local SetCanChat = require(Actions.SetCanChat)
|
||||
|
||||
local initialChatState = {
|
||||
canChat = false,
|
||||
visible = true,
|
||||
lastReadMessages = 0,
|
||||
unreadMessages = 0,
|
||||
}
|
||||
|
||||
local Chat = Rodux.createReducer(initialChatState, {
|
||||
[UpdateChatMessages.name] = function(state, action)
|
||||
if state.visible then
|
||||
return {
|
||||
canChat = state.canChat,
|
||||
visible = true,
|
||||
lastReadMessages = action.messages,
|
||||
unreadMessages = 0,
|
||||
}
|
||||
else
|
||||
return {
|
||||
canChat = state.canChat,
|
||||
visible = false,
|
||||
lastReadMessages = state.lastReadMessages,
|
||||
unreadMessages = action.messages - state.lastReadMessages,
|
||||
}
|
||||
end
|
||||
end,
|
||||
|
||||
[UpdateChatVisible.name] = function(state, action)
|
||||
if action.visible then
|
||||
return {
|
||||
canChat = state.canChat,
|
||||
visible = true,
|
||||
lastReadMessages = state.lastReadMessages + state.unreadMessages,
|
||||
unreadMessages = 0,
|
||||
}
|
||||
else
|
||||
return {
|
||||
canChat = state.canChat,
|
||||
visible = false,
|
||||
lastReadMessages = state.lastReadMessages,
|
||||
unreadMessages = state.unreadMessages,
|
||||
}
|
||||
end
|
||||
end,
|
||||
|
||||
[SetCanChat.name] = function(state, action)
|
||||
return {
|
||||
canChat = action.canChat,
|
||||
visible = state.visible,
|
||||
lastReadMessages = state.lastReadMessages,
|
||||
unreadMessages = state.unreadMessages,
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
return Chat
|
||||
@@ -0,0 +1,80 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local UpdateChatMessages = require(Actions.UpdateChatMessages)
|
||||
local UpdateChatVisible = require(Actions.UpdateChatVisible)
|
||||
local SetCanChat = require(Actions.SetCanChat)
|
||||
local Chat = require(script.Parent.Chat)
|
||||
|
||||
local function countValues(t)
|
||||
local c = 0
|
||||
for _, _ in pairs(t) do
|
||||
c = c + 1
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = Chat(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.canChat).to.equal(false)
|
||||
expect(defaultState.visible).to.equal(true)
|
||||
expect(defaultState.lastReadMessages).to.equal(0)
|
||||
expect(defaultState.unreadMessages).to.equal(0)
|
||||
end)
|
||||
|
||||
describe("SetCanChat", function()
|
||||
it("should change the value of canChat", function()
|
||||
local oldState = Chat(nil, {})
|
||||
local newState = Chat(oldState, SetCanChat(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.canChat).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = Chat(nil, {})
|
||||
local newState = Chat(oldState, SetCanChat(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "canChat" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("UpdateChatMessages", function()
|
||||
it("should change the value of lastReadMessages when visible", function()
|
||||
local oldState = Chat(nil, {})
|
||||
oldState = Chat(oldState, UpdateChatVisible(true))
|
||||
local newState = Chat(oldState, UpdateChatMessages(10))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.lastReadMessages).to.equal(10)
|
||||
expect(newState.unreadMessages).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should change the value of unreadMessages when not visible", function()
|
||||
local oldState = Chat(nil, {})
|
||||
oldState = Chat(oldState, UpdateChatMessages(5))
|
||||
oldState = Chat(oldState, UpdateChatVisible(false))
|
||||
local newState = Chat(oldState, UpdateChatMessages(15))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.lastReadMessages).to.equal(5)
|
||||
expect(newState.unreadMessages).to.equal(10)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("UpdateChatVisible", function()
|
||||
it("should reset unreadMessages", function()
|
||||
local oldState = Chat(nil, {})
|
||||
oldState = Chat(oldState, UpdateChatVisible(false))
|
||||
expect(oldState.visible).to.equal(false)
|
||||
oldState = Chat(oldState, UpdateChatMessages(10))
|
||||
local newState = Chat(oldState, UpdateChatVisible(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.visible).to.equal(true)
|
||||
expect(newState.lastReadMessages).to.equal(10)
|
||||
expect(newState.unreadMessages).to.equal(0)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
local Cryo = require(CorePackages.Cryo)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
local UpdateCoreGuiEnabled = require(Actions.UpdateCoreGuiEnabled)
|
||||
|
||||
local initialCoreGuiEnabled = {
|
||||
[Enum.CoreGuiType.PlayerList] = true,
|
||||
[Enum.CoreGuiType.Health] = true,
|
||||
[Enum.CoreGuiType.Backpack] = true,
|
||||
[Enum.CoreGuiType.Chat] = true,
|
||||
[Enum.CoreGuiType.EmotesMenu] = true,
|
||||
}
|
||||
|
||||
local CoreGuiEanbled = Rodux.createReducer(initialCoreGuiEnabled, {
|
||||
[UpdateCoreGuiEnabled.name] = function(state, action)
|
||||
if action.coreGuiType == Enum.CoreGuiType.All then
|
||||
local newState = {}
|
||||
for coreGuiType, _ in pairs(state) do
|
||||
newState[coreGuiType] = action.enabled
|
||||
end
|
||||
return newState
|
||||
else
|
||||
return Cryo.Dictionary.join(state, {
|
||||
[action.coreGuiType] = action.enabled,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
return CoreGuiEanbled
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local UpdateCoreGuiEnabled = require(Actions.UpdateCoreGuiEnabled)
|
||||
local CoreGuiEnabled = require(script.Parent.CoreGuiEnabled)
|
||||
|
||||
it("everything should be enabled by default", function()
|
||||
local defaultState = CoreGuiEnabled(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
|
||||
expect(defaultState[Enum.CoreGuiType.PlayerList]).to.equal(true)
|
||||
expect(defaultState[Enum.CoreGuiType.Health]).to.equal(true)
|
||||
expect(defaultState[Enum.CoreGuiType.Backpack]).to.equal(true)
|
||||
expect(defaultState[Enum.CoreGuiType.Chat]).to.equal(true)
|
||||
expect(defaultState[Enum.CoreGuiType.EmotesMenu]).to.equal(true)
|
||||
end)
|
||||
|
||||
describe("UpdateCoreGuiEnabled", function()
|
||||
it("should change the value of of the given coregui type", function()
|
||||
local oldState = CoreGuiEnabled(nil, {})
|
||||
local newState = CoreGuiEnabled(oldState, UpdateCoreGuiEnabled(Enum.CoreGuiType.PlayerList, false))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState[Enum.CoreGuiType.PlayerList]).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should update all values when passed Enum.CoreGuiType.All", function()
|
||||
local oldState = CoreGuiEnabled(nil, {})
|
||||
local newState = CoreGuiEnabled(oldState, UpdateCoreGuiEnabled(Enum.CoreGuiType.All, false))
|
||||
|
||||
expect(newState[Enum.CoreGuiType.PlayerList]).to.equal(false)
|
||||
expect(newState[Enum.CoreGuiType.Health]).to.equal(false)
|
||||
expect(newState[Enum.CoreGuiType.Backpack]).to.equal(false)
|
||||
expect(newState[Enum.CoreGuiType.Chat]).to.equal(false)
|
||||
expect(newState[Enum.CoreGuiType.EmotesMenu]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
local Cryo = require(CorePackages.Cryo)
|
||||
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local SetMenuOpen = require(Actions.SetMenuOpen)
|
||||
local SetTopBarEnabled = require(Actions.SetTopBarEnabled)
|
||||
local SetSmallTouchDevice = require(Actions.SetSmallTouchDevice)
|
||||
local SetScreenSize = require(Actions.SetScreenSize)
|
||||
local SetInputType = require(Actions.SetInputType)
|
||||
local SetInspectMenuOpen = require(Actions.SetInspectMenuOpen)
|
||||
|
||||
local Constants = require(TopBar.Constants)
|
||||
local InputType = Constants.InputType
|
||||
|
||||
local initialDisplayOptions = {
|
||||
menuOpen = false,
|
||||
inspectMenuOpen = false,
|
||||
topbarEnabled = true, --If the top bar is enabled from the SetCore API
|
||||
isSmallTouchDevice = false,
|
||||
screenSize = Vector2.new(0, 0),
|
||||
inputType = InputType.MouseAndKeyBoard,
|
||||
}
|
||||
|
||||
local DisplayOptions = Rodux.createReducer(initialDisplayOptions, {
|
||||
[SetMenuOpen.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
menuOpen = action.menuOpen,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetTopBarEnabled.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
topbarEnabled = action.enabled,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetSmallTouchDevice.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
isSmallTouchDevice = action.isSmallTouchDevice,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetScreenSize.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
screenSize = action.screenSize,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetInputType.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
inputType = action.inputType,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetInspectMenuOpen.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
inspectMenuOpen = action.inspectMenuOpen
|
||||
})
|
||||
end,
|
||||
})
|
||||
|
||||
return DisplayOptions
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local SetMenuOpen = require(Actions.SetMenuOpen)
|
||||
local SetTopBarEnabled = require(Actions.SetTopBarEnabled)
|
||||
local SetSmallTouchDevice = require(Actions.SetSmallTouchDevice)
|
||||
local SetScreenSize = require(Actions.SetScreenSize)
|
||||
local DisplayOptions = require(script.Parent.DisplayOptions)
|
||||
local SetInputType = require(Actions.SetInputType)
|
||||
local SetInspectMenuOpen = require(Actions.SetInspectMenuOpen)
|
||||
|
||||
local Constants = require(TopBar.Constants)
|
||||
local InputType = Constants.InputType
|
||||
|
||||
local function countValues(t)
|
||||
local c = 0
|
||||
for _, _ in pairs(t) do
|
||||
c = c + 1
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = DisplayOptions(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.menuOpen).to.equal(false)
|
||||
expect(defaultState.topbarEnabled).to.equal(true)
|
||||
expect(defaultState.isSmallTouchDevice).to.equal(false)
|
||||
expect(defaultState.inputType).to.equal(InputType.MouseAndKeyBoard)
|
||||
expect(defaultState.inspectMenuOpen).to.equal(false)
|
||||
end)
|
||||
|
||||
describe("SetMenuOpen", function()
|
||||
it("should change the value of menuOpen", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetMenuOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.menuOpen).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetMenuOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "menuOpen" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetTopBarEnabled", function()
|
||||
it("should change the value of topbarEnabled", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetTopBarEnabled(false))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.topbarEnabled).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetTopBarEnabled(false))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "topbarEnabled" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetSmallTouchDevice", function()
|
||||
it("should change the value of topbarEnabled", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetSmallTouchDevice(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.isSmallTouchDevice).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetSmallTouchDevice(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "isSmallTouchDevice" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
describe("SetScreenSize", function()
|
||||
it("should change the value of topbarEnabled", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetScreenSize(Vector2.new(100, 100)))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.screenSize).to.equal(Vector2.new(100, 100))
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetScreenSize(Vector2.new(100, 100)))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "screenSize" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetInputType", function()
|
||||
it("should change the value of inputType", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetInputType(InputType.Touch))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.inputType).to.equal(InputType.Touch)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetInputType(InputType.Touch))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "inputType" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetInspectMenuOpen", function()
|
||||
it("should change the value of inspectMenuOpen", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetInspectMenuOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.inspectMenuOpen).to.equal(true)
|
||||
newState = DisplayOptions(newState, SetInspectMenuOpen(false))
|
||||
expect(newState.inspectMenuOpen).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = DisplayOptions(nil, {})
|
||||
local newState = DisplayOptions(oldState, SetInspectMenuOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "inspectMenuOpen" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local RobloxTranslator = require(RobloxGui.Modules.RobloxTranslator)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
|
||||
local SetGameName = require(Actions.SetGameName)
|
||||
|
||||
return Rodux.createReducer({
|
||||
name = RobloxTranslator:FormatByKey("CoreScripts.TopBar.GameNamePlaceHolder"),
|
||||
}, {
|
||||
[SetGameName.name] = function(state, action)
|
||||
return {
|
||||
name = action.gameName,
|
||||
}
|
||||
end,
|
||||
})
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local SetGameName = require(Actions.SetGameName)
|
||||
|
||||
local GameInfo = require(script.Parent.GameInfo)
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = GameInfo(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.name).to.equal("Game")
|
||||
end)
|
||||
|
||||
describe("SetGameName", function()
|
||||
it("should change the value of name", function()
|
||||
local oldState = GameInfo(nil, {})
|
||||
local newState = GameInfo(oldState, SetGameName("Test"))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.name).to.equal("Test")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
local UpdateHealth = require(Actions.UpdateHealth)
|
||||
local SetIsDead = require(Actions.SetIsDead)
|
||||
|
||||
local initialHealth = {
|
||||
isDead = false,
|
||||
currentHealth = 100,
|
||||
maxHealth = 100,
|
||||
}
|
||||
|
||||
local Health = Rodux.createReducer(initialHealth, {
|
||||
[UpdateHealth.name] = function(state, action)
|
||||
return {
|
||||
isDead = state.isDead,
|
||||
currentHealth = action.health,
|
||||
maxHealth = action.maxHealth,
|
||||
}
|
||||
end,
|
||||
|
||||
[SetIsDead.name] = function(state, action)
|
||||
return {
|
||||
isDead = action.isDead,
|
||||
currentHealth = state.currentHealth,
|
||||
maxHealth = state.maxHealth,
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
return Health
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local UpdateHealth = require(Actions.UpdateHealth)
|
||||
local SetIsDead = require(Actions.SetIsDead)
|
||||
local Health = require(script.Parent.Health)
|
||||
|
||||
local function countValues(t)
|
||||
local c = 0
|
||||
for _, _ in pairs(t) do
|
||||
c = c + 1
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = Health(nil, {})
|
||||
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.isDead).to.equal(false)
|
||||
expect(defaultState.currentHealth).to.equal(100)
|
||||
expect(defaultState.maxHealth).to.equal(100)
|
||||
end)
|
||||
|
||||
describe("UpdateHealth", function()
|
||||
it("should change the value of health and maxHealth", function()
|
||||
local oldState = Health(nil, {})
|
||||
local newState = Health(oldState, UpdateHealth(15, 30))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.currentHealth).to.equal(15)
|
||||
expect(newState.maxHealth).to.equal(30)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = Health(nil, {})
|
||||
local newState = Health(oldState, UpdateHealth(15, 30))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "currentHealth" and key ~= "maxHealth" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetIsDead", function()
|
||||
it("should change the value of isDead", function()
|
||||
local oldState = Health(nil, {})
|
||||
local newState = Health(oldState, SetIsDead(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.isDead).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = Health(nil, {})
|
||||
local newState = Health(oldState, SetIsDead(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "isDead" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
local Cryo = require(CorePackages.Cryo)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
local SetMoreMenuOpen = require(Actions.SetMoreMenuOpen)
|
||||
local SetBackpackOpen = require(Actions.SetBackpackOpen)
|
||||
local SetEmotesOpen = require(Actions.SetEmotesOpen)
|
||||
local SetLeaderboardOpen = require(Actions.SetLeaderboardOpen)
|
||||
local SetEmotesEnabled = require(Actions.SetEmotesEnabled)
|
||||
|
||||
local FFlagTopBarCloseContextMenuWhenHotkeysUsed = game:DefineFastFlag(
|
||||
"TopBarCloseContextMenuWhenHotkeysUsed", false
|
||||
)
|
||||
|
||||
local initialState = {
|
||||
open = false,
|
||||
backpackOpen = false,
|
||||
leaderboardOpen = false,
|
||||
emotesOpen = false,
|
||||
emotesEnabled = true,
|
||||
}
|
||||
|
||||
local MoreMenu = Rodux.createReducer(initialState, {
|
||||
[SetMoreMenuOpen.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
open = action.open,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetBackpackOpen.name] = function(state, action)
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
return Cryo.Dictionary.join(state, {
|
||||
open = false,
|
||||
backpackOpen = action.open,
|
||||
})
|
||||
else
|
||||
return Cryo.Dictionary.join(state, {
|
||||
backpackOpen = action.open,
|
||||
})
|
||||
end
|
||||
end,
|
||||
|
||||
[SetEmotesOpen.name] = function(state, action)
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
return Cryo.Dictionary.join(state, {
|
||||
open = false,
|
||||
emotesOpen = action.open,
|
||||
})
|
||||
else
|
||||
return Cryo.Dictionary.join(state, {
|
||||
emotesOpen = action.open,
|
||||
})
|
||||
end
|
||||
end,
|
||||
|
||||
[SetEmotesEnabled.name] = function(state, action)
|
||||
return Cryo.Dictionary.join(state, {
|
||||
emotesEnabled = action.enabled,
|
||||
})
|
||||
end,
|
||||
|
||||
[SetLeaderboardOpen.name] = function(state, action)
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
return Cryo.Dictionary.join(state, {
|
||||
open = false,
|
||||
leaderboardOpen = action.open,
|
||||
})
|
||||
else
|
||||
return Cryo.Dictionary.join(state, {
|
||||
leaderboardOpen = action.open,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
return MoreMenu
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local SetMoreMenuOpen = require(Actions.SetMoreMenuOpen)
|
||||
local SetBackpackOpen = require(Actions.SetBackpackOpen)
|
||||
local SetEmotesOpen = require(Actions.SetEmotesOpen)
|
||||
local SetLeaderboardOpen = require(Actions.SetLeaderboardOpen)
|
||||
local SetEmotesEnabled = require(Actions.SetEmotesEnabled)
|
||||
|
||||
local MoreMenu = require(script.Parent.MoreMenu)
|
||||
|
||||
local FFlagTopBarCloseContextMenuWhenHotkeysUsed = game:GetFastFlag(
|
||||
"TopBarCloseContextMenuWhenHotkeysUsed"
|
||||
)
|
||||
|
||||
local function countValues(t)
|
||||
local c = 0
|
||||
for _, _ in pairs(t) do
|
||||
c = c + 1
|
||||
end
|
||||
return c
|
||||
end
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = MoreMenu(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.open).to.equal(false)
|
||||
expect(defaultState.backpackOpen).to.equal(false)
|
||||
expect(defaultState.leaderboardOpen).to.equal(false)
|
||||
expect(defaultState.emotesOpen).to.equal(false)
|
||||
end)
|
||||
|
||||
describe("SetMoreMenuOpen", function()
|
||||
it("should change the value of open", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetMoreMenuOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.open).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetMoreMenuOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "open" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetBackpackOpen", function()
|
||||
it("should change the value of backpackOpen", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetBackpackOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.backpackOpen).to.equal(true)
|
||||
end)
|
||||
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
it("should not change any other values except open", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetBackpackOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "backpackOpen" and key ~= "open" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
it("should set open to false when changed", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
oldState = MoreMenu(oldState, SetMoreMenuOpen(true))
|
||||
local newState = MoreMenu(oldState, SetBackpackOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.open).to.equal(false)
|
||||
end)
|
||||
else
|
||||
it("should not change any other values", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetBackpackOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "backpackOpen" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
describe("SetEmotesOpen", function()
|
||||
it("should change the value of emotesOpen", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetEmotesOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.emotesOpen).to.equal(true)
|
||||
end)
|
||||
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
it("should not change any other values except open", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetEmotesOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "emotesOpen" and key ~= "open" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
it("should set open to false when changed", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
oldState = MoreMenu(oldState, SetMoreMenuOpen(true))
|
||||
local newState = MoreMenu(oldState, SetEmotesOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.open).to.equal(false)
|
||||
end)
|
||||
else
|
||||
it("should not change any other values", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetEmotesOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "emotesOpen" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
describe("SetEmotesEnabled", function()
|
||||
it("should change the value of emotesEnabled", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetEmotesEnabled(false))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.emotesEnabled).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should not change any other values", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetEmotesEnabled(false))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "emotesEnabled" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetLeaderboardOpen", function()
|
||||
it("should change the value of open", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetLeaderboardOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.leaderboardOpen).to.equal(true)
|
||||
end)
|
||||
|
||||
if FFlagTopBarCloseContextMenuWhenHotkeysUsed then
|
||||
it("should not change any other values except open", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetLeaderboardOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "leaderboardOpen" and key ~= "open" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
it("should set open to false when changed", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
oldState = MoreMenu(oldState, SetMoreMenuOpen(true))
|
||||
local newState = MoreMenu(oldState, SetLeaderboardOpen(true))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.open).to.equal(false)
|
||||
end)
|
||||
else
|
||||
it("should not change any other values", function()
|
||||
local oldState = MoreMenu(nil, {})
|
||||
local newState = MoreMenu(oldState, SetLeaderboardOpen(true))
|
||||
expect(countValues(newState)).to.equal(countValues(oldState))
|
||||
for key, value in pairs(newState) do
|
||||
if key ~= "leaderboardOpen" then
|
||||
expect(value).to.equal(oldState[key])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
|
||||
local Actions = script.Parent.Parent.Actions
|
||||
|
||||
local SetRespawnBehaviour = require(Actions.SetRespawnBehaviour)
|
||||
|
||||
return Rodux.createReducer({
|
||||
enabled = true,
|
||||
customCallback = nil,
|
||||
}, {
|
||||
[SetRespawnBehaviour.name] = function(state, action)
|
||||
return {
|
||||
enabled = action.respawnEnabled,
|
||||
customCallback = action.customCallback,
|
||||
}
|
||||
end,
|
||||
})
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
return function()
|
||||
local TopBar = script.Parent.Parent
|
||||
local Actions = TopBar.Actions
|
||||
local SetRespawnBehaviour = require(Actions.SetRespawnBehaviour)
|
||||
|
||||
local Respawn = require(script.Parent.Respawn)
|
||||
|
||||
it("should have the correct default values", function()
|
||||
local defaultState = Respawn(nil, {})
|
||||
expect(type(defaultState)).to.equal("table")
|
||||
expect(defaultState.enabled).to.equal(true)
|
||||
expect(defaultState.customCallback).to.equal(nil)
|
||||
end)
|
||||
|
||||
describe("SetRespawnBehavior", function()
|
||||
it("should change the value of enabled", function()
|
||||
local oldState = Respawn(nil, {})
|
||||
local newState = Respawn(oldState, SetRespawnBehaviour(false))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.enabled).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should change the value of customCallback", function()
|
||||
local Callback = Instance.new("BindableEvent")
|
||||
|
||||
local oldState = Respawn(nil, {})
|
||||
local newState = Respawn(oldState, SetRespawnBehaviour(true, Callback))
|
||||
expect(oldState).to.never.equal(newState)
|
||||
expect(newState.customCallback).to.equal(Callback)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local isNewGamepadMenuEnabled = require(RobloxGui.Modules.Flags.isNewGamepadMenuEnabled)
|
||||
|
||||
local DisplayOptions = require(script.DisplayOptions)
|
||||
local CoreGuiEnabled = require(script.CoreGuiEnabled)
|
||||
local Health = require(script.Health)
|
||||
local MoreMenu = require(script.MoreMenu)
|
||||
local Chat = require(script.Chat)
|
||||
local Respawn = require(script.Respawn)
|
||||
local GameInfo = require(script.GameInfo)
|
||||
|
||||
local Reducer = Rodux.combineReducers({
|
||||
displayOptions = DisplayOptions,
|
||||
coreGuiEnabled = CoreGuiEnabled,
|
||||
health = Health,
|
||||
moreMenu = MoreMenu,
|
||||
chat = Chat,
|
||||
respawn = isNewGamepadMenuEnabled() and Respawn or nil,
|
||||
gameInfo = isNewGamepadMenuEnabled() and GameInfo or nil,
|
||||
})
|
||||
|
||||
return Reducer
|
||||
@@ -0,0 +1,33 @@
|
||||
local Chat = game:GetService("Chat")
|
||||
local RunService = game:GetService("RunService")
|
||||
local Players = game:GetService("Players")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local TopBar = script.Parent.Parent
|
||||
local SetCanChat = require(TopBar.Actions.SetCanChat)
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
local ChatSelector = require(RobloxGui.Modules.ChatSelector)
|
||||
|
||||
local LocalPlayer = Players.LocalPlayer
|
||||
while not LocalPlayer do
|
||||
Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
|
||||
LocalPlayer = Players.LocalPlayer
|
||||
end
|
||||
|
||||
return function(store)
|
||||
coroutine.wrap(function()
|
||||
local canChat = true
|
||||
if not RunService:IsStudio() then
|
||||
local success, localUserCanChat = pcall(function()
|
||||
return Chat:CanUserChatAsync(LocalPlayer.UserId)
|
||||
end)
|
||||
canChat = success and localUserCanChat
|
||||
end
|
||||
|
||||
store:dispatch(SetCanChat(canChat))
|
||||
if not canChat then
|
||||
ChatSelector:SetVisible(false)
|
||||
end
|
||||
end)()
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local HttpRbxApiService = game:GetService("HttpRbxApiService")
|
||||
local LocalizationService = game:GetService("LocalizationService")
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
|
||||
local httpRequest = require(CorePackages.AppTempCommon.Temp.httpRequest)
|
||||
|
||||
local httpImpl = httpRequest(HttpRbxApiService)
|
||||
|
||||
local Thunks = script.Parent
|
||||
local TopBar = Thunks.Parent
|
||||
local SetGameName = require(TopBar.Actions.SetGameName)
|
||||
|
||||
local GetGameNameAndDescription = require(RobloxGui.Modules.Common.GetGameNameAndDescription)
|
||||
|
||||
return function(store)
|
||||
coroutine.wrap(function()
|
||||
if game.GameId == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
GetGameNameAndDescription(httpImpl, game.GameId):andThen(function(
|
||||
gameNameLocaleMap, gameDescriptionsLocaleMap, sourceLocale)
|
||||
|
||||
local localeGameName = gameNameLocaleMap[LocalizationService.RobloxLocaleId]
|
||||
if localeGameName then
|
||||
return store:dispatch(SetGameName(localeGameName))
|
||||
end
|
||||
|
||||
local sourceGameName = gameNameLocaleMap[sourceLocale]
|
||||
if sourceGameName then
|
||||
return store:dispatch(SetGameName(sourceGameName))
|
||||
end
|
||||
end):catch(function()
|
||||
warn("Unable to get game name for Gamepad Menu")
|
||||
end)
|
||||
end)()
|
||||
end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
return function(store)
|
||||
local state = store:getState()
|
||||
|
||||
if state.respawn.customCallback then
|
||||
state.respawn.customCallback:Fire()
|
||||
else
|
||||
local character = Players.LocalPlayer.Character
|
||||
if character ~= nil then
|
||||
-- For backwards compatibility with games that disable respawning
|
||||
-- by renaming the humanoid instance, we don't use FindFirstChildOfClass.
|
||||
local humanoid = character:FindFirstChild("Humanoid")
|
||||
if humanoid ~= nil and humanoid:IsA("Humanoid") then
|
||||
humanoid.Health = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local PolicyProvider = require(CorePackages.PolicyProvider)
|
||||
|
||||
local implementation = PolicyProvider.GetPolicyImplementations.MemStorageService("app-policy")
|
||||
local TopBarAppPolicy = PolicyProvider.withGetPolicyImplementation(implementation)
|
||||
|
||||
TopBarAppPolicy.Mapper = function(policy)
|
||||
return {
|
||||
}
|
||||
end
|
||||
|
||||
return TopBarAppPolicy
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
return function()
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local Roact = require(CorePackages.Roact)
|
||||
it("should create and destroy without errors", function()
|
||||
local TopBarAppPolicy = require(script.Parent.TopBarAppPolicy)
|
||||
local testPolicyValue = "TestPolicy"
|
||||
local testPolicyMapper = function(policy)
|
||||
return {
|
||||
UnitTestPolicy = function()
|
||||
return testPolicyValue
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local RoactTestComponent = Roact.PureComponent:extend("RoactTestComponent")
|
||||
function RoactTestComponent:render()
|
||||
end
|
||||
function RoactTestComponent:didMount()
|
||||
self.props.callback(self.props.testValue)
|
||||
end
|
||||
RoactTestComponent = TopBarAppPolicy.connect(function(appPolicy, props)
|
||||
return {
|
||||
testValue = appPolicy.UnitTestPolicy(),
|
||||
}
|
||||
end)(RoactTestComponent)
|
||||
|
||||
local testValue
|
||||
local function testCallback(actualTestValue)
|
||||
testValue = actualTestValue
|
||||
end
|
||||
|
||||
local element = Roact.createElement(TopBarAppPolicy.Provider, {
|
||||
policy = { testPolicyMapper },
|
||||
}, {
|
||||
SomeComponent = Roact.createElement(RoactTestComponent, {
|
||||
callback = testCallback,
|
||||
}),
|
||||
})
|
||||
|
||||
local instance = Roact.mount(element)
|
||||
expect(testValue).to.equal(testPolicyValue)
|
||||
Roact.unmount(instance)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,120 @@
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
|
||||
local RobloxGui = CoreGui:WaitForChild("RobloxGui")
|
||||
|
||||
local AppDarkTheme = require(CorePackages.AppTempCommon.LuaApp.Style.Themes.DarkTheme)
|
||||
local AppFont = require(CorePackages.AppTempCommon.LuaApp.Style.Fonts.Gotham)
|
||||
|
||||
local Roact = require(CorePackages.Roact)
|
||||
local Rodux = require(CorePackages.Rodux)
|
||||
local RoactRodux = require(CorePackages.RoactRodux)
|
||||
local UIBlox = require(CorePackages.UIBlox)
|
||||
|
||||
|
||||
local SettingsUtil = require(RobloxGui.Modules.Settings.Utility)
|
||||
local TenFootInterface = require(RobloxGui.Modules.TenFootInterface)
|
||||
local isNewInGameMenuEnabled = require(RobloxGui.Modules.isNewInGameMenuEnabled)
|
||||
|
||||
local isNewGamepadMenuEnabled = require(RobloxGui.Modules.Flags.isNewGamepadMenuEnabled)
|
||||
|
||||
local GetFFlagUseRoactPolicyProvider = require(RobloxGui.Modules.Flags.GetFFlagUseRoactPolicyProvider)
|
||||
|
||||
local TopBarApp = require(script.Components.TopBarApp)
|
||||
local Reducer = require(script.Reducer)
|
||||
local Constants = require(script.Constants)
|
||||
local TopBarAppPolicy = require(script.TopBarAppPolicy)
|
||||
|
||||
local SetSmallTouchDevice = require(script.Actions.SetSmallTouchDevice)
|
||||
local SetInspectMenuOpen = require(script.Actions.SetInspectMenuOpen)
|
||||
|
||||
local GetCanChat = require(script.Thunks.GetCanChat)
|
||||
local GetGameName = require(script.Thunks.GetGameName)
|
||||
|
||||
local registerSetCores = require(script.registerSetCores)
|
||||
|
||||
local GlobalConfig = require(script.GlobalConfig)
|
||||
|
||||
local TopBar = {}
|
||||
TopBar.__index = TopBar
|
||||
|
||||
function TopBar.new()
|
||||
local self = setmetatable({}, TopBar)
|
||||
|
||||
if GlobalConfig.propValidation then
|
||||
Roact.setGlobalConfig({
|
||||
propValidation = true,
|
||||
})
|
||||
end
|
||||
if GlobalConfig.elementTracing then
|
||||
Roact.setGlobalConfig({
|
||||
elementTracing = true,
|
||||
})
|
||||
end
|
||||
|
||||
if not TenFootInterface:IsEnabled() then
|
||||
GuiService:SetGlobalGuiInset(0, Constants.TopBarHeight, 0, 0)
|
||||
end
|
||||
|
||||
self.store = Rodux.Store.new(Reducer, nil, {
|
||||
Rodux.thunkMiddleware,
|
||||
})
|
||||
registerSetCores(self.store)
|
||||
self.store:dispatch(GetCanChat)
|
||||
|
||||
if isNewGamepadMenuEnabled() then
|
||||
self.store:dispatch(GetGameName)
|
||||
end
|
||||
|
||||
if isNewInGameMenuEnabled() then
|
||||
-- Move to top of script when removing isNewInGameMenuEnabled
|
||||
local InGameMenu = require(RobloxGui.Modules.InGameMenu)
|
||||
InGameMenu.mountInGameMenu()
|
||||
end
|
||||
|
||||
coroutine.wrap(function()
|
||||
self.store:dispatch(SetSmallTouchDevice(SettingsUtil.IsSmallTouchScreen()))
|
||||
end)()
|
||||
|
||||
local appStyle = {
|
||||
Theme = AppDarkTheme,
|
||||
Font = AppFont,
|
||||
}
|
||||
|
||||
if GetFFlagUseRoactPolicyProvider() then
|
||||
self.root = Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = self.store,
|
||||
}, {
|
||||
PolicyProvider = Roact.createElement(TopBarAppPolicy.Provider, {
|
||||
policy = { TopBarAppPolicy.Mapper },
|
||||
}, {
|
||||
ThemeProvider = Roact.createElement(UIBlox.Style.Provider, {
|
||||
style = appStyle,
|
||||
}, {
|
||||
TopBarApp = Roact.createElement(TopBarApp)
|
||||
})
|
||||
})
|
||||
})
|
||||
else
|
||||
self.root = Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = self.store,
|
||||
}, {
|
||||
ThemeProvider = Roact.createElement(UIBlox.Style.Provider, {
|
||||
style = appStyle,
|
||||
}, {
|
||||
TopBarApp = Roact.createElement(TopBarApp)
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
self.element = Roact.mount(self.root, CoreGui, "TopBar")
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TopBar:setInspectMenuOpen(open)
|
||||
self.store:dispatch(SetInspectMenuOpen(open))
|
||||
end
|
||||
|
||||
return TopBar.new()
|
||||
@@ -0,0 +1,6 @@
|
||||
return function()
|
||||
it("should require without errors", function()
|
||||
local TopBarApp = require(script.Parent)
|
||||
expect(TopBarApp).to.be.ok()
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
local StarterGui = game:GetService("StarterGui")
|
||||
|
||||
local TopBar = script.Parent
|
||||
|
||||
local SetTopBarEnabled = require(TopBar.Actions.SetTopBarEnabled)
|
||||
|
||||
local function registerSetCores(store)
|
||||
StarterGui:RegisterSetCore("TopbarEnabled", function(enabled)
|
||||
if type(enabled) == "boolean" then
|
||||
store:dispatch(SetTopBarEnabled(enabled))
|
||||
else
|
||||
error("SetCore TopbarEnabled argument must be a boolean", 2)
|
||||
end
|
||||
end)
|
||||
|
||||
StarterGui:RegisterGetCore("TopbarEnabled", function()
|
||||
return store:getState().displayOptions.topbarEnabled
|
||||
end)
|
||||
end
|
||||
|
||||
return registerSetCores
|
||||
Reference in New Issue
Block a user