Clients/Client2018/content/scripts/CoreScripts/Modules/NewChat.lua

295 lines
9.9 KiB
Lua

--[[
// FileName: NewChat.lua
// Written by: Xsitsu
// Description: Bridges the topbar in corescripts to any chat system running in the non-corescripts environment.
]]
local CoreGuiService = game:GetService("CoreGui")
local RobloxGui = CoreGuiService:WaitForChild("RobloxGui")
local StarterGui = game:GetService("StarterGui")
local GuiService = game:GetService("GuiService")
local PlayersService = game:GetService("Players")
local ChatTypesSet = false
local ClassicChatEnabled = PlayersService.ClassicChat
local BubbleChatEnabled = PlayersService.BubbleChat
local Util = require(RobloxGui.Modules.ChatUtil)
local moduleApiTable = {}
do
local ChatWindowState =
{
Visible = true,
MessageCount = 0,
TopbarEnabled = true,
CoreGuiEnabled = true,
}
local communicationsConnections = {}
local eventConnections = {}
local SetCoreCache = {}
local function FindInCollectionByKeyAndType(collection, indexName, type)
if (collection and collection[indexName] and collection[indexName]:IsA(type)) then
return collection[indexName]
end
return nil
end
local function DispatchEvent(eventName, ...)
local event = FindInCollectionByKeyAndType(communicationsConnections.ChatWindow, eventName, "BindableEvent")
if (event) then
event:Fire(...)
return true
end
return false
end
local function AttemptInvokeFunction(functionName, ...)
local func = FindInCollectionByKeyAndType(communicationsConnections.ChatWindow, functionName, "BindableFunction")
if (func) then
return true, func:Invoke()
end
return false, nil
end
local function DoConnectGetCore(connectionName)
StarterGui:RegisterGetCore(connectionName, function(data)
local func = FindInCollectionByKeyAndType(communicationsConnections.GetCore, connectionName, "BindableFunction")
local rVal = nil
if (func) then rVal = func:Invoke(data) end
return rVal
end)
end
function moduleApiTable:ToggleVisibility()
ChatWindowState.Visible = not ChatWindowState.Visible
local didFire = DispatchEvent("ToggleVisibility")
if (not didFire) then
moduleApiTable.VisibilityStateChanged:fire(ChatWindowState.Visible)
end
end
function moduleApiTable:SetVisible(visible)
ChatWindowState.Visible = visible
local didFire = DispatchEvent("SetVisible", ChatWindowState.Visible)
if (not didFire) then
moduleApiTable.VisibilityStateChanged:fire(ChatWindowState.Visible)
end
end
function moduleApiTable:FocusChatBar()
DispatchEvent("FocusChatBar")
end
function moduleApiTable:GetVisibility()
local success, retVal = AttemptInvokeFunction("GetVisibility")
if (success) then
return retVal
else
return ChatWindowState.Visible
end
end
function moduleApiTable:GetMessageCount()
local success, retVal = AttemptInvokeFunction("GetMessageCount")
if (success) then
return retVal
else
return ChatWindowState.MessageCount
end
end
function moduleApiTable:TopbarEnabledChanged(enabled)
ChatWindowState.TopbarEnabled = enabled
DispatchEvent("TopbarEnabledChanged", ChatWindowState.TopbarEnabled)
end
function moduleApiTable:IsFocused(useWasFocused)
local success, retVal = AttemptInvokeFunction("IsFocused", useWasFocused)
if (success) then
return retVal
else
return false
end
end
function moduleApiTable:ClassicChatEnabled()
return ClassicChatEnabled
end
function moduleApiTable:IsBubbleChatOnly()
return BubbleChatEnabled and not ClassicChatEnabled
end
function moduleApiTable:IsDisabled()
return not (BubbleChatEnabled or ClassicChatEnabled)
end
function SetInitialChatTypes(chatTypesTable)
if ChatTypesSet then
return
end
ChatTypesSet = true
local bubbleChat = chatTypesTable.BubbleChatEnabled
local classicChat = chatTypesTable.ClassicChatEnabled
if type(bubbleChat) == "boolean" then
BubbleChatEnabled = bubbleChat
end
if type(classicChat) == "boolean" then
ClassicChatEnabled = classicChat
end
if not (ClassicChatEnabled or BubbleChatEnabled) then
moduleApiTable.ChatDisabled:fire()
end
if BubbleChatEnabled and not ClassicChatEnabled then
moduleApiTable.BubbleChatOnlySet:fire()
end
end
moduleApiTable.ChatBarFocusChanged = Util.Signal()
moduleApiTable.VisibilityStateChanged = Util.Signal()
moduleApiTable.MessagesChanged = Util.Signal()
-- Signals that are called when we get information on if Bubble Chat and Classic chat are enabled from the chat.
moduleApiTable.BubbleChatOnlySet = Util.Signal()
moduleApiTable.ChatDisabled = Util.Signal()
StarterGui.CoreGuiChangedSignal:connect(function(coreGuiType, enabled)
if (coreGuiType == Enum.CoreGuiType.All or coreGuiType == Enum.CoreGuiType.Chat) then
ChatWindowState.CoreGuiEnabled = enabled
DispatchEvent("CoreGuiEnabled", ChatWindowState.CoreGuiEnabled)
end
end)
GuiService:AddSpecialKey(Enum.SpecialKey.ChatHotkey)
GuiService.SpecialKeyPressed:connect(function(key, modifiers)
DispatchEvent("SpecialKeyPressed", key, modifiers)
end)
function DoConnectSetCore(setCoreName)
StarterGui:RegisterSetCore(setCoreName, function(data)
local event = FindInCollectionByKeyAndType(communicationsConnections.SetCore, setCoreName, "BindableEvent")
if (event) then
event:Fire(data)
else
if SetCoreCache[setCoreName] == nil then
SetCoreCache[setCoreName] = {}
end
table.insert(SetCoreCache[setCoreName], data)
end
end)
end
DoConnectSetCore("ChatMakeSystemMessage")
DoConnectSetCore("ChatWindowPosition")
DoConnectSetCore("ChatWindowSize")
DoConnectSetCore("ChatBarDisabled")
DoConnectGetCore("ChatWindowPosition")
DoConnectGetCore("ChatWindowSize")
DoConnectGetCore("ChatBarDisabled")
local function RegisterCoreGuiConnections(containerTable)
if (type(containerTable) == "table") then
local chatWindowCollection = containerTable.ChatWindow
local setCoreCollection = containerTable.SetCore
local getCoreCollection = containerTable.GetCore
if (type(chatWindowCollection) == "table") then
for i, v in pairs(eventConnections) do
v:disconnect()
end
if type(chatWindowCollection.ChatTypes) == "table" then
SetInitialChatTypes(chatWindowCollection.ChatTypes)
end
eventConnections = {}
communicationsConnections.ChatWindow = {}
communicationsConnections.ChatWindow.ToggleVisibility = FindInCollectionByKeyAndType(chatWindowCollection, "ToggleVisibility", "BindableEvent")
communicationsConnections.ChatWindow.SetVisible = FindInCollectionByKeyAndType(chatWindowCollection, "SetVisible", "BindableEvent")
communicationsConnections.ChatWindow.FocusChatBar = FindInCollectionByKeyAndType(chatWindowCollection, "FocusChatBar", "BindableEvent")
communicationsConnections.ChatWindow.TopbarEnabledChanged = FindInCollectionByKeyAndType(chatWindowCollection, "TopbarEnabledChanged", "BindableEvent")
communicationsConnections.ChatWindow.IsFocused = FindInCollectionByKeyAndType(chatWindowCollection, "IsFocused", "BindableFunction")
communicationsConnections.ChatWindow.SpecialKeyPressed = FindInCollectionByKeyAndType(chatWindowCollection, "SpecialKeyPressed", "BindableEvent")
local function DoConnect(index)
communicationsConnections.ChatWindow[index] = FindInCollectionByKeyAndType(chatWindowCollection, index, "BindableEvent")
if (communicationsConnections.ChatWindow[index]) then
local con = communicationsConnections.ChatWindow[index].Event:connect(function(...) moduleApiTable[index]:fire(...) end)
table.insert(eventConnections, con)
end
end
DoConnect("ChatBarFocusChanged")
DoConnect("VisibilityStateChanged")
DoConnect("MessagesChanged")
local index = "MessagePosted"
communicationsConnections.ChatWindow[index] = FindInCollectionByKeyAndType(chatWindowCollection, index, "BindableEvent")
if (communicationsConnections.ChatWindow[index]) then
local con = communicationsConnections.ChatWindow[index].Event:connect(function(message) game:GetService("Players"):Chat(message) end)
table.insert(eventConnections, con)
end
moduleApiTable:SetVisible(ChatWindowState.Visible)
moduleApiTable:TopbarEnabledChanged(ChatWindowState.TopbarEnabled)
local event = FindInCollectionByKeyAndType(chatWindowCollection, "CoreGuiEnabled", "BindableEvent")
if (event) then
communicationsConnections.ChatWindow.CoreGuiEnabled = event
event:Fire(ChatWindowState.CoreGuiEnabled)
end
else
error("Table 'ChatWindow' must be provided!")
end
if (type(setCoreCollection) == "table" and type(getCoreCollection) == "table") then
communicationsConnections.SetCore = {}
communicationsConnections.GetCore = {}
local function addSetCore(setCoreName)
local event = FindInCollectionByKeyAndType(setCoreCollection, setCoreName, "BindableEvent")
if (event) then
communicationsConnections.SetCore[setCoreName] = event
if SetCoreCache[setCoreName] then
for i, data in pairs(SetCoreCache[setCoreName]) do
event:Fire(data)
end
SetCoreCache[setCoreName] = nil
end
end
end
addSetCore("ChatMakeSystemMessage")
addSetCore("ChatWindowPosition")
addSetCore("ChatWindowSize")
addSetCore("ChatBarDisabled")
communicationsConnections.GetCore.ChatWindowPosition = FindInCollectionByKeyAndType(getCoreCollection, "ChatWindowPosition", "BindableFunction")
communicationsConnections.GetCore.ChatWindowSize = FindInCollectionByKeyAndType(getCoreCollection, "ChatWindowSize", "BindableFunction")
communicationsConnections.GetCore.ChatBarDisabled = FindInCollectionByKeyAndType(getCoreCollection, "ChatBarDisabled", "BindableFunction")
elseif (type(setCoreCollection) ~= "nil" or type(getCoreCollection) ~= "nil") then
error("Both 'SetCore' and 'GetCore' must be tables if provided!")
end
end
end
StarterGui:RegisterSetCore("CoreGuiChatConnections", RegisterCoreGuiConnections)
end
return moduleApiTable