This commit is contained in:
lx
2026-07-06 14:01:11 -04:00
commit c4f97d729d
16468 changed files with 935321 additions and 0 deletions
@@ -0,0 +1,67 @@
stds.roblox = {
read_globals = {
game = {
other_fields = true,
},
-- Roblox globals
"script",
-- Extra functions
"tick", "warn", "spawn", "delay",
"wait", "settings", "UserSettings", "typeof",
-- Types
"Vector2", "Vector3",
"Color3",
"UDim", "UDim2",
"Ray",
"Rect",
"CFrame",
"Enum",
"Instance",
"TweenInfo",
"Random",
"NumberRange",
"NumberSequence",
"NumberSequenceKeypoint",
"ColorSequence",
"BrickColor",
}
}
stds.testez = {
read_globals = {
"describe",
"it", "itFOCUS", "itSKIP",
"FOCUS", "SKIP", "HACK_NO_XPCALL",
"expect",
}
}
ignore = {
"212", -- unused arguments
"421", -- shadowing local variable
"422", -- shadowing argument
"431", -- shadowing upvalue
"432", -- shadowing upvalue argument
}
std = "lua51+roblox"
files["**/*.spec.lua"] = {
std = "+testez",
ignore = { "631" }, --Line is too long
}
files["**/*Locale.lua"] = {
ignore = { "631" }, --Line is too long
}
files["**/Locales/*.lua"] = {
ignore = { "631" }, --Line is too long
}
files["**/Legacy/AvatarEditor/*.lua"] = {
ignore = { "121", "122", "211", "213", "612", "614", "631", }, -- Bunch of warnings for legacy code
}
@@ -0,0 +1,53 @@
local CoreGui = game:GetService("CoreGui")
local UserInputService = game:GetService("UserInputService")
local CorePackages = game:GetService("CorePackages")
local Modules = CoreGui.RobloxGui.Modules
local FlagSettings = require(Modules.LuaApp.FlagSettings)
-- Update LuaApp.FlagSettings using the fact that this script is loaded.
FlagSettings:SetIsLuaAppStarterScriptEnabled(true)
local Roact = require(Modules.Common.Roact)
local App = require(Modules.LuaApp.Components.App)
local LuaErrorReporter = require(Modules.Common.LuaErrorReporter)
if not UserSettings().GameSettings:InStudioMode() then
-- listen and report errors
local errorReporter = LuaErrorReporter.new()
errorReporter:setCurrentApp("Mobile")
errorReporter:startQueueTimers()
end
-- Common Setup
if game.Players.LocalPlayer == nil then
game.Players.PlayerAdded:Wait()
end
-- Reduce render quality to optimize performance
local renderSteppedConnection = nil
renderSteppedConnection = game:GetService("RunService").RenderStepped:connect(function()
if renderSteppedConnection then
renderSteppedConnection:Disconnect()
end
settings().Rendering.QualityLevel = 1
end)
local root = Roact.createElement(App)
Roact.mount(root, CoreGui, "App")
-- Run tests when shift+alt+ctrl+T is pressed
UserInputService.InputEnded:connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard and
input.KeyCode == Enum.KeyCode.T and
UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) and
UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) and
UserInputService:IsKeyDown(Enum.KeyCode.LeftAlt)
then
local TestEZ = require(CorePackages.TestEZ)
TestEZ.run(Modules.LuaApp, function(results)
TestEZ.Reporters.TextReporter.report(results)
end)
end
end)
@@ -0,0 +1,20 @@
local scriptContext = game:GetService("ScriptContext")
local UserInputService = game:GetService("UserInputService")
local RobloxGui = game:GetService("CoreGui"):FindFirstChild("RobloxGui")
scriptContext:AddCoreScriptLocal("LuaAppStarterScript", RobloxGui)
local TestLuaMobileApp = require(RobloxGui.Modules.RhodiumTest.Testcase.LuaApp.TestLuaMobileApp)
-- Run Rhodium test when ctrl+shift+alt+R is pressed
UserInputService.InputEnded:connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard and
UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) and
UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) and
UserInputService:IsKeyDown(Enum.KeyCode.LeftAlt)
then
if input.KeyCode == Enum.KeyCode.R then
TestLuaMobileApp()
end
end
end)
@@ -0,0 +1,398 @@
local CoreGui = game:GetService("CoreGui")
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local Modules = CoreGui.RobloxGui.Modules
local Analytics = require(Modules.Common.Analytics)
local LuaErrorReporter = require(Modules.Common.LuaErrorReporter)
local Create = require(Modules.Mobile.Create)
local Constants = require(Modules.Mobile.Constants)
local MobileAppState = require(Modules.Mobile.AppState)
local AvatarEditorFlags = require(Modules.LuaApp.Legacy.AvatarEditor.Flags)
local AppGui = require(Modules.LuaApp.Legacy.AvatarEditor.AppGui)
local getScreenBottomInset = require(Modules.LuaApp.getScreenBottomInset)
local NotificationType = require(Modules.LuaApp.Enum.NotificationType)
local RefactoringAvatarEditorSetup = AvatarEditorFlags:GetFlag("RefactoringAvatarEditorSetup")
local luaAppLegacyInputDisabledGlobally = settings():GetFFlag('LuaAppLegacyInputDisabledGlobally2')
local EnableLuaEventStreamRelease = settings():GetFFlag('EnableLuaEventStreamRelease')
local ChatMaster = nil
local AvatarEditorMain = nil
local function reportAppReady(analyticsImpl, context)
analyticsImpl.EventStream:setRBXEventStream("appReady", context)
end
local function notifyAppReady(appName)
spawn(function()
GuiService:BroadcastNotification(appName, NotificationType.APP_READY)
end)
local analyticsImpl = Analytics.new()
reportAppReady(analyticsImpl, appName)
end
local AvatarEditorSetup = nil
local AppNameEnum = {}
if RefactoringAvatarEditorSetup then
AvatarEditorSetup = require(Modules.Mobile.AvatarEditorSetup)
AppNameEnum = require(Modules.Mobile.AppNameEnum)
else
local AppNames = {
"AvatarEditor",
"Chat",
"ShareGameToChat",
}
for i = 1, #AppNames do
AppNameEnum[AppNames[i]] = AppNames[i]
end
setmetatable(AppNameEnum, {
__index = function(self, key)
error(("Invalid AppNameEnum %q"):format(tostring(key)))
end
})
end
--This is to cover the sky while loading, and also prevent the sky from flashing in when the global gui inset changes
local screenGui
if RefactoringAvatarEditorSetup then
AvatarEditorSetup:Initialize(notifyAppReady)
else
if not UserSettings().GameSettings:InStudioMode() then
screenGui = Create.new "ScreenGui" {
Name = "SkyCoverGui",
DisplayOrder = 1,
Create.new "Frame" {
Name = "HackHeader",
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 0, UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.BLUE_PRESSED,
},
Create.new "Frame" {
Name = "HackBody",
Position = UDim2.new(0, 0, 0, UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y),
Size = UDim2.new(1, 0, 1, 200),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.WHITE,
},
}
else
screenGui = Create.new "ScreenGui" {
Name = "SkyCoverGui",
DisplayOrder = 1,
Create.new "Frame" {
Name = "HackHeader",
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 0, 64),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.BLUE_PRESSED,
},
Create.new "Frame" {
Name = "HackBody",
Position = UDim2.new(0, 0, 0, 64),
Size = UDim2.new(1, 0, 1, 200),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.WHITE,
},
}
end
local function adjustScreenGuiLayout()
local headerHeight = UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y
screenGui.HackHeader.Size = UDim2.new(1, 0, 0, headerHeight)
screenGui.HackBody.Position = UDim2.new(0, 0, 0, headerHeight)
end
local navBarChanged = UserInputService:GetPropertyChangedSignal("NavBarSize")
navBarChanged:Connect(function()
adjustScreenGuiLayout()
end)
local statusBarChanged = UserInputService:GetPropertyChangedSignal("StatusBarSize")
statusBarChanged:Connect(function()
adjustScreenGuiLayout()
end)
screenGui.Parent = CoreGui
--[[
As long as initializing AvatarEditorMain requires a yield, it has to run in a
spawned task. It is then possible for the user to switch apps in the middle of
initialization. So, openAvatarEditor and closeAvatarEditor first check to see
if it's currently initializing, and if it is, they set a bool indicating whether
to call Start() when initialization is done.
]]
local startAvatarEditorAfterInitializing = false
end
local function openChat()
if ChatMaster == nil then
ChatMaster = require(Modules.ChatMaster).new()
end
ChatMaster:Start()
notifyAppReady(AppNameEnum.Chat)
end
local function closeChat()
ChatMaster:Stop()
end
local function openShareGameToChat(parameters)
if ChatMaster == nil then
ChatMaster = require(Modules.ChatMaster).new()
end
ChatMaster:Start(ChatMaster.Type.GameShare, parameters)
notifyAppReady(AppNameEnum.ShareGameToChat)
end
local function closeShareGameToChat()
ChatMaster:Stop(ChatMaster.Type.GameShare)
end
local openAvatarEditor
if not RefactoringAvatarEditorSetup then
openAvatarEditor = function()
startAvatarEditorAfterInitializing = true
end
end
local closeAvatarEditor
if not RefactoringAvatarEditorSetup then
closeAvatarEditor = function()
startAvatarEditorAfterInitializing = false
end
end
if not RefactoringAvatarEditorSetup then
local function avatarEditorInitialization()
spawn(function()
local header
local appGui
if not UserSettings().GameSettings:InStudioMode() then
header = require(Modules.LuaApp.Legacy.AvatarEditor.Header).new("Avatar",
UserInputService.NavBarSize.Y, UserInputService.StatusBarSize.Y)
local headerHeight = UserInputService.StatusBarSize.Y + UserInputService.NavBarSize.Y
appGui = AppGui(
UDim2.new(0, 0, 0, headerHeight),
UDim2.new(1, 0, 1, -headerHeight))
local function updateUIDimensions()
header:SetNavAndStatusBarHeight(UserInputService.NavBarSize.Y, UserInputService.StatusBarSize.Y)
local headerHeight = UserInputService.NavBarSize.Y + UserInputService.StatusBarSize.Y
appGui:setDimensions(
UDim2.new(0, 0, 0, headerHeight),
UDim2.new(1, 0, 1, -headerHeight))
end
UserInputService:GetPropertyChangedSignal("NavBarSize"):Connect( updateUIDimensions )
UserInputService:GetPropertyChangedSignal("StatusBarSize"):Connect( updateUIDimensions )
else
local navBarHeight = 44
local statusBarHeight = 20
header = require(Modules.LuaApp.Legacy.AvatarEditor.Header).new("Avatar",
navBarHeight, statusBarHeight)
local headerHeight = navBarHeight + statusBarHeight
appGui = AppGui(
UDim2.new(0, 0, 0, headerHeight),
UDim2.new(1, 0, 1, -headerHeight))
end
header.rbx.Parent = appGui.ScreenGui
AvatarEditorMain =
require(Modules.LuaApp.Legacy.AvatarEditor.AvatarEditorMain)
.new(appGui)
local function startAvatarEditor()
screenGui.HackBody.Visible = false
AvatarEditorMain:Start()
notifyAppReady(AppNameEnum.AvatarEditor)
end
if startAvatarEditorAfterInitializing then
startAvatarEditor()
end
openAvatarEditor = startAvatarEditor
closeAvatarEditor = function()
screenGui.HackBody.Visible = true
AvatarEditorMain:Stop()
end
end)
end
local hasRunInitialization = false
local renderSteppedConnection = nil
renderSteppedConnection = game:GetService("RunService").RenderStepped:connect(function()
if not hasRunInitialization then
hasRunInitialization = true
if renderSteppedConnection then
renderSteppedConnection:Disconnect()
end
avatarEditorInitialization()
end
end)
end
local function installStudioTestingHooks(store)
local ActionType = require(CoreGui.RobloxGui.Modules.Mobile.ActionType)
print("Testing in Studio")
print("")
print("Use number keys:")
print("1: AvatarEditor")
print("2: Chat")
print("")
local function onKeyPress(inputObject, gameProcessedEvent)
local actionMap = {
[Enum.KeyCode.One] = function()
store:Dispatch( {type = ActionType.OpenApp, appName = AppNameEnum.AvatarEditor} )
end;
[Enum.KeyCode.Two] = function()
store:Dispatch( {type = ActionType.OpenApp, appName = AppNameEnum.Chat} )
end;
}
(actionMap[inputObject.KeyCode] or function()end)()
end
UserInputService.InputBegan:connect(onKeyPress)
end
local initMobile
if not UserSettings().GameSettings:InStudioMode()
then
initMobile = function()
local errorReporter = LuaErrorReporter.new()
errorReporter:setCurrentApp("Mobile")
errorReporter:startQueueTimers()
-- to do : observe app lifecycle changes to disable timers when in background
if EnableLuaEventStreamRelease then
game:BindToClose(function()
-- there is currently a bug with the EventStream, where the stream is not released
-- by the game engine. This call is a temporary work around until a new api is available.
local analytics = Analytics.new()
analytics.EventStream:releaseRBXEventStream()
end)
end
local appState = MobileAppState.new()
local function setGlobalGuiInset()
GuiService:SetGlobalGuiInset(0, 0, 0, getScreenBottomInset())
end
setGlobalGuiInset()
UserInputService:GetPropertyChangedSignal("BottomBarSize"):Connect(setGlobalGuiInset)
GuiService.SafeZoneOffsetsChanged:Connect(setGlobalGuiInset)
UserInputService.LegacyInputEventsEnabled = (not luaAppLegacyInputDisabledGlobally)
appState.store.changed:connect(
function(newState, oldState)
if oldState.OpenApp ~= newState.OpenApp then
if newState.OpenApp == AppNameEnum.Chat then
openChat()
end
if newState.OpenApp == AppNameEnum.AvatarEditor then
if RefactoringAvatarEditorSetup then
AvatarEditorSetup:Open()
else
openAvatarEditor()
end
end
if newState.OpenApp == AppNameEnum.ShareGameToChat then
openShareGameToChat(newState.Parameters)
end
if oldState.OpenApp == AppNameEnum.Chat then
closeChat()
end
if oldState.OpenApp == AppNameEnum.AvatarEditor then
if RefactoringAvatarEditorSetup then
AvatarEditorSetup:Close()
else
closeAvatarEditor()
end
end
if oldState.OpenApp == AppNameEnum.ShareGameToChat then
closeShareGameToChat()
end
end
end
)
end
else
initMobile = function()
local appState = MobileAppState.new()
GuiService:SetGlobalGuiInset(0, 0, 0, 49)
appState.store.changed:connect(
function(newState, oldState)
if oldState.OpenApp ~= newState.OpenApp then
if newState.OpenApp == AppNameEnum.Chat then
--openChat()
end
if newState.OpenApp == AppNameEnum.AvatarEditor then
if RefactoringAvatarEditorSetup then
AvatarEditorSetup:Open()
else
openAvatarEditor()
end
end
if oldState.OpenApp == AppNameEnum.Chat then
--closeChat()
end
if oldState.OpenApp == AppNameEnum.AvatarEditor then
if RefactoringAvatarEditorSetup then
AvatarEditorSetup:Close()
else
closeAvatarEditor()
end
end
end
end
)
installStudioTestingHooks(appState.store)
end
end
initMobile()
@@ -0,0 +1,5 @@
local scriptContext = game:GetService("ScriptContext")
local RobloxGui = game:GetService("CoreGui"):FindFirstChild("RobloxGui")
scriptContext:AddCoreScriptLocal("MobileMaster", RobloxGui)
@@ -0,0 +1,16 @@
local ActionTypeNames = {
"OpenApp",
}
local ActionType = {}
for i = 1, #ActionTypeNames do
ActionType[ActionTypeNames[i]] = ActionTypeNames[i]
end
setmetatable(ActionType, {
__index = function(self, key)
error(("Invalid ActionType %q"):format(tostring(key)))
end
})
return ActionType
@@ -0,0 +1,18 @@
local AppNames = {
"AvatarEditor",
"Chat",
"ShareGameToChat",
}
local AppNameEnum = {}
for i = 1, #AppNames do
AppNameEnum[AppNames[i]] = AppNames[i]
end
setmetatable(AppNameEnum, {
__index = function(self, key)
error(("Invalid AppNameEnum %q"):format(tostring(key)))
end
})
return AppNameEnum
@@ -0,0 +1,14 @@
local Modules = script.Parent.Parent
local Immutable = require(Modules.Common.Immutable)
return function(state, action)
state = state or {OpenApp = "", Paramters = {}}
if action.type == "OpenApp" then
state = Immutable.Set(state, "OpenApp", action.appName)
state = Immutable.Set(state, "Parameters", action.parameters)
end
return state
end
@@ -0,0 +1,24 @@
local Modules = script.Parent.Parent
local AppReducer = require(Modules.Mobile.AppReducer)
local Store = require(Modules.Common.Rodux).Store
local NavigationEventReceiver = require(Modules.Mobile.NavigationEventReceiver)
local AppState = {}
function AppState.new()
local state = {}
state.store = Store.new(AppReducer)
state.NavigationEventReceiver = NavigationEventReceiver:init(state)
return state
end
function AppState:Destruct()
self.store:Destruct()
end
return AppState
@@ -0,0 +1,213 @@
local CoreGui = game:GetService("CoreGui")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Modules = CoreGui.RobloxGui.Modules
local AppNameEnum = require(Modules.Mobile.AppNameEnum)
local Create = require(Modules.Mobile.Create)
local Constants = require(Modules.Mobile.Constants)
local AppGui = require(Modules.LuaApp.Legacy.AvatarEditor.AppGui)
local LuaAppConstants = require(Modules.LuaApp.Constants)
local AvatarEditorSetup = {}
function AvatarEditorSetup:Initialize(notifyAppReady, useRoactLuaApp)
--This is to cover the sky while loading, and also prevent the sky from flashing in when the global gui inset changes
local screenGui
if not UserSettings().GameSettings:InStudioMode() then
screenGui = Create.new "ScreenGui" {
Name = "SkyCoverGui",
DisplayOrder = 1,
Create.new "Frame" {
Name = "HackHeader",
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 0, UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.BLUE_PRESSED,
},
Create.new "Frame" {
Name = "HackBody",
Position = UDim2.new(0, 0, 0, UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y),
Size = UDim2.new(1, 0, 1, 200),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.WHITE,
},
}
else
screenGui = Create.new "ScreenGui" {
Name = "SkyCoverGui",
DisplayOrder = 1,
Create.new "Frame" {
Name = "HackHeader",
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 0, 64),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.BLUE_PRESSED,
},
Create.new "Frame" {
Name = "HackBody",
Position = UDim2.new(0, 0, 0, 64),
Size = UDim2.new(1, 0, 1, 200),
BorderSizePixel = 0,
BackgroundColor3 = Constants.Color.WHITE,
},
}
end
local function adjustScreenGuiLayout()
local headerHeight = UserInputService.NavBarSize.Y+UserInputService.StatusBarSize.Y
screenGui.HackHeader.Size = UDim2.new(1, 0, 0, headerHeight)
screenGui.HackBody.Position = UDim2.new(0, 0, 0, headerHeight)
end
local navBarChanged = UserInputService:GetPropertyChangedSignal("NavBarSize")
navBarChanged:Connect(function()
adjustScreenGuiLayout()
end)
local statusBarChanged = UserInputService:GetPropertyChangedSignal("StatusBarSize")
statusBarChanged:Connect(function()
adjustScreenGuiLayout()
end)
screenGui.Parent = CoreGui
if useRoactLuaApp then
screenGui.Enabled = false
end
--[[
As long as initializing AvatarEditorMain requires a yield, it has to run in a
spawned task. It is then possible for the user to switch apps in the middle of
initialization. So, openAvatarEditor and closeAvatarEditor first check to see
if it's currently initializing, and if it is, they set a bool indicating whether
to call Start() when initialization is done.
]]
local startAvatarEditorAfterInitializing = false
self.openAvatarEditor = function()
startAvatarEditorAfterInitializing = true
end
self.closeAvatarEditor = function()
startAvatarEditorAfterInitializing = false
end
local function avatarEditorInitialization()
spawn(function()
self.AppGui = nil
if not useRoactLuaApp then
local header
if not UserSettings().GameSettings:InStudioMode() then
header = require(Modules.LuaApp.Legacy.AvatarEditor.Header).new("Avatar",
UserInputService.NavBarSize.Y, UserInputService.StatusBarSize.Y)
local headerHeight = UserInputService.StatusBarSize.Y + UserInputService.NavBarSize.Y
self.AppGui = AppGui(
UDim2.new(0, 0, 0, headerHeight),
UDim2.new(1, 0, 1, -headerHeight))
local function updateUIDimensions()
header:SetNavAndStatusBarHeight(UserInputService.NavBarSize.Y, UserInputService.StatusBarSize.Y)
local headerHeight = UserInputService.NavBarSize.Y + UserInputService.StatusBarSize.Y
self:UpdateTopBarHeight(headerHeight)
end
UserInputService:GetPropertyChangedSignal("NavBarSize"):Connect( updateUIDimensions )
UserInputService:GetPropertyChangedSignal("StatusBarSize"):Connect( updateUIDimensions )
else
local navBarHeight = 44
local statusBarHeight = 20
header = require(Modules.LuaApp.Legacy.AvatarEditor.Header).new("Avatar",
navBarHeight, statusBarHeight)
local headerHeight = navBarHeight + statusBarHeight
self.AppGui = AppGui(
UDim2.new(0, 0, 0, headerHeight),
UDim2.new(1, 0, 1, -headerHeight))
end
header.rbx.Parent = self.AppGui.ScreenGui
else
-- Sync with default value in LuaApp topbar reducer
local topBarHeight = LuaAppConstants.TOP_BAR_SIZE
self.AppGui = AppGui(
UDim2.new(0, 0, 0, topBarHeight),
UDim2.new(1, 0, 1, -topBarHeight))
end
AvatarEditorMain =
require(Modules.LuaApp.Legacy.AvatarEditor.AvatarEditorMain)
.new(self.AppGui)
local function startAvatarEditor()
if useRoactLuaApp then
screenGui.Enabled = true
end
screenGui.HackBody.Visible = false
AvatarEditorMain:Start()
-- Staging broadcasting of APP_READY to accomodate for unpredictable
-- delay on the native side.
-- Once Lua tab bar is integrated, there will be no use for this
notifyAppReady(AppNameEnum.AvatarEditor)
end
if startAvatarEditorAfterInitializing then
startAvatarEditor()
end
self.openAvatarEditor = startAvatarEditor
self.closeAvatarEditor = function()
screenGui.HackBody.Visible = true
AvatarEditorMain:Stop()
if useRoactLuaApp then
screenGui.Enabled = false
end
end
end)
end
local hasRunInitialization = false
local renderSteppedConnection = nil
renderSteppedConnection = RunService.RenderStepped:connect(function()
if not hasRunInitialization then
hasRunInitialization = true
if renderSteppedConnection then
renderSteppedConnection:Disconnect()
end
avatarEditorInitialization()
end
end)
end
function AvatarEditorSetup:Open()
if not _G.__TESTEZ_RUNNING_TEST__ then
RunService:setThrottleFramerateEnabled(false)
end
self.openAvatarEditor()
end
function AvatarEditorSetup:Close()
if not _G.__TESTEZ_RUNNING_TEST__ then
RunService:setThrottleFramerateEnabled(true)
end
self.closeAvatarEditor()
end
function AvatarEditorSetup:UpdateTopBarHeight(topBarHeight)
if self.AppGui then
self.AppGui:setDimensions(
UDim2.new(0, 0, 0, topBarHeight),
UDim2.new(1, 0, 1, -topBarHeight))
end
end
return AvatarEditorSetup
@@ -0,0 +1,70 @@
local Constants = {
Color = {
GRAY1 = Color3.fromRGB(25, 25, 25),
GRAY2 = Color3.fromRGB(117, 117, 117),
GRAY3 = Color3.fromRGB(184, 184, 184),
GRAY4 = Color3.fromRGB(227, 227, 227),
GRAY5 = Color3.fromRGB(242, 242, 242),
GRAY6 = Color3.fromRGB(245, 245, 245),
WHITE = Color3.fromRGB(255, 255, 255),
BLUE_PRIMARY = Color3.fromRGB(0, 162, 255),
BLUE_HOVER = Color3.fromRGB(50, 181, 255),
BLUE_PRESSED = Color3.fromRGB(0, 116, 189),
BLUE_DISABLED = Color3.fromRGB(153, 218, 255),
GREEN_PRIMARY = Color3.fromRGB(2, 183, 87),
GREEN_HOVER = Color3.fromRGB(63, 198, 121),
GREEN_PRESSED = Color3.fromRGB(17, 130, 55),
GREEN_DISABLED = Color3.fromRGB(163, 226, 189),
RED_PRIMARY = Color3.fromRGB(226, 35, 26),
RED_NEGATIVE = Color3.fromRGB(216, 104, 104),
RED_HOVER = Color3.fromRGB(226, 118, 118),
RED_PRESSED = Color3.fromRGB(172, 30, 45),
ORANGE_WARNING = Color3.fromRGB(246, 136, 2),
ORANGE_FAVORITE = Color3.fromRGB(246, 183, 2),
BROWN_TIX = Color3.fromRGB(204, 158, 113),
ALPHA_SHADOW_PRIMARY = 0.3, -- Used with Gray1
ALPHA_SHADOW_HOVER = 0.75, -- Used with Gray1
CONVERSATION_BACKGROUND = Color3.fromRGB(224, 224, 224),
},
Header = {
HEIGHT = 64,
},
Tween = {
PHONE_TWEEN_TIME = 0.25,
PHONE_TWEEN_STYLE = Enum.EasingStyle.Quad,
PHONE_TWEEN_DIRECTION = Enum.EasingDirection.Out,
},
PresenceType = {
NONE = "NONE",
ONLINE = "ONLINE",
IN_GAME = "IN_GAME",
IN_STUDIO = "IN_STUDIO",
},
ServerState = {
NONE = "NONE",
CREATING = "CREATING",
CREATED = "CREATED",
},
ConversationLoadingState = {
NONE = "NONE",
LOADING = "LOADING",
DONE = "DONE"
},
PresenceColors = {
NONE = nil, --Your code will crash if you render this. Intended.
ONLINE = Color3.fromRGB(0, 162, 255),
IN_GAME = Color3.fromRGB(2, 183, 87),
IN_STUDIO = Color3.fromRGB(246, 136, 2),
},
Text = {
INPUT_PLACEHOLDER = Color3.fromRGB(189, 189, 189),
INPUT = Color3.fromRGB(25, 25, 25),
POST_TYPING_STATUS_INTERVAL = 3, --How frequently do we POST our typing status if we're still typing
},
MAX_PARTICIPANT_COUNT = 5,
MIN_PARTICIPANT_COUNT = 2,
-- This value actually comes from iOS, but we are shortcutting actually getting the value from there.
TAB_BAR_SIZE = 49,
}
return Constants
@@ -0,0 +1,82 @@
local Create = {
events = {}
}
--[[
Merge a list of dictionary tables into one table
]]
function Create.merge(...)
if select("#", ...) == 1 then
return (...)
end
local new = {}
for i = 1, select("#", ...) do
for key, value in pairs(select(i, ...)) do
-- Push numeric keys as a list
if (type(key) == "number") then
table.insert(new, value)
else
new[key] = value
end
end
end
return new
end
--[[
Create a new instance with the given type properties.
Usage:
Create.new "Frame" {
Name = "MyFrame"
}
-- OR --
Create "Frame" {
Name = "MyFrame"
}
Makes no assumptions about the types of children added. The only requirement
is that the "Parent" property on them can be assigned.
]]
function Create.new(name)
return function(...)
local props = Create.merge(...)
local new = Instance.new(name)
-- Add properties to this instance; all string keys are property names
for key, value in pairs(props) do
if type(key) == "string" then
assert(key ~= "Parent", "Don't set 'Parent' using Create!")
new[key] = value
elseif type(key) == "table" then
-- Events use a special-case key
if key == Create.events then
for name, event in pairs(value) do
new[name]:connect(event)
end
end
end
end
-- Add children after all the properties are set
for _, child in ipairs(props) do
child.Parent = new
end
return new
end
end
setmetatable(Create, {
__call = function(self, ...)
return Create.new(...)
end
})
return Create
@@ -0,0 +1,33 @@
local Modules = script.Parent
local ActionType = require(Modules.ActionType)
local NotificationService = game:GetService("NotificationService")
local HttpService = game:GetService("HttpService")
local NavigationEventReceiver = {}
function NavigationEventReceiver:init(appState)
local function onNaviationNotifications(eventData)
local decodedDetail = HttpService:JSONDecode(eventData.detail)
local detailType = decodedDetail.Type or eventData.detailType
if detailType == "Destination" then
if decodedDetail.appName then
appState.store:dispatch( {type = ActionType.OpenApp, appName = decodedDetail.appName, parameters = decodedDetail.parameters} )
else
appState.store:dispatch( {type = ActionType.OpenApp, appName = eventData.detail, parameters = {}} )
end
end
end
local function onRobloxEventReceived(eventData)
if eventData.namespace == "Navigations" then
onNaviationNotifications(eventData)
end
end
NotificationService.RobloxEventReceived:connect(onRobloxEventReceived)
end
return NavigationEventReceiver