add gs
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local RunService = game:GetService("RunService")
|
||||
local Players = game:GetService("Players")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local LuaApp = Modules.LuaApp
|
||||
|
||||
local Rodux = require(Modules.Common.Rodux)
|
||||
|
||||
local AppReducer = require(LuaApp.AppReducer)
|
||||
local AppState = require(LuaChat.AppState)
|
||||
local Config = require(LuaApp.Config)
|
||||
local NotificationType = require(LuaApp.Enum.NotificationType)
|
||||
local DebugManager = require(LuaChat.Debug.DebugManager)
|
||||
local Device = require(LuaChat.Device)
|
||||
local DialogInfo = require(LuaChat.DialogInfo)
|
||||
local NotificationBroadcaster = require(Modules.LuaChat.NotificationBroadcaster)
|
||||
local PerformanceTesting = require(LuaApp.PerformanceTesting)
|
||||
local RobloxEventReceiver = require(Modules.LuaChat.RobloxEventReceiver)
|
||||
local FlagSettings = require(LuaApp.FlagSettings)
|
||||
|
||||
local GetLocalUser = require(LuaApp.Thunks.GetLocalUser)
|
||||
local SetRoute = require(LuaChat.Actions.SetRoute)
|
||||
local PopRoute = require(LuaChat.Actions.PopRoute)
|
||||
local ToggleChatPaused = require(LuaChat.Actions.ToggleChatPaused)
|
||||
|
||||
local Alert = require(LuaChat.Views.Phone.Alert)
|
||||
local ToastView = require(LuaChat.Views.ToastView)
|
||||
|
||||
local Intent = DialogInfo.Intent
|
||||
|
||||
local ChatMaster = {}
|
||||
ChatMaster.__index = ChatMaster
|
||||
|
||||
ChatMaster.Type = {
|
||||
Default = "Default",
|
||||
GameShare = "GameShare",
|
||||
}
|
||||
|
||||
function ChatMaster.new(roduxStore)
|
||||
local self = {}
|
||||
setmetatable(self, ChatMaster)
|
||||
|
||||
if Players.LocalPlayer == nil then
|
||||
Players.PlayerAdded:Wait()
|
||||
end
|
||||
|
||||
-- In debug mode, load the DebugManager overlay and logging system
|
||||
if Config.LuaChat.Debug then
|
||||
warn("CHAT DEBUG MODE IS ENABLED")
|
||||
DebugManager:Initialize(CoreGui)
|
||||
DebugManager:Start()
|
||||
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)
|
||||
|
||||
roduxStore = roduxStore or Rodux.Store.new(AppReducer)
|
||||
|
||||
-- Device has to be called before AppState is constructed because constructor for
|
||||
-- ScreenManager needs to know device type/orientation. ScreenManager is bound to
|
||||
-- AppState since Views in LuaChat needs to access it directly for GetCurrentView().
|
||||
Device.simulatePlatformIfInStudio(roduxStore)
|
||||
|
||||
self._appState = AppState.new(CoreGui, roduxStore)
|
||||
self._chatRunning = false
|
||||
self._gameShareRunning = false
|
||||
|
||||
PerformanceTesting:Initialize(self._appState)
|
||||
|
||||
RobloxEventReceiver:init(roduxStore)
|
||||
self._notificationBroadcaster = NotificationBroadcaster.new(roduxStore)
|
||||
|
||||
do
|
||||
self._screenGui = Instance.new("ScreenGui")
|
||||
self._screenGui.DisplayOrder = 9
|
||||
self._screenGui.Parent = CoreGui
|
||||
self._alertView = Alert.new(self._appState)
|
||||
self._alertView.rbx.Parent = self._screenGui
|
||||
self._alertView.rbx.Name = "AlertView"
|
||||
self._toastView = ToastView.new(self._appState)
|
||||
self._toastView.rbx.Parent = self._screenGui
|
||||
self._toastView.rbx.Name = "ToastView"
|
||||
end
|
||||
|
||||
if not FlagSettings:IsLuaAppStarterScriptEnabled() then
|
||||
self._appState.store:dispatch(GetLocalUser())
|
||||
end
|
||||
|
||||
-- Connection for dealing with the Android native back button
|
||||
self.backButtonConnection = nil
|
||||
self.onBackButtonPressed = function()
|
||||
if #self._appState.store:getState().ChatAppReducer.Location.history > 1 then
|
||||
self._appState.store:dispatch(PopRoute())
|
||||
else
|
||||
GuiService:BroadcastNotification("", NotificationType.BACK_BUTTON_NOT_CONSUMED)
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ChatMaster:Start(startType, parameters)
|
||||
if not startType then
|
||||
startType = ChatMaster.Type.Default
|
||||
end
|
||||
|
||||
--pcall since tests run at a lower security context
|
||||
pcall(function()
|
||||
RunService:setThrottleFramerateEnabled(Config.General.PerformanceTestingMode == Enum.VirtualInputMode.None)
|
||||
RunService:Set3dRenderingEnabled(false)
|
||||
|
||||
self.backButtonConnection = GuiService.ShowLeaveConfirmation:Connect(self.onBackButtonPressed)
|
||||
end)
|
||||
|
||||
self._appState.store:dispatch(ToggleChatPaused(false))
|
||||
|
||||
if startType == ChatMaster.Type.Default then
|
||||
|
||||
if not next(self._appState.store:getState().ChatAppReducer.Location.current) then
|
||||
self._appState.store:dispatch(SetRoute(Intent.ConversationHub, {}))
|
||||
end
|
||||
self._chatRunning = true
|
||||
|
||||
elseif startType == ChatMaster.Type.GameShare then
|
||||
|
||||
self._appState.store:dispatch(SetRoute(Intent.GameShare, parameters))
|
||||
self._gameShareRunning = true
|
||||
end
|
||||
end
|
||||
|
||||
function ChatMaster:Stop(stopType)
|
||||
if not stopType then
|
||||
stopType = ChatMaster.Type.Default
|
||||
end
|
||||
|
||||
if stopType == ChatMaster.Type.Default and self._gameShareRunning then
|
||||
warn('cannot stop chat while share game to chat is running')
|
||||
return
|
||||
end
|
||||
|
||||
if stopType == ChatMaster.Type.GameShare and self._chatRunning then
|
||||
warn('cannot stop share game to chat while chat is running')
|
||||
return
|
||||
end
|
||||
|
||||
PerformanceTesting:Stop()
|
||||
|
||||
self._chatRunning = false
|
||||
self._gameShareRunning = false
|
||||
|
||||
--pcall since tests run at a lower security context
|
||||
pcall(function()
|
||||
RunService:setThrottleFramerateEnabled(false)
|
||||
RunService:Set3dRenderingEnabled(true)
|
||||
end)
|
||||
|
||||
if self.backButtonConnection ~= nil then
|
||||
self.backButtonConnection:Disconnect()
|
||||
end
|
||||
|
||||
self._appState.store:dispatch(ToggleChatPaused(true))
|
||||
end
|
||||
|
||||
function ChatMaster:Destruct()
|
||||
-- Doesn't Destruct AppState since the store could be still used elsewhere.
|
||||
self._screenGui:Destroy()
|
||||
self._notificationBroadcaster:Destruct()
|
||||
end
|
||||
|
||||
return ChatMaster
|
||||
@@ -0,0 +1,119 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local ChatMaster = require(Modules.ChatMaster)
|
||||
local Rodux = require(Modules.Common.Rodux)
|
||||
local AppReducer = require(Modules.LuaApp.AppReducer)
|
||||
local DialogInfo = require(Modules.LuaChat.DialogInfo)
|
||||
local RemoveRoute = require(Modules.LuaChat.Actions.RemoveRoute)
|
||||
local SetRoute = require(Modules.LuaChat.Actions.SetRoute)
|
||||
|
||||
local function closeGameShare(chatMaster)
|
||||
chatMaster._appState.store:dispatch(RemoveRoute(DialogInfo.Intent.GameShare))
|
||||
chatMaster:Stop(ChatMaster.Type.GameShare)
|
||||
end
|
||||
|
||||
describe("new", function()
|
||||
it("should create a ChatMaster object", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
|
||||
it("should optionally take a rodux store as an argument", function()
|
||||
local store = Rodux.Store.new(AppReducer)
|
||||
local chatMaster = ChatMaster.new(store)
|
||||
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Start", function()
|
||||
it("should open chat with no arguments", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
chatMaster:Start()
|
||||
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
|
||||
it("should open Share Game To Chat with valid arguments", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Stop", function()
|
||||
it("should close chat with no arguments", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
chatMaster:Start()
|
||||
chatMaster:Stop()
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
|
||||
it("should close given GameShare as an argument", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
chatMaster:Stop(ChatMaster.Type.GameShare)
|
||||
expect(chatMaster).to.be.ok()
|
||||
end)
|
||||
|
||||
it("closing after GameShare should remove GameShare route", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
local appState = chatMaster._appState
|
||||
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.GameShare)
|
||||
closeGameShare(chatMaster)
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.never.equal(DialogInfo.Intent.GameShare)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("LuaChat and GameShare interaction", function()
|
||||
it("opening LuaChat after closing GameShare should open the ConversationHub", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
local appState = chatMaster._appState
|
||||
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.GameShare)
|
||||
closeGameShare(chatMaster)
|
||||
chatMaster:Start(ChatMaster.Type.Default)
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.ConversationHub)
|
||||
end)
|
||||
|
||||
it("opening GameShare after closing LuaChat should open the GameShare screen", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
local appState = chatMaster._appState
|
||||
|
||||
chatMaster:Start(ChatMaster.Type.Default)
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.ConversationHub)
|
||||
chatMaster:Stop(ChatMaster.Type.Default)
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.GameShare)
|
||||
|
||||
closeGameShare(chatMaster)
|
||||
chatMaster:Start(ChatMaster.Type.Default)
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current.intent).to.equal(DialogInfo.Intent.ConversationHub)
|
||||
end)
|
||||
|
||||
it("closing GameShare should preserve the user's location history", function()
|
||||
local chatMaster = ChatMaster.new()
|
||||
local appState = chatMaster._appState
|
||||
|
||||
chatMaster:Start()
|
||||
appState.store:dispatch(SetRoute(DialogInfo.Intent.Conversation, {conversationId = "1"}))
|
||||
chatMaster:Stop()
|
||||
|
||||
local conversationLocation = appState.store:getState().ChatAppReducer.Location.current
|
||||
expect(conversationLocation).to.be.ok()
|
||||
|
||||
chatMaster:Start(ChatMaster.Type.GameShare, {placeId = "1818"})
|
||||
closeGameShare(chatMaster)
|
||||
|
||||
chatMaster:Start()
|
||||
expect(appState.store:getState().ChatAppReducer.Location.current).to.equal(conversationLocation)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(user)
|
||||
return {
|
||||
user = user,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(id, participants, title, lastUpdated)
|
||||
return {
|
||||
conversationId = id,
|
||||
participants = participants,
|
||||
title = title,
|
||||
lastUpdated = lastUpdated,
|
||||
}
|
||||
end)
|
||||
+1075
File diff suppressed because it is too large
Load Diff
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(alert)
|
||||
return {
|
||||
alert = alert,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(placeIds)
|
||||
return {
|
||||
placeIds = placeIds,
|
||||
}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(imageToken)
|
||||
return {
|
||||
imageToken = imageToken,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,19 @@
|
||||
local LuaChat = script.Parent.Parent
|
||||
local WebApi = require(LuaChat.WebApi)
|
||||
local SetChatEnabled = require(LuaChat.Actions.SetChatEnabled)
|
||||
|
||||
return function(onSuccess)
|
||||
return function(store)
|
||||
spawn(function()
|
||||
local status, response = WebApi.GetChatSettings()
|
||||
if status ~= WebApi.Status.OK then
|
||||
warn("Failure in WebApi.GetChatSettings", status)
|
||||
return
|
||||
end
|
||||
store:dispatch(SetChatEnabled(response.chatEnabled))
|
||||
if onSuccess then
|
||||
onSuccess(response.chatEnabled)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
local LuaChat = script.Parent.Parent
|
||||
local WebApi = require(LuaChat.WebApi)
|
||||
local FetchChatSettingsStarted = require(LuaChat.Actions.FetchChatSettingsStarted)
|
||||
local FetchChatSettingsCompleted = require(LuaChat.Actions.FetchChatSettingsCompleted)
|
||||
local FetchChatSettingsFailed = require(LuaChat.Actions.FetchChatSettingsFailed)
|
||||
|
||||
return function(onSuccess)
|
||||
return function(store)
|
||||
store:dispatch(FetchChatSettingsStarted())
|
||||
|
||||
spawn(function()
|
||||
local status, response = WebApi.GetChatSettings()
|
||||
if status ~= WebApi.Status.OK then
|
||||
store:dispatch(FetchChatSettingsFailed(status))
|
||||
warn("Failure in WebApi.GetChatSettings", status)
|
||||
return
|
||||
end
|
||||
store:dispatch(FetchChatSettingsCompleted(response))
|
||||
if onSuccess then
|
||||
onSuccess(response)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(settings)
|
||||
return {
|
||||
settings = settings,
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(status)
|
||||
return {
|
||||
status = status,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(isFetchedOldestConversation)
|
||||
return {
|
||||
value = isFetchedOldestConversation,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, isFetchedOldestMessage)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
fetchedOldestMessage = isFetchedOldestMessage,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, isFetchingOlderMessages)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
fetchingOlderMessages = isFetchingOlderMessages,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,13 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
local RetrievalStatus = require(Modules.LuaApp.Enum.RetrievalStatus)
|
||||
|
||||
return Action(script.Name, function(userId)
|
||||
return {
|
||||
userId = userId,
|
||||
status = RetrievalStatus.Fetching,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,18 @@
|
||||
local Modules = script.Parent.Parent
|
||||
|
||||
local WebApi = require(Modules.WebApi)
|
||||
|
||||
local SetFriendCount = require(Modules.Actions.SetFriendCount)
|
||||
|
||||
return function()
|
||||
return function(store)
|
||||
spawn(function()
|
||||
local status, totalCount = WebApi.GetFriendCount()
|
||||
if status ~= WebApi.Status.OK then
|
||||
store:dispatch(SetFriendCount(0)) -- Remember to come back and add status instead of setting to zero
|
||||
else
|
||||
store:dispatch(SetFriendCount(totalCount))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local WebApi = require(LuaChat.WebApi)
|
||||
local PlaceInfoModel = require(LuaChat.Models.PlaceInfoModel)
|
||||
|
||||
local RequestMultiplePlaceInfos = require(LuaChat.Actions.RequestMultiplePlaceInfos)
|
||||
local FailedToFetchMultiplePlaceInfos = require(LuaChat.Actions.FailedToFetchMultiplePlaceInfos)
|
||||
local ReceivedMultiplePlaceInfos = require(LuaChat.Actions.ReceivedMultiplePlaceInfos)
|
||||
|
||||
return function(placeIdList)
|
||||
return function(store)
|
||||
local state = store:getState()
|
||||
local placesToFetch = {}
|
||||
|
||||
if state.ChatAppReducer.PlaceInfos then
|
||||
for _, placeId in pairs(placeIdList) do
|
||||
if not state.ChatAppReducer.PlaceInfosAsync[placeId] then
|
||||
table.insert(placesToFetch, placeId)
|
||||
end
|
||||
end
|
||||
if #placesToFetch == 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
store:dispatch(RequestMultiplePlaceInfos(placesToFetch))
|
||||
|
||||
spawn(function()
|
||||
local status, result = WebApi.GetMultiplePlaceInfos(placesToFetch)
|
||||
|
||||
if status ~= WebApi.Status.OK then
|
||||
warn("WebApi failure in GetMultiplePlaceInfos")
|
||||
store:dispatch(FailedToFetchMultiplePlaceInfos(placesToFetch))
|
||||
return
|
||||
end
|
||||
|
||||
local placeInfos = {}
|
||||
for _, placeInfoData in pairs(result) do
|
||||
table.insert(placeInfos, PlaceInfoModel.fromWeb(placeInfoData))
|
||||
end
|
||||
store:dispatch(ReceivedMultiplePlaceInfos(placeInfos))
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
local Modules = script.Parent.Parent
|
||||
|
||||
local WebApi = require(Modules.WebApi)
|
||||
local ThumbnailModel = require(Modules.Models.ThumbnailModel)
|
||||
|
||||
local RequestPlaceThumbnail = require(Modules.Actions.RequestPlaceThumbnail)
|
||||
local ReceivedPlaceThumbnail = require(Modules.Actions.ReceivedPlaceThumbnail)
|
||||
local FailedToFetchPlaceThumbnail = require(Modules.Actions.FailedToFetchPlaceThumbnail)
|
||||
|
||||
local RETRY_COUNT = 3
|
||||
local WAIT_TIME = 2
|
||||
|
||||
return function(imageToken, width, height)
|
||||
return function(store)
|
||||
local state = store:getState()
|
||||
if state.ChatAppReducer.PlaceThumbnailsAsync[imageToken] then
|
||||
return
|
||||
end
|
||||
store:dispatch(RequestPlaceThumbnail(imageToken))
|
||||
|
||||
spawn(function()
|
||||
local thumbnail = ''
|
||||
local retryCount = RETRY_COUNT
|
||||
local waitTime = WAIT_TIME
|
||||
|
||||
while (retryCount > 0) do
|
||||
local status, result = WebApi.GetPlaceThumbnail(imageToken, width, height)
|
||||
if status ~= WebApi.Status.OK then
|
||||
warn("WebApi failure in GetPlaceThumbnail")
|
||||
store:dispatch(FailedToFetchPlaceThumbnail(imageToken))
|
||||
break
|
||||
else
|
||||
local placeThumbnailData = result[1]
|
||||
if placeThumbnailData.final == true then
|
||||
thumbnail = placeThumbnailData.url
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
retryCount = retryCount - 1
|
||||
if retryCount > 0 then
|
||||
wait(waitTime)
|
||||
waitTime = waitTime * 2
|
||||
end
|
||||
end
|
||||
|
||||
local thumbnailModel = ThumbnailModel.fromWeb(thumbnail)
|
||||
store:dispatch(ReceivedPlaceThumbnail(imageToken, thumbnailModel))
|
||||
|
||||
end)
|
||||
end
|
||||
end
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, messageId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
messageId = messageId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, messageId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
messageId = messageId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,185 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local PlaceInfoModel = require(LuaChat.Models.PlaceInfoModel)
|
||||
local ToastModel = require(LuaChat.Models.ToastModel)
|
||||
local WebApi = require(LuaChat.WebApi)
|
||||
|
||||
local FailedToFetchedMostRecentlyPlayedGames = require(Actions.FailedToFetchMostRecentlyPlayedGames)
|
||||
local FailedToFetchMultiplePlaceInfos = require(Actions.FailedToFetchMultiplePlaceInfos)
|
||||
local FetchedMostRecentlyPlayedGames = require(Actions.FetchedMostRecentlyPlayedGames)
|
||||
local FetchingMostRecentlyPlayedGames = require(Actions.FetchingMostRecentlyPlayedGames)
|
||||
local GameFailedToPin = require(Actions.GameFailedToPin)
|
||||
local GameFailedToUnpin = require(Actions.GameFailedToUnpin)
|
||||
local PinnedGame = require(Actions.PinnedGame)
|
||||
local PinningGame = require(Actions.PinningGame)
|
||||
local ReceivedMultiplePlaceInfos = require(Actions.ReceivedMultiplePlaceInfos)
|
||||
local RequestMultiplePlaceInfos = require(Actions.RequestMultiplePlaceInfos)
|
||||
local SetMostRecentlyPlayedGamesForUser = require(Actions.SetMostRecentlyPlayedGamesForUser)
|
||||
local SetMostRecentlyPlayedPlayableGameForUser = require(Actions.SetMostRecentlyPlayedPlayableGameForUser)
|
||||
local SetPinnedGameForConversation = require(Actions.SetPinnedGameForConversation)
|
||||
local ShowToast = require(Actions.ShowToast)
|
||||
local UnpinnedGame = require(Actions.UnpinnedGame)
|
||||
local UnpinningGame = require(Actions.UnpinningGame)
|
||||
|
||||
local PlayTogetherActions = {}
|
||||
|
||||
local HOME_GAMES_SORTS = "HomeSorts"
|
||||
local MOST_RECENTLY_PLAYED_GAMES = "MyRecent"
|
||||
|
||||
function PlayTogetherActions.PinGame(conversationId, universeId)
|
||||
return function(store)
|
||||
if universeId == store:getState().ChatAppReducer.Conversations[conversationId].pinnedGame.universeId then
|
||||
local messageKey = "Feature.Chat.Message.AlreadyPinnedGame"
|
||||
local toastModel = ToastModel.new(Constants.ToastIDs.PIN_PINNED_GAME, messageKey)
|
||||
store:dispatch(ShowToast(toastModel))
|
||||
return
|
||||
end
|
||||
|
||||
if store:getState().ChatAppReducer.PlayTogetherAsync.pinningGames[conversationId] then
|
||||
return
|
||||
end
|
||||
|
||||
store:dispatch(PinningGame(conversationId))
|
||||
|
||||
spawn(function()
|
||||
local status, _ = WebApi.PinGame(conversationId, universeId)
|
||||
if status == WebApi.Status.OK then
|
||||
store:dispatch(PinnedGame(conversationId))
|
||||
else
|
||||
store:dispatch(GameFailedToPin(conversationId))
|
||||
|
||||
local messageKey = "Feature.Chat.Message.PinFailed"
|
||||
local toastModel = ToastModel.new(Constants.ToastIDs.PIN_GAME_FAILED, messageKey)
|
||||
store:dispatch(ShowToast(toastModel))
|
||||
|
||||
warn("Game could not be pinned.")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayTogetherActions.UnpinGame(conversationId)
|
||||
return function(store)
|
||||
if store:getState().ChatAppReducer.PlayTogetherAsync.unPinningGames[conversationId] then
|
||||
return
|
||||
end
|
||||
|
||||
store:dispatch(UnpinningGame(conversationId))
|
||||
|
||||
spawn(function()
|
||||
local status, _ = WebApi.UnpinGame(conversationId)
|
||||
if status == WebApi.Status.OK then
|
||||
store:dispatch(UnpinnedGame(conversationId))
|
||||
else
|
||||
store:dispatch(GameFailedToUnpin(conversationId))
|
||||
|
||||
local messageKey = "Feature.Chat.Message.UnpinFailed"
|
||||
local toastModel = ToastModel.new(Constants.ToastIDs.UNPIN_GAME_FAILED, messageKey)
|
||||
store:dispatch(ShowToast(toastModel))
|
||||
|
||||
warn("Game could not be unpinned.")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayTogetherActions.SetPinnedGameForConversation(universeId, rootPlaceId, conversationId)
|
||||
return function(store)
|
||||
spawn(function()
|
||||
store:dispatch(SetPinnedGameForConversation(
|
||||
universeId,
|
||||
rootPlaceId,
|
||||
conversationId
|
||||
))
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayTogetherActions.GetMostRecentlyPlayedGames()
|
||||
return function(store)
|
||||
spawn(function()
|
||||
if store:getState().ChatAppReducer.PlayTogetherAsync.fetchingMostRecentlyPlayedGames then
|
||||
return
|
||||
end
|
||||
|
||||
store:dispatch(FetchingMostRecentlyPlayedGames())
|
||||
|
||||
local gameSorts = WebApi.GetGamesSorts(HOME_GAMES_SORTS)
|
||||
if not gameSorts then
|
||||
warn("Failed to get game sorts")
|
||||
store:dispatch(FailedToFetchedMostRecentlyPlayedGames())
|
||||
return
|
||||
end
|
||||
|
||||
for _, sort in pairs(gameSorts) do
|
||||
if sort.name == MOST_RECENTLY_PLAYED_GAMES then
|
||||
local games = WebApi.GetMostRecentlyPlayedGames(sort.token)
|
||||
if games then
|
||||
store:dispatch(FetchedMostRecentlyPlayedGames())
|
||||
store:dispatch(SetMostRecentlyPlayedGamesForUser(games))
|
||||
else
|
||||
warn("No most recently played games found")
|
||||
store:dispatch(FailedToFetchedMostRecentlyPlayedGames())
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
warn("No most recently played game sort")
|
||||
store:dispatch(FailedToFetchedMostRecentlyPlayedGames())
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function PlayTogetherActions.GetMostRecentlyPlayedPlayableGame()
|
||||
return function(store)
|
||||
local mostRecentlyPlayedGames = store:getState().ChatAppReducer.MostRecentlyPlayedGames.games
|
||||
if not mostRecentlyPlayedGames or #mostRecentlyPlayedGames == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
spawn(function()
|
||||
local mostRecentlyPlayedPlayableGamePlaceId = nil
|
||||
for _, game in pairs(mostRecentlyPlayedGames) do
|
||||
local placeId = tostring(game.placeId)
|
||||
local placeInfo = store:getState().ChatAppReducer.PlaceInfos[placeId]
|
||||
|
||||
if (placeInfo == nil) and (not store:getState().ChatAppReducer.PlaceInfosAsync[placeId]) then
|
||||
local placeIds = { placeId }
|
||||
store:dispatch(RequestMultiplePlaceInfos(placeIds))
|
||||
|
||||
local status, result = WebApi.GetMultiplePlaceInfos(placeIds)
|
||||
|
||||
if status ~= WebApi.Status.OK then
|
||||
warn("WebApi failure in GetMostRecentlyPlayedPlayableGame")
|
||||
store:dispatch(FailedToFetchMultiplePlaceInfos(placeIds))
|
||||
else
|
||||
local placeInfos = {}
|
||||
for _, placeInfoData in pairs(result) do
|
||||
table.insert(placeInfos, PlaceInfoModel.fromWeb(placeInfoData))
|
||||
end
|
||||
store:dispatch(ReceivedMultiplePlaceInfos(placeInfos))
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
if placeInfo and placeInfo.isPlayable then
|
||||
mostRecentlyPlayedPlayableGamePlaceId = placeId
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if mostRecentlyPlayedPlayableGamePlaceId then
|
||||
store:dispatch(SetMostRecentlyPlayedPlayableGameForUser(mostRecentlyPlayedPlayableGamePlaceId))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return PlayTogetherActions
|
||||
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
-----------------------------------------------------------------------------
|
||||
--- ---
|
||||
--- Under Migration to CorePackages ---
|
||||
--- ---
|
||||
--- Please put your changes in AppTempCommon. ---
|
||||
--- NOTE: You will have to rebuild for changes to kick in ---
|
||||
-----------------------------------------------------------------------------
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
return require(CorePackages.AppTempCommon.LuaChat.Actions.ReceivedConversation)
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,15 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, messages, shouldMarkConversationUnread, messageId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
messages = messages,
|
||||
shouldMarkConversationUnread = shouldMarkConversationUnread,
|
||||
exclusiveStartMessageId = messageId,
|
||||
}
|
||||
end
|
||||
)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
-----------------------------------------------------------------------------
|
||||
--- ---
|
||||
--- Under Migration to CorePackages ---
|
||||
--- ---
|
||||
--- Please put your changes in AppTempCommon. ---
|
||||
--- NOTE: You will have to rebuild for changes to kick in ---
|
||||
-----------------------------------------------------------------------------
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
return require(CorePackages.AppTempCommon.LuaChat.Actions.ReceivedMultiplePlaceInfos)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function(value)
|
||||
return {
|
||||
value = value,
|
||||
}
|
||||
end)
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(imageToken, thumbnail)
|
||||
return {
|
||||
imageToken = imageToken,
|
||||
thumbnail = thumbnail,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
-----------------------------------------------------------------------------
|
||||
--- ---
|
||||
--- Under Migration to CorePackages ---
|
||||
--- ---
|
||||
--- Please put your changes in AppTempCommon. ---
|
||||
--- NOTE: You will have to rebuild for changes to kick in ---
|
||||
-----------------------------------------------------------------------------
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
return require(CorePackages.AppTempCommon.LuaChat.Actions.ReceivedUserPresence)
|
||||
@@ -0,0 +1,24 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local SetUserTyping = require(LuaChat.Actions.SetUserTyping)
|
||||
|
||||
local typingCount = 0
|
||||
|
||||
return function(conversationId, userId)
|
||||
return function(store)
|
||||
spawn(function()
|
||||
typingCount = typingCount + 1
|
||||
local thisTypingCount = typingCount
|
||||
|
||||
store:dispatch(SetUserTyping(conversationId, userId, true))
|
||||
|
||||
wait(5)
|
||||
|
||||
if typingCount == thisTypingCount then
|
||||
store:dispatch(SetUserTyping(conversationId, userId, false))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(intent)
|
||||
return {
|
||||
intent = intent,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, title, isDefaultTitle, lastUpdated)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
title = title,
|
||||
isDefaultTitle = isDefaultTitle,
|
||||
lastUpdated = lastUpdated,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(placeIds)
|
||||
return {
|
||||
placeIds = placeIds,
|
||||
}
|
||||
end)
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(imageToken)
|
||||
return {
|
||||
imageToken = imageToken,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Action = require(Modules.Common.Action)
|
||||
|
||||
return Action(script.Name, function(userId)
|
||||
return {
|
||||
userId = userId
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, message)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
message = message
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, messageId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
messageId = messageId
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(isLoaded)
|
||||
return {
|
||||
value = isLoaded,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(isEnabled)
|
||||
return {
|
||||
value = isEnabled,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(connectionState)
|
||||
return {
|
||||
connectionState = connectionState;
|
||||
}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(convoId, conversationLoadingState)
|
||||
return {
|
||||
conversationId = convoId,
|
||||
value = conversationLoadingState
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(isFetchingConversations)
|
||||
return {
|
||||
value = isFetchingConversations,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(formFactor)
|
||||
return {
|
||||
formFactor = formFactor,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(count)
|
||||
return {
|
||||
count = count,
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(games)
|
||||
return {
|
||||
games = games,
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(placeId)
|
||||
return {
|
||||
placeId = placeId,
|
||||
}
|
||||
end)
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(universeId, rootPlaceId, conversationId)
|
||||
return {
|
||||
universeId = universeId,
|
||||
rootPlaceId = rootPlaceId,
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,13 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(intent, parameters, popToIntent)
|
||||
return {
|
||||
intent = intent,
|
||||
parameters = parameters or {},
|
||||
popToIntent = popToIntent,
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(unreadConversationCount)
|
||||
return {
|
||||
count = unreadConversationCount,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(userId, isFriend)
|
||||
return {
|
||||
isFriend = isFriend,
|
||||
userId = userId,
|
||||
}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, isLeaving)
|
||||
return {
|
||||
id = conversationId,
|
||||
isLeaving = isLeaving,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId, userId, isUserTyping)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
userId = userId,
|
||||
value = isUserTyping,
|
||||
}
|
||||
end)
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameSortName, placeIds)
|
||||
return {
|
||||
name = gameSortName,
|
||||
placeIds = placeIds or {},
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(games)
|
||||
return {
|
||||
games = games,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameSortName)
|
||||
return {
|
||||
gameSortName = gameSortName,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameSortName)
|
||||
return {
|
||||
gameSortName = gameSortName,
|
||||
}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameSortName)
|
||||
return {
|
||||
gameSortName = gameSortName,
|
||||
}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ShareGameToChatActions = LuaChat.Actions.ShareGameToChatFromChat
|
||||
|
||||
local AddGamesBySort = require(ShareGameToChatActions.AddGamesBySortShareGameToChatFromChat)
|
||||
local AddGamesInformation = require(ShareGameToChatActions.AddGamesInformationShareGameToChatFromChat)
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local ClearAllGamesInSorts = require(ShareGameToChatActions.ClearAllGamesInSortsShareGameToChatFromChat)
|
||||
local FailedToFetchGamesBySort = require(ShareGameToChatActions.FailedToFetchGamesBySortShareGameToChatFromChat)
|
||||
local FailedToShareGameToChat = require(ShareGameToChatActions.FailedToShareGameToChatFromChat)
|
||||
local FetchedGamesBySort = require(ShareGameToChatActions.FetchedGamesBySortShareGameToChatFromChat)
|
||||
local FetchingGamesBySort = require(ShareGameToChatActions.FetchingGamesBySortShareGameToChatFromChat)
|
||||
local PopRoute = require(LuaChat.Actions.PopRoute)
|
||||
local ResetShareGame = require(ShareGameToChatActions.ResetShareGameToChatFromChat)
|
||||
local ResetShareGameToChatAsync = require(ShareGameToChatActions.ResetShareGameToChatFromChatAsync)
|
||||
local SharedGameToChat = require(ShareGameToChatActions.SharedGameToChatFromChat)
|
||||
local SharingGameToChat = require(ShareGameToChatActions.SharingGameToChatFromChat)
|
||||
local ShowToast = require(LuaChat.Actions.ShowToast)
|
||||
local ToastModel = require(LuaChat.Models.ToastModel)
|
||||
local SetGameThumbnails = require(LuaApp.Actions.SetGameThumbnails)
|
||||
local UpdateGameSortsTokens = require(ShareGameToChatActions.UpdateGameSortsTokensShareGameToChatFromChat)
|
||||
local WebApi = require(LuaChat.WebApi)
|
||||
|
||||
local SHARED_GAMES_SORT = "GamesAllSorts"
|
||||
|
||||
local ShareGameToChatFromChatThunks = {}
|
||||
|
||||
function ShareGameToChatFromChatThunks.FetchGames(gameSortName, fetchedThumbnailSize)
|
||||
return function(store)
|
||||
spawn(function()
|
||||
if store:getState().ChatAppReducer.ShareGameToChatAsync.fetchingGamesBySort[gameSortName] then
|
||||
return
|
||||
end
|
||||
|
||||
store:dispatch(FetchingGamesBySort(gameSortName))
|
||||
|
||||
if not store:getState().ChatAppReducer.SharedGameSorts[gameSortName]
|
||||
or not store:getState().ChatAppReducer.SharedGameSorts[gameSortName].tokenExpiry
|
||||
or store:getState().ChatAppReducer.SharedGameSorts[gameSortName].tokenExpiry < tick() then
|
||||
local gameSorts = WebApi.GetGamesSorts(SHARED_GAMES_SORT)
|
||||
if not gameSorts then
|
||||
store:dispatch(FailedToFetchGamesBySort(gameSortName))
|
||||
warn("Failed to get game sorts")
|
||||
return
|
||||
end
|
||||
|
||||
store:dispatch(UpdateGameSortsTokens(gameSorts))
|
||||
end
|
||||
|
||||
local gamesList = nil
|
||||
if store:getState().ChatAppReducer.SharedGameSorts[gameSortName] and
|
||||
store:getState().ChatAppReducer.SharedGameSorts[gameSortName].token then
|
||||
gamesList = WebApi.GetGamesInSortByToken(store:getState().ChatAppReducer.SharedGameSorts[gameSortName].token)
|
||||
end
|
||||
|
||||
if gamesList then
|
||||
local placeIds = {}
|
||||
local newPlaceIds = {}
|
||||
local games = {}
|
||||
|
||||
for _, game in pairs(gamesList) do
|
||||
table.insert(placeIds, game.placeId)
|
||||
if not store:getState().ChatAppReducer.SharedGamesInfo[game.placeId] then
|
||||
games[game.placeId] = game
|
||||
end
|
||||
|
||||
if not store:getState().ChatAppReducer.SharedGamesInfo[game.placeId] or
|
||||
not store:getState().ChatAppReducer.SharedGamesInfo[game.placeId].url then
|
||||
table.insert(newPlaceIds, game.placeId)
|
||||
end
|
||||
end
|
||||
|
||||
if #newPlaceIds > 0 then
|
||||
local _, placesInfo = WebApi.GetMultiplePlaceInfos(newPlaceIds)
|
||||
local imageTokens = {}
|
||||
for _, placeInfo in pairs(placesInfo) do
|
||||
games[placeInfo.placeId].url = placeInfo.url
|
||||
games[placeInfo.placeId].isPlayable = placeInfo.isPlayable
|
||||
table.insert(imageTokens, placeInfo.imageToken)
|
||||
end
|
||||
|
||||
store:dispatch(AddGamesInformation(games))
|
||||
|
||||
local thumbnails = WebApi.GetPlacesThumbnails(imageTokens, fetchedThumbnailSize, fetchedThumbnailSize)
|
||||
store:dispatch(SetGameThumbnails(thumbnails))
|
||||
end
|
||||
|
||||
store:dispatch(FetchedGamesBySort(gameSortName))
|
||||
store:dispatch(AddGamesBySort(gameSortName, placeIds))
|
||||
else
|
||||
store:dispatch(AddGamesBySort(gameSortName, nil))
|
||||
store:dispatch(FailedToFetchGamesBySort(gameSortName))
|
||||
warn("No " .. gameSortName .. " games found")
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ShareGameToChatFromChatThunks.HasGameFetchRequestCompleted(sortName, shareGameToChatAsync)
|
||||
return shareGameToChatAsync.fetchedGamesBySort[sortName] or
|
||||
shareGameToChatAsync.failedToFetchGamesBySort[sortName]
|
||||
end
|
||||
|
||||
function ShareGameToChatFromChatThunks.Sharing(store)
|
||||
store:dispatch(SharingGameToChat())
|
||||
end
|
||||
|
||||
function ShareGameToChatFromChatThunks.Shared(store)
|
||||
store:dispatch(PopRoute())
|
||||
store:dispatch(SharedGameToChat())
|
||||
|
||||
store:dispatch(ResetShareGame())
|
||||
store:dispatch(ClearAllGamesInSorts())
|
||||
store:dispatch(ResetShareGameToChatAsync())
|
||||
end
|
||||
|
||||
function ShareGameToChatFromChatThunks.FailedToShare(store)
|
||||
local messageKey = "Feature.Chat.ShareGameToChat.FailedToShareTheGame"
|
||||
local toastModel = ToastModel.new(Constants.ToastIDs.GAME_NOT_SHAREABLE, messageKey)
|
||||
|
||||
store:dispatch(ShowToast(toastModel))
|
||||
store:dispatch(FailedToShareGameToChat())
|
||||
end
|
||||
|
||||
return ShareGameToChatFromChatThunks
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function()
|
||||
return {}
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(gameSorts)
|
||||
return {
|
||||
gameSorts = gameSorts,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(alert)
|
||||
return {
|
||||
alert = alert,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(toast)
|
||||
return {
|
||||
toast = toast,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(toast)
|
||||
return {
|
||||
toast = toast,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(isPaused)
|
||||
return {
|
||||
value = isPaused,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
@@ -0,0 +1,11 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Action = require(Common.Action)
|
||||
|
||||
return Action(script.Name, function(conversationId)
|
||||
return {
|
||||
conversationId = conversationId,
|
||||
}
|
||||
end)
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
local PlayerService = game:GetService("Players")
|
||||
|
||||
return function(eventStreamImpl, eventContext, conversationId, placeId)
|
||||
assert(type(eventContext) == "string", "Expected eventContext to be a string")
|
||||
assert(type(conversationId) == "string", "Expected conversationId to be a string")
|
||||
assert(type(placeId) == "string", "Expected placeId to be a string")
|
||||
|
||||
local eventName = "loadGameLinkCardInChat"
|
||||
|
||||
local player = PlayerService.LocalPlayer
|
||||
local userId = "UNKNOWN"
|
||||
if player then
|
||||
userId = tostring(player.UserId)
|
||||
end
|
||||
|
||||
eventStreamImpl:setRBXEventStream(eventContext, eventName, {
|
||||
uid = userId,
|
||||
cid = conversationId,
|
||||
pid = placeId,
|
||||
})
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
local Players = game:GetService("Players")
|
||||
|
||||
return function(eventStreamImpl, eventContext, conversationId)
|
||||
assert(type(eventContext) == "string", "Expected eventContext to be a string")
|
||||
assert(type(conversationId) == "string", "Expected conversationId to be a string")
|
||||
|
||||
local eventName = "sendIcebreaker"
|
||||
local player = Players.LocalPlayer
|
||||
local userId = tostring(player.UserId)
|
||||
|
||||
eventStreamImpl:setRBXEventStream(eventContext, eventName, {
|
||||
uid = userId,
|
||||
cid = conversationId,
|
||||
})
|
||||
end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
local PlayerService = game:GetService("Players")
|
||||
|
||||
return function(eventStreamImpl, eventContext, conversationId, placeId)
|
||||
assert(type(eventContext) == "string", "Expected eventContext to be a string")
|
||||
|
||||
local eventName = "shareGameToChatFromChat"
|
||||
|
||||
local player = PlayerService.LocalPlayer
|
||||
local userId = "UNKNOWN"
|
||||
if player then
|
||||
userId = tostring(player.UserId)
|
||||
end
|
||||
|
||||
eventStreamImpl:setRBXEventStream(eventContext, eventName, {
|
||||
uid = userId,
|
||||
cid = conversationId,
|
||||
pid = placeId,
|
||||
})
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local ActiveConversationId = require(LuaChat.Reducers.ActiveConversationId)
|
||||
local ShareGameToChatAsync = require(LuaChat.Reducers.ShareGameToChatAsync)
|
||||
local SharedGameSorts = require(LuaChat.Reducers.SharedGameSorts)
|
||||
local SharedGamesInfo = require(LuaChat.Reducers.SharedGamesInfo)
|
||||
|
||||
local AppLoaded = require(LuaChat.Reducers.AppLoaded)
|
||||
local AppState = require(LuaChat.Reducers.AppState)
|
||||
local Conversations = require(LuaChat.Reducers.Conversations)
|
||||
local ConversationsAsync = require(LuaChat.Reducers.ConversationsAsync)
|
||||
local Location = require(LuaChat.Reducers.Location)
|
||||
local MostRecentlyPlayedGames = require(LuaChat.Reducers.MostRecentlyPlayedGames)
|
||||
local PlaceInfos = require(Modules.LuaChat.Reducers.PlaceInfos)
|
||||
local PlaceInfosAsync = require(LuaChat.Reducers.PlaceInfosAsync)
|
||||
local PlaceThumbnails = require(Modules.LuaChat.Reducers.PlaceThumbnails)
|
||||
local PlaceThumbnailsAsync = require(LuaChat.Reducers.PlaceThumbnailsAsync)
|
||||
local PlayTogetherAsync = require(LuaChat.Reducers.PlayTogetherAsync)
|
||||
local Toast = require(LuaChat.Reducers.Toast)
|
||||
local ToggleChatPaused = require(LuaChat.Reducers.ToggleChatPaused)
|
||||
local UnreadConversationCount = require(LuaChat.Reducers.UnreadConversationCount)
|
||||
|
||||
local FFlagLuaChatCheckWasUsedRecently = settings():GetFFlag("LuaChatCheckWasUsedRecently")
|
||||
|
||||
local ChatEnabled
|
||||
local ChatSettings
|
||||
if FFlagLuaChatCheckWasUsedRecently then
|
||||
ChatSettings = require(LuaChat.Reducers.ChatSettings)
|
||||
else
|
||||
ChatEnabled = require(LuaChat.Reducers.ChatEnabled)
|
||||
end
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
local newState = {
|
||||
-- Unique to Chat
|
||||
ActiveConversationId = ActiveConversationId(state.ActiveConversationId, action),
|
||||
AppState = AppState(state.AppState, action),
|
||||
Location = Location(state.Location, action),
|
||||
AppLoaded = AppLoaded(state.AppLoaded, action),
|
||||
ToggleChatPaused = ToggleChatPaused(state.ToggleChatPaused, action),
|
||||
|
||||
-- TODO: update and move the following to the LuaApp state when WebApi is refactored:
|
||||
-- See: https://jira.roblox.com/browse/SOC-1737
|
||||
PlaceInfos = PlaceInfos(state.PlaceInfos, action),
|
||||
PlaceInfosAsync = PlaceInfosAsync(state.PlaceInfosAsync, action),
|
||||
PlaceThumbnails = PlaceThumbnails(state.PlaceThumbnails, action),
|
||||
PlaceThumbnailsAsync = PlaceThumbnailsAsync(state.PlaceThumbnailsAsync, action),
|
||||
|
||||
-- May be able to be shared with other pages
|
||||
Toast = Toast(state.Toast, action),
|
||||
Conversations = Conversations(state.Conversations, action),
|
||||
ConversationsAsync = ConversationsAsync(state.ConversationsAsync, action),
|
||||
UnreadConversationCount = UnreadConversationCount(state.UnreadConversationCount, action),
|
||||
MostRecentlyPlayedGames = MostRecentlyPlayedGames(state.MostRecentlyPlayedGames, action),
|
||||
PlayTogetherAsync = PlayTogetherAsync(state.PlayTogetherAsync, action),
|
||||
-- Share game to chat from chat
|
||||
ShareGameToChatAsync = ShareGameToChatAsync(state.ShareGameToChatAsync, action),
|
||||
SharedGameSorts = SharedGameSorts(state.SharedGameSorts, action),
|
||||
SharedGamesInfo = SharedGamesInfo(state.SharedGamesInfo, action),
|
||||
}
|
||||
|
||||
if FFlagLuaChatCheckWasUsedRecently then
|
||||
newState.ChatSettings = ChatSettings(state.ChatSettings, action)
|
||||
else
|
||||
newState.ChatEnabled = ChatEnabled(state.ChatEnabled, action)
|
||||
end
|
||||
|
||||
return newState
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local LocalizationService = game:GetService("LocalizationService")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local Common = Modules.Common
|
||||
|
||||
local request = require(Modules.LuaApp.Http.request)
|
||||
local ScreenManager = require(Modules.LuaChat.ScreenManager)
|
||||
local AppReducer = require(Modules.LuaApp.AppReducer)
|
||||
local Localization = require(Modules.LuaApp.Localization)
|
||||
local Analytics = require(Common.Analytics)
|
||||
local Rodux = require(Common.Rodux)
|
||||
|
||||
local AppState = {}
|
||||
|
||||
local function appStateConstructor(chatGui, store, analyticsImpl)
|
||||
local state = {}
|
||||
|
||||
state.store = store
|
||||
state.localization = Localization.new(LocalizationService.RobloxLocaleId)
|
||||
state.analytics = analyticsImpl
|
||||
state.request = request
|
||||
state.screenManager = ScreenManager.new(chatGui, state)
|
||||
return state
|
||||
end
|
||||
|
||||
function AppState.new(chatGui, store)
|
||||
local analyticsImpl = Analytics.new()
|
||||
return appStateConstructor(chatGui, store, analyticsImpl)
|
||||
end
|
||||
|
||||
function AppState.mock(chatGui, store, analyticsImpl)
|
||||
analyticsImpl = analyticsImpl or Analytics.mock()
|
||||
chatGui = chatGui or CoreGui
|
||||
store = store or Rodux.Store.new(AppReducer)
|
||||
|
||||
return appStateConstructor(chatGui, store, analyticsImpl)
|
||||
end
|
||||
|
||||
function AppState:Destruct()
|
||||
self.store:destruct()
|
||||
end
|
||||
|
||||
return AppState
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
|
||||
local Modules = script.Parent.Parent
|
||||
local Create = require(Modules.Create)
|
||||
local Constants = require(Modules.Constants)
|
||||
local Text = require(Modules.Text)
|
||||
|
||||
local ListEntry = require(Modules.Components.ListEntry)
|
||||
|
||||
local ICON_CELL_WIDTH = 60
|
||||
local HEIGHT = 48
|
||||
|
||||
local LABEL_SPACING = 12
|
||||
|
||||
local ActionEntry = {}
|
||||
|
||||
function ActionEntry.new(appState, icon, localizationKey, size)
|
||||
local self = {}
|
||||
|
||||
size = size or 24
|
||||
|
||||
setmetatable(self, {__index = ActionEntry})
|
||||
|
||||
local text = appState.localization:Format(localizationKey)
|
||||
|
||||
local listEntry = ListEntry.new(appState, HEIGHT)
|
||||
self.rbx = listEntry.rbx
|
||||
|
||||
local iconFrame = Create.new"Frame" {
|
||||
BackgroundTransparency = 1,
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(0, ICON_CELL_WIDTH, 1, 0),
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Create.new"ImageLabel" {
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(0, size, 0, size),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Image = icon,
|
||||
BorderSizePixel = 0,
|
||||
},
|
||||
}
|
||||
iconFrame.Parent = self.rbx
|
||||
|
||||
local label = Create.new"TextLabel" {
|
||||
Name = "Label",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -ICON_CELL_WIDTH, 1, 0),
|
||||
Position = UDim2.new(0, ICON_CELL_WIDTH, 0, 0),
|
||||
TextSize = Constants.Font.FONT_SIZE_18,
|
||||
TextColor3 = Constants.Color.GRAY1,
|
||||
Font = Enum.Font.SourceSans,
|
||||
Text = text,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
}
|
||||
label.Parent = self.rbx
|
||||
|
||||
local labelEffectiveWidth = Text.GetTextWidth(text, Enum.Font.SourceSans, Constants.Font.FONT_SIZE_18) + LABEL_SPACING
|
||||
local value = Create.new"TextLabel" {
|
||||
Name = "Value",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -ICON_CELL_WIDTH-12-labelEffectiveWidth, 1, 0),
|
||||
Position = UDim2.new(0, ICON_CELL_WIDTH+labelEffectiveWidth, 0, 0),
|
||||
TextSize = Constants.Font.FONT_SIZE_18,
|
||||
TextColor3 = Constants.Color.GRAY2,
|
||||
Font = Enum.Font.SourceSans,
|
||||
Text = "",
|
||||
TextXAlignment = Enum.TextXAlignment.Right,
|
||||
ClipsDescendants = true,
|
||||
}
|
||||
value.Parent = self.rbx
|
||||
|
||||
local divider = Create.new"Frame" {
|
||||
Name = "Divider",
|
||||
BackgroundColor3 = Constants.Color.GRAY4,
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 0, 1),
|
||||
Position = UDim2.new(0, 0, 1, -1),
|
||||
}
|
||||
divider.Parent = self.rbx
|
||||
self.divider = divider
|
||||
|
||||
self.tapped = Instance.new("BindableEvent")
|
||||
self.tapped.Parent = self.rbx
|
||||
|
||||
listEntry.tapped:connect(function()
|
||||
self.tapped:fire()
|
||||
end)
|
||||
|
||||
value:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
||||
self:AdjustLayout()
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ActionEntry:SetDividerOffset(dividerOffset)
|
||||
self.divider.Size = UDim2.new(1, -dividerOffset, 0, 1)
|
||||
self.divider.Position = UDim2.new(0, dividerOffset, 1, -1)
|
||||
end
|
||||
|
||||
function ActionEntry:AdjustLayout()
|
||||
local text = self.rbx.Value.Text
|
||||
local valueWidth = Text.GetTextWidth(text, Enum.Font.SourceSans, Constants.Font.FONT_SIZE_18)
|
||||
if valueWidth > self.rbx.Value.AbsoluteSize.X then
|
||||
self.rbx.Value.TextXAlignment = Enum.TextXAlignment.Right
|
||||
else
|
||||
self.rbx.Value.TextXAlignment = Enum.TextXAlignment.Left
|
||||
end
|
||||
end
|
||||
|
||||
function ActionEntry:Update(state)
|
||||
self.rbx.Value.Text = state
|
||||
self:AdjustLayout()
|
||||
end
|
||||
|
||||
return ActionEntry
|
||||
@@ -0,0 +1,589 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Players = game:GetService("Players")
|
||||
local GuiService = game:GetService("GuiService")
|
||||
local TweenService = game:GetService("TweenService")
|
||||
local HttpService = game:GetService("HttpService")
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local Create = require(LuaChat.Create)
|
||||
local FlagSettings = require(LuaChat.FlagSettings)
|
||||
local GameParams = require(LuaChat.Models.GameParams)
|
||||
local getInputEvent = require(LuaChat.Utils.getInputEvent)
|
||||
local GetMultiplePlaceInfos = require(LuaChat.Actions.GetMultiplePlaceInfos)
|
||||
local GetPlaceThumbnail = require(LuaChat.Actions.GetPlaceThumbnail)
|
||||
local LoadingIndicator = require(LuaChat.Components.LoadingIndicator)
|
||||
local NotificationType = require(LuaApp.Enum.NotificationType)
|
||||
local PlayTogetherActions = require(LuaChat.Actions.PlayTogetherActions)
|
||||
local Text = require(LuaChat.Text)
|
||||
local FormFactor = require(LuaApp.Enum.FormFactor)
|
||||
|
||||
local FFlagLuaChatToSplitRbxConnections = settings():GetFFlag("LuaChatToSplitRbxConnections")
|
||||
local UseCppTextTruncation = FlagSettings.UseCppTextTruncation()
|
||||
local UrlSupportNewGamesAPI = settings():GetFFlag("UrlSupportNewGamesAPI")
|
||||
local LuaChatAssetCardsSelfTerminateConnection = settings():GetFFlag("LuaChatAssetCardsSelfTerminateConnection")
|
||||
local LuaChatFixAssetCardResizeTruncation = true or settings():GetFFlag("LuaChatFixAssetCardResizeTruncation")
|
||||
|
||||
local BUBBLE_PADDING = 10
|
||||
local DEFAULT_THUMBNAIL = "rbxasset://textures/ui/LuaChat/icons/share-game-thumbnail.png"
|
||||
local EXTERIOR_PADDING = 3
|
||||
local GAME_CARD_BUTTON_CLICKED_EVENT = "clickBtnFromLinkCardInChat"
|
||||
local GAME_MASK_IMAGE = "rbxasset://textures/ui/LuaChat/9-slice/gr-mask-game-icon.png"
|
||||
local GAME_PLAY_INTENT = "gamePlayIntent"
|
||||
local GAME_PLAY_EVENT_CONTEXT = "PlayGameFromLinkCard"
|
||||
local ICON_SIZE = 64
|
||||
local INTERIOR_PADDING = 12
|
||||
local LINK_CARD_CLICKED_EVENT = "clickLinkCardInChat"
|
||||
local PIN_ICON = "rbxasset://textures/ui/LuaChat/icons/ic-pin.png"
|
||||
local PIN_ICON_HORIZONTAL_PADDING = 10
|
||||
local PIN_ICON_SIZE = 20
|
||||
local PIN_ICON_VERTICAL_PADDING = 8
|
||||
local PIN_PRESSED_ICON = "rbxasset://textures/ui/LuaChat/icons/ic-pinpressed.png"
|
||||
local PLACE_INFO_THUMBNAIL_SIZE = 50
|
||||
local TOUCH_CONTEXT = "touch"
|
||||
|
||||
local ASSET_CARD_HORIZONTAL_MARGIN_PHONE = 108
|
||||
local ASSET_CARD_HORIZONTAL_MARGIN_TABLET = 224
|
||||
|
||||
local function isOutgoingMessage(message)
|
||||
local localUserId = tostring(Players.LocalPlayer.UserId)
|
||||
return message.senderTargetId == localUserId
|
||||
end
|
||||
|
||||
local FFlagLuaChatInfiniteRelayoutRecursionFix = settings():GetFFlag("LuaChatInfiniteRelayoutRecursionFix")
|
||||
local AssetCard = {}
|
||||
AssetCard.__index = AssetCard
|
||||
|
||||
function AssetCard.new(appState, message, assetId)
|
||||
local self = {}
|
||||
setmetatable(self, AssetCard)
|
||||
|
||||
local state = appState.store:getState()
|
||||
local user = state.Users[message.senderTargetId]
|
||||
local username = user and user.name or "unknown user"
|
||||
|
||||
self._analytics = appState.analytics
|
||||
self.appState = appState
|
||||
self.paddingObject = nil
|
||||
self.message = message
|
||||
self.bubbleType = "AssetCard"
|
||||
self.connections = {}
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
self.rbx_connections = {}
|
||||
end
|
||||
self.cardBodyClick = nil
|
||||
self.assetId = assetId
|
||||
self.conversationId = message.conversationId
|
||||
self.universeId = nil
|
||||
self.pinButtonClick = nil
|
||||
|
||||
self.luaChatPlayTogetherEnabled = FlagSettings.IsLuaChatPlayTogetherEnabled(
|
||||
self.appState.store:getState().FormFactor)
|
||||
|
||||
self.tail = Create.new "ImageLabel" {
|
||||
Name = "Tail",
|
||||
Size = UDim2.new(0, 6, 0, 6),
|
||||
BackgroundTransparency = 1,
|
||||
}
|
||||
|
||||
self.actionLabel = Create.new "TextLabel" {
|
||||
Name = "ActionLabel",
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Size = UDim2.new(0.8, 0, 0.8, 0),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
TextSize = Constants.Font.FONT_SIZE_20,
|
||||
TextColor3 = Constants.Color.GRAY1,
|
||||
Font = Enum.Font.SourceSans,
|
||||
Text = self.appState.localization:Format("Feature.Chat.Action.ViewAssetDetails"),
|
||||
}
|
||||
|
||||
self.actionButton = Create.new "ImageButton" {
|
||||
Name = "Action",
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(0.5, 1),
|
||||
Position = UDim2.new(0.5, 0, 1, 0),
|
||||
Size = UDim2.new(1, 0, 0, 32),
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = Rect.new(3,3,4,4),
|
||||
Image = "rbxasset://textures/ui/LuaChat/9-slice/input-default.png",
|
||||
self.actionLabel,
|
||||
}
|
||||
|
||||
local textLabelWidth
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
textLabelWidth = -(PIN_ICON_SIZE + (2 * INTERIOR_PADDING) + BUBBLE_PADDING)
|
||||
else
|
||||
textLabelWidth = -(INTERIOR_PADDING + BUBBLE_PADDING)
|
||||
end
|
||||
self.Title = Create.new "TextLabel" {
|
||||
Name = "Title",
|
||||
TextTruncate = UseCppTextTruncation and Enum.TextTruncate.AtEnd or nil,
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
AnchorPoint = Vector2.new(0, 0),
|
||||
TextSize = Constants.Font.FONT_SIZE_20,
|
||||
Size = UDim2.new(1, textLabelWidth, 0, 20),
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
|
||||
TextColor3 = Constants.Color.GRAY1,
|
||||
Font = Enum.Font.SourceSans,
|
||||
TextXAlignment = Enum.TextXAlignment.Left
|
||||
}
|
||||
|
||||
self.Icon = Create.new "ImageLabel" {
|
||||
Name = "Icon",
|
||||
BackgroundTransparency = 1,
|
||||
Position = UDim2.new(0, 0, 0, self.Title.TextSize + INTERIOR_PADDING),
|
||||
Size = UDim2.new(0, ICON_SIZE, 0, ICON_SIZE),
|
||||
|
||||
Create.new "ImageLabel" {
|
||||
Name = "Mask",
|
||||
BackgroundTransparency = 1,
|
||||
BorderSizePixel = 0,
|
||||
Image = GAME_MASK_IMAGE,
|
||||
ImageColor3 = Constants.Color.WHITE,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
SliceCenter = Rect.new(3,3,4,4),
|
||||
}
|
||||
}
|
||||
|
||||
self.Details = Create.new "TextLabel" {
|
||||
Name = "Details",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, - INTERIOR_PADDING -ICON_SIZE, 0, ICON_SIZE),
|
||||
Position = self.Icon.Position + UDim2.new(0 , INTERIOR_PADDING + ICON_SIZE, 0, 0),
|
||||
|
||||
TextColor3 = Constants.Color.GRAY2,
|
||||
Font = Enum.Font.SourceSans,
|
||||
TextSize = Constants.Font.FONT_SIZE_14,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
TextWrapped = true,
|
||||
}
|
||||
|
||||
self.fadeScreen = Create.new "Frame" {
|
||||
Name = "FadeScreen",
|
||||
BackgroundTransparency = 0,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundColor3 = Color3.new(1, 1, 1),
|
||||
BorderSizePixel = 0,
|
||||
}
|
||||
|
||||
|
||||
self.Content = Create.new "ImageButton" {
|
||||
Name = "Content",
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -BUBBLE_PADDING * 2, 1, -BUBBLE_PADDING * 2),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
Visible = false,
|
||||
|
||||
self.actionButton,
|
||||
self.Title,
|
||||
self.Icon,
|
||||
self.Details,
|
||||
self.fadeScreen,
|
||||
}
|
||||
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
self.PinIcon = Create.new "ImageLabel" {
|
||||
Name = "PinIcon",
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
Size = UDim2.new(0, PIN_ICON_SIZE, 0, PIN_ICON_SIZE),
|
||||
Image = PIN_ICON,
|
||||
}
|
||||
|
||||
self.PinButton = Create.new "TextButton" {
|
||||
Name = "PinButton",
|
||||
Text = "",
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
Position = UDim2.new(1, BUBBLE_PADDING, 0, -BUBBLE_PADDING),
|
||||
Size = UDim2.new(0, PIN_ICON_SIZE + 2 * PIN_ICON_HORIZONTAL_PADDING,
|
||||
0, PIN_ICON_SIZE + 2 * PIN_ICON_VERTICAL_PADDING),
|
||||
|
||||
self.PinIcon
|
||||
}
|
||||
self.PinButton.Parent = self.Content
|
||||
end
|
||||
|
||||
self.bubble = Create.new "ImageLabel" {
|
||||
Name = "Bubble",
|
||||
BackgroundTransparency = 1,
|
||||
AnchorPoint = Vector2.new(1, 0),
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
Size = UDim2.new(0, 267, 1, 0),
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = Rect.new(10, 10, 11, 11),
|
||||
LayoutOrder = 2,
|
||||
|
||||
self.Content,
|
||||
self.tail,
|
||||
}
|
||||
|
||||
self.usernameLabel = Create.new "TextLabel" {
|
||||
Name = "UsernameLabel",
|
||||
Font = Enum.Font.SourceSans,
|
||||
TextSize = Constants.Font.FONT_SIZE_12,
|
||||
Visible = false,
|
||||
BackgroundTransparency = 1,
|
||||
Size = UDim2.new(1, -56, 0, 16),
|
||||
Position = UDim2.new(0, 56, 0, 0),
|
||||
TextColor3 = Constants.Color.GRAY2,
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
Text = username,
|
||||
}
|
||||
|
||||
self.bubbleContainer = Create.new "Frame" {
|
||||
Name = "BubbleContainer",
|
||||
BackgroundTransparency = 1,
|
||||
LayoutOrder = 2,
|
||||
Size = UDim2.new(1, 0, 0, 0),
|
||||
|
||||
self.bubble,
|
||||
self.usernameLabel,
|
||||
}
|
||||
|
||||
self.layout = Create.new "UIListLayout" {
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
}
|
||||
|
||||
self.rbx = Create.new "Frame" {
|
||||
Name = "AssetCard",
|
||||
BackgroundTransparency = 1,
|
||||
|
||||
self.layout,
|
||||
self.bubbleContainer,
|
||||
}
|
||||
|
||||
-- 'isOutgoing' means "is sent by the local user". This function separates the tail position & color
|
||||
if isOutgoingMessage(message) then
|
||||
self.tail.AnchorPoint = Vector2.new(0, 0)
|
||||
self.tail.Position = UDim2.new(1, 0, 0, 0)
|
||||
self.tail.ImageColor3 = Color3.new(1, 1, 1)
|
||||
|
||||
self.bubble.ImageColor3 = Color3.new(1, 1, 1)
|
||||
self.bubble.AnchorPoint = Vector2.new(1, 0)
|
||||
self.bubble.Position = UDim2.new(1, -10, 0, 0)
|
||||
|
||||
self.rbx.UIListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right
|
||||
else
|
||||
self.tail.AnchorPoint = Vector2.new(1, 0)
|
||||
self.tail.Position = UDim2.new(0, 0, 0, 0)
|
||||
self.tail.ImageColor3 = Color3.new(1, 1, 1)
|
||||
|
||||
self.bubble.ImageColor3 = Color3.new(1, 1, 1)
|
||||
self.bubble.AnchorPoint = Vector2.new(0, 0)
|
||||
self.bubble.Position = UDim2.new(0, 54, 0, 0)
|
||||
|
||||
self.rbx.UIListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Left
|
||||
end
|
||||
|
||||
self.appStateConnection = self.appState.store.changed:connect(function(state)
|
||||
self:Update(state)
|
||||
end)
|
||||
table.insert(self.connections, self.appStateConnection)
|
||||
|
||||
if not FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
local connection = self.rbx:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
||||
self:Resize()
|
||||
end)
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
table.insert(self.rbx_connections, connection)
|
||||
else
|
||||
table.insert(self.connections, connection)
|
||||
end
|
||||
end
|
||||
|
||||
self:Update(state)
|
||||
|
||||
if FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
self:Resize()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function AssetCard:_truncateText()
|
||||
if LuaChatFixAssetCardResizeTruncation then
|
||||
if not UseCppTextTruncation then
|
||||
if self.placeInfo ~= nil then
|
||||
self.Title.Text = self.placeInfo.name
|
||||
end
|
||||
Text.TruncateTextLabel(self.Title, "...")
|
||||
end
|
||||
else
|
||||
if not UseCppTextTruncation then
|
||||
Text.TruncateTextLabel(self.Title, "...")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:Resize()
|
||||
local formFactor = self.appState.store:getState().FormFactor
|
||||
|
||||
local bubbleSizeOffsetY
|
||||
if FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
bubbleSizeOffsetY = formFactor == FormFactor.PHONE and ASSET_CARD_HORIZONTAL_MARGIN_PHONE
|
||||
or ASSET_CARD_HORIZONTAL_MARGIN_TABLET
|
||||
else
|
||||
bubbleSizeOffsetY = Constants:GetFormFactorSpecific(formFactor).ASSET_CARD_HORIZONTAL_MARGIN
|
||||
end
|
||||
|
||||
local bubbleHeight = 92 + ICON_SIZE
|
||||
self.bubble.Size = UDim2.new(1, -bubbleSizeOffsetY, 0, bubbleHeight)
|
||||
|
||||
local containerHeight = bubbleHeight
|
||||
if self.usernameLabel.Visible then
|
||||
containerHeight = containerHeight + self.usernameLabel.AbsoluteSize.Y
|
||||
end
|
||||
|
||||
self.bubbleContainer.Size = UDim2.new(1, 0, 0, containerHeight)
|
||||
|
||||
local height = 0
|
||||
for _, child in ipairs(self.rbx:GetChildren()) do
|
||||
if child:IsA("GuiObject") then
|
||||
height = height + child.AbsoluteSize.Y
|
||||
end
|
||||
end
|
||||
height = height + EXTERIOR_PADDING * 2
|
||||
|
||||
if FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
-- FFlagLuaChatInfiniteRelayoutRecursionFix aims to seperate resize
|
||||
-- and truncation logic so they may be called independantly
|
||||
self.rbx.Size = UDim2.new(1, 0, 0, height)
|
||||
self:_truncateText()
|
||||
else
|
||||
if LuaChatFixAssetCardResizeTruncation then
|
||||
-- resize the frame before we truncate
|
||||
self.rbx.Size = UDim2.new(1, 0, 0, height)
|
||||
|
||||
if not UseCppTextTruncation then
|
||||
-- set the title text first in case the text is already truncated
|
||||
-- from a Resize() call when the frame was a smaller width
|
||||
if self.placeInfo ~= nil then
|
||||
self.Title.Text = self.placeInfo.name
|
||||
end
|
||||
Text.TruncateTextLabel(self.Title, "...")
|
||||
end
|
||||
else
|
||||
if not UseCppTextTruncation then
|
||||
Text.TruncateTextLabel(self.Title, "...")
|
||||
end
|
||||
self.rbx.Size = UDim2.new(1, 0, 0, height)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:onPinPressed()
|
||||
self.PinIcon.Image = PIN_PRESSED_ICON
|
||||
self.userInputServiceCon = UserInputService.InputEnded:Connect(function()
|
||||
self:onPinRelease()
|
||||
end)
|
||||
end
|
||||
|
||||
function AssetCard:onPinRelease()
|
||||
if self.userInputServiceCon then
|
||||
self.userInputServiceCon:Disconnect()
|
||||
self.userInputServiceCon = nil
|
||||
end
|
||||
self.PinIcon.Image = PIN_ICON
|
||||
end
|
||||
|
||||
function AssetCard:Update(newState)
|
||||
local placeInfo = newState.ChatAppReducer.PlaceInfos[self.assetId]
|
||||
if placeInfo == nil then
|
||||
self:ShowLoadingIndicator(true)
|
||||
self.appState.store:dispatch(GetMultiplePlaceInfos({self.assetId}))
|
||||
else
|
||||
self.placeInfo = placeInfo
|
||||
self.Title.Text = placeInfo.name
|
||||
if FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
self:_truncateText()
|
||||
end
|
||||
|
||||
local description = placeInfo.description:gsub("%s", " ")
|
||||
if description:gsub("^%s+$", "") == "" then
|
||||
description = self.appState.localization:Format("Feature.Chat.Label.NoDescriptionYet")
|
||||
end
|
||||
self.Details.Text = description
|
||||
self.universeId = placeInfo.universeId
|
||||
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
if self.pinButtonClick then self.pinButtonClick:Disconnect() end
|
||||
if self.pinButtonInputBegin then self.pinButtonInputBegin:Disconnect() end
|
||||
|
||||
self.pinButtonClick = self.PinButton.Activated:Connect(function()
|
||||
self.appState.store:dispatch(PlayTogetherActions.PinGame(self.conversationId, self.universeId))
|
||||
end)
|
||||
self.pinButtonInputBegin = self.PinButton.InputBegan:Connect(function()
|
||||
self:onPinPressed()
|
||||
end)
|
||||
end
|
||||
|
||||
if UrlSupportNewGamesAPI then
|
||||
local thumbnail = newState.ChatAppReducer.PlaceThumbnails[placeInfo.imageToken]
|
||||
if thumbnail == nil then
|
||||
self.appState.store:dispatch(GetPlaceThumbnail(
|
||||
placeInfo.imageToken, PLACE_INFO_THUMBNAIL_SIZE, PLACE_INFO_THUMBNAIL_SIZE
|
||||
))
|
||||
else
|
||||
if thumbnail.image == '' then
|
||||
self.thumbnail = DEFAULT_THUMBNAIL
|
||||
else
|
||||
self.thumbnail = thumbnail.image
|
||||
end
|
||||
self:FillThumbnail()
|
||||
self:Show()
|
||||
end
|
||||
else
|
||||
self.thumbnail = DEFAULT_THUMBNAIL
|
||||
self:Show()
|
||||
end
|
||||
end
|
||||
if self.cardBodyClick then self.cardBodyClick:Disconnect() end
|
||||
if self.detailsButtonClick then self.detailsButtonClick:Disconnect() end
|
||||
|
||||
self:StyleViewDetailsAsPlay(self.placeInfo ~= nil and self.placeInfo.isPlayable)
|
||||
|
||||
self.cardBodyClick = getInputEvent(self.Content):Connect(function()
|
||||
self:ReportAnEvent(LINK_CARD_CLICKED_EVENT, TOUCH_CONTEXT)
|
||||
if self.placeInfo then
|
||||
GuiService:BroadcastNotification(self.assetId,
|
||||
NotificationType.VIEW_GAME_DETAILS)
|
||||
end
|
||||
end)
|
||||
|
||||
self.detailsButtonClick = getInputEvent(self.actionButton):Connect(function()
|
||||
self:ReportAnEvent(GAME_CARD_BUTTON_CLICKED_EVENT, TOUCH_CONTEXT)
|
||||
if self.placeInfo then
|
||||
if self.placeInfo.isPlayable then
|
||||
self:ReportAnEvent(GAME_PLAY_INTENT, GAME_PLAY_EVENT_CONTEXT)
|
||||
local gameParams = GameParams.fromPlaceId(self.assetId)
|
||||
local payload = HttpService:JSONEncode(gameParams)
|
||||
|
||||
GuiService:BroadcastNotification(payload,
|
||||
NotificationType.LAUNCH_GAME)
|
||||
else
|
||||
GuiService:BroadcastNotification(self.assetId,
|
||||
NotificationType.VIEW_GAME_DETAILS)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not FFlagLuaChatInfiniteRelayoutRecursionFix then
|
||||
self:Resize()
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:ReportAnEvent(eventName, eventContext)
|
||||
local additionalArgs
|
||||
if eventName == GAME_PLAY_INTENT then
|
||||
additionalArgs = {
|
||||
conversationId = self.conversationId,
|
||||
rootPlaceId = self.assetId
|
||||
}
|
||||
else
|
||||
additionalArgs = {
|
||||
conversationId = self.conversationId,
|
||||
placeId = self.assetId
|
||||
}
|
||||
end
|
||||
|
||||
self._analytics.EventStream:setRBXEventStream(eventContext, eventName, additionalArgs)
|
||||
end
|
||||
|
||||
function AssetCard:StyleViewDetailsAsPlay(isShowingAsPlay)
|
||||
if isShowingAsPlay then
|
||||
self.actionButton.ImageColor3 = Constants.Color.GREEN_PRIMARY
|
||||
self.actionLabel.Text = self.appState.localization:Format("Common.VisitGame.Label.Play")
|
||||
self.actionLabel.TextColor3 = Constants.Color.WHITE
|
||||
else
|
||||
self.actionButton.ImageColor3 = Constants.Color.WHITE
|
||||
self.actionLabel.Text = self.appState.localization:Format("Feature.Chat.Action.ViewAssetDetails")
|
||||
self.actionLabel.TextColor3 = Constants.Color.GRAY1
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:Show()
|
||||
self.Content.Visible = true
|
||||
spawn(function()
|
||||
while (not self.Icon.IsLoaded) do wait() end
|
||||
|
||||
self:ShowLoadingIndicator(false)
|
||||
local fadeInTween = TweenService:Create(
|
||||
self.fadeScreen,
|
||||
TweenInfo.new(0.4),
|
||||
{BackgroundTransparency = 1}
|
||||
)
|
||||
fadeInTween:Play()
|
||||
end)
|
||||
|
||||
if LuaChatAssetCardsSelfTerminateConnection then
|
||||
if self.appStateConnection then
|
||||
self.appStateConnection:disconnect()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:FillThumbnail()
|
||||
self.Icon.Image = self.thumbnail or ""
|
||||
end
|
||||
|
||||
function AssetCard:ShowLoadingIndicator(isVisible)
|
||||
if isVisible then
|
||||
if not self.loadingIndicator then
|
||||
local loadingIndicator = LoadingIndicator.new(self.appState)
|
||||
loadingIndicator.rbx.AnchorPoint = Vector2.new(0.5, 0.5)
|
||||
loadingIndicator.rbx.Position = UDim2.new(0.5, 0, 0.5, 0)
|
||||
loadingIndicator.rbx.Size = UDim2.new(0.5, 0, 0.25, 0)
|
||||
loadingIndicator.rbx.Parent = self.bubble
|
||||
loadingIndicator:SetVisible(true)
|
||||
self.loadingIndicator = loadingIndicator
|
||||
end
|
||||
else
|
||||
if self.loadingIndicator then
|
||||
self.loadingIndicator:Destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not LuaChatAssetCardsSelfTerminateConnection then
|
||||
function AssetCard:DisconnectUpdate()
|
||||
if self.Content.Visible then
|
||||
if self.appStateConnection then
|
||||
self.appStateConnection:disconnect()
|
||||
self.appStateConnection = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AssetCard:Destruct()
|
||||
for _, connection in pairs(self.connections) do
|
||||
connection:disconnect()
|
||||
end
|
||||
self.connections = {}
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
for _, connection in pairs(self.rbx_connections) do
|
||||
connection:Disconnect()
|
||||
end
|
||||
self.rbx_connections = {}
|
||||
end
|
||||
if self.pinButtonClick then self.pinButtonClick:Disconnect() end
|
||||
if self.pinButtonInputBegin then self.pinButtonInputBegin:Disconnect() end
|
||||
self.rbx:Destroy()
|
||||
end
|
||||
|
||||
return AssetCard
|
||||
@@ -0,0 +1,373 @@
|
||||
local PlayerService = game:GetService("Players")
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local TweenService = game:GetService("TweenService")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local Common = Modules.Common
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local Components = LuaChat.Components
|
||||
|
||||
local ChatGameDrawer = require(Components.ChatGameDrawer)
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local DialogInfo = require(LuaChat.DialogInfo)
|
||||
local PaddedImageButton = require(LuaChat.Components.PaddedImageButton)
|
||||
local Roact = require(CoreGui.RobloxGui.Modules.Common.Roact)
|
||||
local RoactAnalytics = require(LuaApp.Services.RoactAnalytics)
|
||||
local RoactLocalization = require(LuaApp.Services.RoactLocalization)
|
||||
local RoactRodux = require(CoreGui.RobloxGui.Modules.Common.RoactRodux)
|
||||
local RoactServices = require(LuaApp.RoactServices)
|
||||
local Text = require(Common.Text)
|
||||
|
||||
local FFlagLuaChatLoadGameLinkCardInChatAnalytics = settings():GetFFlag("LuaChatLoadGameLinkCardInChatAnalytics")
|
||||
local FFlagGroupChatIconEnabled = settings():GetFFlag("LuaChatGroupChatIconEnabled")
|
||||
local FFlagLuaChatFlexibleTitleWidth = settings():GetFFlag("LuaChatFlexibleTitleWidth")
|
||||
local FFlagLuaChatToSplitRbxConnections = settings():GetFFlag("LuaChatToSplitRbxConnections")
|
||||
|
||||
local PLATFORM_SPECIFIC_CONSTANTS = {
|
||||
[Enum.Platform.Android] = {
|
||||
BACK_BUTTON_ASSET_ID = "rbxasset://textures/ui/LuaChat/icons/ic-back-android.png",
|
||||
},
|
||||
|
||||
Default = {
|
||||
BACK_BUTTON_ASSET_ID = "rbxasset://textures/ui/LuaChat/icons/ic-back.png",
|
||||
},
|
||||
}
|
||||
|
||||
local TITLE_LABEL_MAX_WIDTH = 200
|
||||
local TITLE_LABEL_HEIGHT = 25
|
||||
|
||||
local function getPlatformSpecific(platform)
|
||||
return PLATFORM_SPECIFIC_CONSTANTS[platform] or PLATFORM_SPECIFIC_CONSTANTS.Default
|
||||
end
|
||||
|
||||
local function createRoactInstanceGameDrawer(self)
|
||||
local newGameDrawer = Roact.createElement(ChatGameDrawer, {
|
||||
conversationId = self.conversationId,
|
||||
isGameDrawerOpen = self.isGameDrawerOpen,
|
||||
Localization = self.appState.localization,
|
||||
onSize = function(newSize, forceOpen)
|
||||
self:SetGameDrawerSize(newSize, forceOpen)
|
||||
end,
|
||||
})
|
||||
return Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = self.appState.store,
|
||||
}, {
|
||||
serviceProvider = Roact.createElement(RoactServices.ServiceProvider, {
|
||||
services = {
|
||||
[RoactAnalytics] = self.appState.analytics,
|
||||
[RoactLocalization] = self.appState.localization,
|
||||
}
|
||||
}, {
|
||||
newGameDrawer
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
local BaseHeader = {}
|
||||
|
||||
--[[
|
||||
This type of pseudo-inheritance for components is usually bad, but this is a special exception.
|
||||
It is not recommended to do this.
|
||||
]]
|
||||
function BaseHeader:Template()
|
||||
local class = {}
|
||||
for key, value in pairs(self) do
|
||||
class[key] = value
|
||||
end
|
||||
return class
|
||||
end
|
||||
|
||||
function BaseHeader:SetPlatform(platform)
|
||||
self.platform = platform
|
||||
end
|
||||
|
||||
function BaseHeader:SetTitle(text)
|
||||
local label = self.titleLabel
|
||||
if label then
|
||||
local labelFont = label.Font
|
||||
local labelTextSize = label.TextSize
|
||||
|
||||
local maxTitleLabelWidth = self.innerTitles.AbsoluteSize.X
|
||||
if FFlagGroupChatIconEnabled and self.groupChatIcon then
|
||||
maxTitleLabelWidth = maxTitleLabelWidth
|
||||
- (self.groupChatIcon.Visible and self.groupChatIcon.AbsoluteSize.X or 0)
|
||||
end
|
||||
|
||||
if FFlagLuaChatFlexibleTitleWidth then
|
||||
label.Text = Text.Truncate(text, labelFont, labelTextSize, maxTitleLabelWidth, "...")
|
||||
else
|
||||
label.Text = Text.Truncate(text, labelFont, labelTextSize, TITLE_LABEL_MAX_WIDTH, "...")
|
||||
end
|
||||
|
||||
local titleTextLength = Text.GetTextWidth(label.Text, labelFont, labelTextSize)
|
||||
self.titleLabel.Size = UDim2.new(0, titleTextLength, 0, TITLE_LABEL_HEIGHT)
|
||||
end
|
||||
self.title = text
|
||||
end
|
||||
|
||||
function BaseHeader:SetDefaultSubtitle()
|
||||
if (self.dialogType ~= DialogInfo.DialogType.Centered) and (self.dialogType ~= DialogInfo.DialogType.Left) then
|
||||
self:SetSubtitle("")
|
||||
return
|
||||
end
|
||||
local displayText = ""
|
||||
local player = PlayerService.LocalPlayer
|
||||
if player then
|
||||
local userId = tostring(player.UserId)
|
||||
local localUser = self.appState.store:getState().Users[userId]
|
||||
if localUser and not localUser.isFetching then
|
||||
if player:GetUnder13() then
|
||||
displayText = string.format("%s: <13", localUser.name)
|
||||
else
|
||||
displayText = string.format("%s: 13+", localUser.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
self:SetSubtitle(displayText)
|
||||
end
|
||||
|
||||
--[[
|
||||
Sets the Header's subtitle
|
||||
|
||||
Pass an empty string to hide the subtitle completely.
|
||||
|
||||
Otherwise pass nil to default to the userAge label.
|
||||
]]
|
||||
function BaseHeader:SetSubtitle(displayText)
|
||||
assert(type(displayText) == "nil" or type(displayText) == "string",
|
||||
"Invalid argument number #1 to SetSubtitle, expected string or nil.")
|
||||
self.subtitle = displayText
|
||||
if displayText == "" then
|
||||
self.innerSubtitle.Visible = false
|
||||
else
|
||||
self.innerSubtitle.Visible = true
|
||||
self.innerSubtitle.Text = displayText
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:SetBackButtonEnabled(enabled)
|
||||
self.backButton.rbx.Visible = enabled
|
||||
end
|
||||
|
||||
function BaseHeader:AddButton(button)
|
||||
table.insert(self.buttons, button)
|
||||
button.rbx.Parent = self.innerButtons
|
||||
button.rbx.LayoutOrder = #self.buttons
|
||||
end
|
||||
|
||||
function BaseHeader:AddContent(content)
|
||||
content.rbx.Parent = self.innerContent
|
||||
end
|
||||
|
||||
function BaseHeader:SetConnectionState(connectionState)
|
||||
if not self.subtitle then
|
||||
self:SetDefaultSubtitle()
|
||||
end
|
||||
if self.dialogType == DialogInfo.DialogType.Right then
|
||||
return
|
||||
end
|
||||
if connectionState ~= self.connectionState and self.rbx.Parent ~= nil and self.rbx.Parent.Parent ~= nil then
|
||||
if connectionState == Enum.ConnectionState.Disconnected then
|
||||
self.isDisconnectedOpen = true
|
||||
self:DoSizeTweening()
|
||||
else
|
||||
self.isDisconnectedOpen = false
|
||||
self:DoSizeTweening()
|
||||
end
|
||||
self.connectionState = connectionState
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:GetNewBackButton(dialogType)
|
||||
local backButton
|
||||
if dialogType == DialogInfo.DialogType.Modal then
|
||||
backButton = PaddedImageButton.new(self.appState, "Close", "rbxasset://textures/ui/LuaChat/icons/ic-close-gray2.png")
|
||||
elseif dialogType == DialogInfo.DialogType.Popup then
|
||||
backButton = PaddedImageButton.new(self.appState, "Close", "rbxasset://textures/ui/LuaChat/icons/ic-close-white.png")
|
||||
else
|
||||
backButton = PaddedImageButton.new(self.appState, "Back", getPlatformSpecific(self.platform).BACK_BUTTON_ASSET_ID)
|
||||
end
|
||||
backButton.rbx.Position = UDim2.new(0, 0, 0.5, 0)
|
||||
backButton.rbx.AnchorPoint = Vector2.new(0, 0.5)
|
||||
return backButton
|
||||
end
|
||||
|
||||
function BaseHeader:Destroy()
|
||||
for _, conn in pairs(self.connections) do
|
||||
conn:disconnect()
|
||||
end
|
||||
self.connections = {}
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
for _, conn in pairs(self.rbx_connections) do
|
||||
conn:Disconnect()
|
||||
end
|
||||
self.rbx_connections = {}
|
||||
end
|
||||
|
||||
self.buttons = {}
|
||||
-- Destroy an attached Roact Gamedrawer if we have one:
|
||||
if self.roactInstanceGameDrawer ~= nil then
|
||||
Roact.teardown(self.roactInstanceGameDrawer)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:CreateGameDrawer(store, conversationId)
|
||||
-- Create the game drawer. Note it's probably not shown yet:
|
||||
self.conversationId = conversationId
|
||||
self.heightOfGameDrawer = 0
|
||||
self.hasFriendsInGame = false
|
||||
self.isGameDrawerSized = false
|
||||
self.isGameDrawerOpen = false
|
||||
if FFlagLuaChatLoadGameLinkCardInChatAnalytics then
|
||||
self.roactInstanceGameDrawer = Roact.mount(createRoactInstanceGameDrawer(self), self.rbx.GameDrawer, "ChatGameDrawer")
|
||||
else
|
||||
local newGameDrawer = Roact.createElement(ChatGameDrawer, {
|
||||
AnchorPoint = Vector2.new(0, 0),
|
||||
conversationId = conversationId,
|
||||
Localization = self.appState.localization,
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
onSize = function(newSize, forceOpen)
|
||||
self:SetGameDrawerSize(newSize, forceOpen)
|
||||
end,
|
||||
})
|
||||
self.roactInstanceGameDrawer = Roact.mount(Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = store,
|
||||
}, {
|
||||
serviceProvider = Roact.createElement(RoactServices.ServiceProvider, {
|
||||
services = {
|
||||
[RoactLocalization] = self.appState.localization,
|
||||
}
|
||||
}, {
|
||||
newGameDrawer
|
||||
})
|
||||
}), self.rbx.GameDrawer, "ChatGameDrawer")
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:ToggleGameDrawer()
|
||||
if self.isGameDrawerOpen == false then
|
||||
self.isGameDrawerOpen = true
|
||||
else
|
||||
self.isGameDrawerOpen = false
|
||||
end
|
||||
if FFlagLuaChatLoadGameLinkCardInChatAnalytics then
|
||||
self.roactInstanceGameDrawer = Roact.reconcile(self.roactInstanceGameDrawer, createRoactInstanceGameDrawer(self))
|
||||
end
|
||||
self:DoSizeTweening()
|
||||
end
|
||||
|
||||
-- Note: Start is called whenever we return to a conversation:
|
||||
function BaseHeader:Start()
|
||||
self.lastHeight = -1
|
||||
self.lastHeightDisconnected = -1
|
||||
self.lastHeightDrawer = -1
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
if self.hasFriendsInGame then
|
||||
self:OpenDrawer()
|
||||
else
|
||||
self:CloseDrawer()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:OpenDrawer()
|
||||
if self.isGameDrawerSized and (not self.isGameDrawerOpen) then
|
||||
self.isGameDrawerOpen = true
|
||||
self:DoSizeTweening()
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:CloseDrawer()
|
||||
if self.isGameDrawerSized and self.isGameDrawerOpen then
|
||||
self.isGameDrawerOpen = false
|
||||
self:DoSizeTweening()
|
||||
end
|
||||
end
|
||||
|
||||
function BaseHeader:InputFocus()
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
self:CloseDrawer()
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the open game drawer size - and tween it open:
|
||||
function BaseHeader:SetGameDrawerSize(drawerSize, hasFriendsInGame)
|
||||
if drawerSize > 0 and hasFriendsInGame and not self.isGameDrawerSized then
|
||||
self.isGameDrawerOpen = true
|
||||
end
|
||||
self.heightOfGameDrawer = drawerSize
|
||||
self.hasFriendsInGame = hasFriendsInGame
|
||||
self.isGameDrawerSized = true
|
||||
self:DoSizeTweening()
|
||||
end
|
||||
|
||||
-- Do tweening for any drawers that might be open:
|
||||
function BaseHeader:DoSizeTweening()
|
||||
-- Base height of our header is the main contents:
|
||||
local desiredHeight = self.heightOfHeader
|
||||
|
||||
-- Disconnected is the network error message:
|
||||
if self.isDisconnectedOpen then
|
||||
desiredHeight = desiredHeight + self.heightOfDisconnected
|
||||
if not self.rbx.Disconnected.Visible or
|
||||
(self.lastHeightDisconnected ~= self.heightOfDisconnected) then
|
||||
local size = UDim2.new(1, 0, 0, self.heightOfDisconnected)
|
||||
local resizeTween = TweenService:Create(
|
||||
self.rbx.Disconnected,
|
||||
TweenInfo.new(Constants.Tween.DEFAULT_TWEEN_TIME, Constants.Tween.DEFAULT_TWEEN_STYLE, Enum.EasingDirection.In),
|
||||
{ Size = size }
|
||||
)
|
||||
resizeTween:Play()
|
||||
self.rbx.Disconnected.Visible = true
|
||||
self.lastHeightDisconnected = self.heightOfDisconnected
|
||||
end
|
||||
else
|
||||
if self.rbx.Disconnected.Visible then
|
||||
self.rbx.Disconnected.Size = UDim2.new(1, 0, 0, 0)
|
||||
self.rbx.Disconnected.Visible = false
|
||||
self.lastHeightDisconnected = 0
|
||||
end
|
||||
end
|
||||
|
||||
if self.luaChatPlayTogetherEnabled then
|
||||
-- Game drawer is the list of games being played by participants of this conversation:
|
||||
if self.isGameDrawerOpen and self.heightOfGameDrawer then
|
||||
desiredHeight = desiredHeight + self.heightOfGameDrawer
|
||||
if not self.rbx.GameDrawer.Visible or
|
||||
(self.lastHeightDrawer ~= self.heightOfGameDrawer) then
|
||||
self.rbx.GameDrawer.Visible = true
|
||||
local size = UDim2.new(1, 0, 0, self.heightOfGameDrawer)
|
||||
local resizeTween = TweenService:Create(
|
||||
self.rbx.GameDrawer,
|
||||
TweenInfo.new(Constants.Tween.DEFAULT_TWEEN_TIME, Constants.Tween.DEFAULT_TWEEN_STYLE, Enum.EasingDirection.In),
|
||||
{ Size = size }
|
||||
)
|
||||
resizeTween:Play()
|
||||
self.lastHeightDrawer = self.heightOfGameDrawer
|
||||
end
|
||||
else
|
||||
if self.rbx.GameDrawer.Visible then
|
||||
self.rbx.GameDrawer.Size = UDim2.new(1, 0, 0, 0)
|
||||
self.rbx.GameDrawer.Visible = false
|
||||
self.lastHeightDrawer = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the size of the main drawer:
|
||||
if (self.lastHeight ~= desiredHeight) then
|
||||
local size = UDim2.new(1, 0, 0, desiredHeight)
|
||||
local resizeTween = TweenService:Create(
|
||||
self.rbx,
|
||||
TweenInfo.new(Constants.Tween.DEFAULT_TWEEN_TIME, Constants.Tween.DEFAULT_TWEEN_STYLE, Enum.EasingDirection.In),
|
||||
{ Size = size }
|
||||
)
|
||||
resizeTween:Play()
|
||||
self.lastHeight = desiredHeight
|
||||
end
|
||||
end
|
||||
|
||||
return BaseHeader
|
||||
@@ -0,0 +1,187 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local NotificationService = game:GetService("NotificationService")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local AppNotificationService = require(LuaApp.Services.AppNotificationService)
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local Create = require(LuaChat.Create)
|
||||
local DialogInfo = require(LuaChat.DialogInfo)
|
||||
local Intent = DialogInfo.Intent
|
||||
local Signal = require(Common.Signal)
|
||||
|
||||
local Roact = require(Common.Roact)
|
||||
local RoactAnalytics = require(LuaApp.Services.RoactAnalytics)
|
||||
local RoactLocalization = require(LuaApp.Services.RoactLocalization)
|
||||
local RoactNetworking = require(LuaApp.Services.RoactNetworking)
|
||||
local RoactRodux = require(Common.RoactRodux)
|
||||
local RoactServices = require(LuaApp.RoactServices)
|
||||
|
||||
local Components = LuaChat.Components
|
||||
local HeaderLoader = require(Components.HeaderLoader)
|
||||
local ResponseIndicator = require(Components.ResponseIndicator)
|
||||
--[[
|
||||
TODO: we would have a ticket "removing the fast flag LuaChatShareGameToChatFromChatV2".
|
||||
When removing the flag LuaChatShareGameToChatFromChatV2, we need to delete the actions, reduces and store that
|
||||
V1 share game to chat from chat used.
|
||||
]]
|
||||
-- V1 sharing game to chat from chat
|
||||
local SharedGameList = require(Components.SharedGameList)
|
||||
-- V2 sharing game to chat from chat
|
||||
local SharedGamesList = require(Components.ShareGameToChatFromChat.SharedGamesList)
|
||||
local TabBarView = require(LuaChat.TabBarView)
|
||||
local TabPageParameters = require(LuaChat.Models.TabPageParameters)
|
||||
|
||||
-- Actions for V1 sharing game to chat from chat
|
||||
local ClearAllGames = require(LuaChat.Actions.ShareGameToChatFromChat.ClearAllGamesInSortsShareGameToChatFromChat)
|
||||
local ResetShareGameToChatAsync = require(LuaChat.Actions.ShareGameToChatFromChat.ResetShareGameToChatFromChatAsync)
|
||||
|
||||
local FFlagLuaChatToSplitRbxConnections = settings():GetFFlag("LuaChatToSplitRbxConnections")
|
||||
local FFlagLuaChatShareGameToChatFromChatV2 = settings():GetFFlag("LuaChatShareGameToChatFromChatV2")
|
||||
|
||||
local BrowseGames = {}
|
||||
BrowseGames.__index = BrowseGames
|
||||
|
||||
function BrowseGames.new(appState)
|
||||
local self = {
|
||||
appState = appState,
|
||||
connections = {},
|
||||
rbx_connections = {},
|
||||
}
|
||||
setmetatable(self, BrowseGames)
|
||||
|
||||
self._analytics = self.appState.analytics
|
||||
self._localization = self.appState.localization
|
||||
self._request = self.appState.request
|
||||
|
||||
self.responseIndicator = ResponseIndicator.new(appState)
|
||||
self.responseIndicator:SetVisible(false)
|
||||
|
||||
self.header = HeaderLoader.GetHeader(appState, Intent.BrowseGames)
|
||||
self.header:SetDefaultSubtitle()
|
||||
self.header:SetTitle(self.appState.localization:Format("Feature.Chat.ShareGameToChat.BrowseGames"))
|
||||
self.header:SetBackButtonEnabled(true)
|
||||
self.header:SetConnectionState(Enum.ConnectionState.Disconnected)
|
||||
|
||||
local sharedGamesConfig = Constants.SharedGamesConfig
|
||||
self.gamesPages = {}
|
||||
|
||||
local sharedGamesList = FFlagLuaChatShareGameToChatFromChatV2 and SharedGamesList
|
||||
or SharedGameList
|
||||
|
||||
for _, sortName in ipairs(sharedGamesConfig.SortNames) do
|
||||
table.insert(
|
||||
self.gamesPages,
|
||||
TabPageParameters(
|
||||
self._localization:Format(sharedGamesConfig.SortsAttribute[sortName].TILE_LOCALIZATION_KEY),
|
||||
sharedGamesList,
|
||||
{
|
||||
gameSort = sortName,
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
self.rbx = Create.new"Frame" {
|
||||
Name = "BrowseGames",
|
||||
BackgroundTransparency = 1,
|
||||
BorderSizePixel = 0,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
|
||||
Create.new("UIListLayout") {
|
||||
Name = "ListLayout",
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
},
|
||||
|
||||
self.header.rbx,
|
||||
|
||||
Create.new"Frame" {
|
||||
Name = "Content",
|
||||
BackgroundColor3 = Constants.Color.GRAY5,
|
||||
BorderSizePixel = 0,
|
||||
ClipsDescendants = true,
|
||||
LayoutOrder = 1,
|
||||
Size = UDim2.new(1, 0, 1, -self.header.heightOfHeader),
|
||||
|
||||
self.responseIndicator.rbx,
|
||||
},
|
||||
}
|
||||
|
||||
self.mainContent = Roact.mount(Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = appState.store,
|
||||
}, {
|
||||
Roact.createElement(RoactServices.ServiceProvider, {
|
||||
services = {
|
||||
[AppNotificationService] = NotificationService,
|
||||
[RoactAnalytics] = self._analytics,
|
||||
[RoactLocalization] = self._localization,
|
||||
[RoactNetworking] = self._request,
|
||||
}
|
||||
}, {
|
||||
TabBarView = Roact.createElement(TabBarView, {
|
||||
tabs = self.gamesPages,
|
||||
}),
|
||||
}),
|
||||
|
||||
}), self.rbx.Content, "MainContent")
|
||||
|
||||
self.BackButtonPressed = Signal.new()
|
||||
self.header.BackButtonPressed:connect(function()
|
||||
if not FFlagLuaChatShareGameToChatFromChatV2 then
|
||||
self:CleanGamesInSorts()
|
||||
end
|
||||
self.BackButtonPressed:fire()
|
||||
end)
|
||||
|
||||
local headerSizeConnection = self.header.rbx:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
|
||||
self:Resize()
|
||||
end)
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
table.insert(self.rbx_connections, headerSizeConnection)
|
||||
else
|
||||
table.insert(self.connections, headerSizeConnection)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function BrowseGames:CleanGamesInSorts()
|
||||
self.appState.store:dispatch(ClearAllGames())
|
||||
self.appState.store:dispatch(ResetShareGameToChatAsync())
|
||||
end
|
||||
|
||||
function BrowseGames:Resize()
|
||||
local sizeContent = UDim2.new(1, 0, 1, -self.header.rbx.AbsoluteSize.Y)
|
||||
self.rbx.Content.Size = sizeContent
|
||||
end
|
||||
|
||||
function BrowseGames:Update(current, previous)
|
||||
self.header:SetConnectionState(current.ConnectionState)
|
||||
|
||||
local isSharing = self.appState.store:getState().ChatAppReducer.ShareGameToChatAsync.sharingGame or false
|
||||
self.responseIndicator:SetVisible(isSharing)
|
||||
end
|
||||
|
||||
function BrowseGames:Destruct()
|
||||
for _, connection in pairs(self.connections) do
|
||||
connection:Disconnect()
|
||||
end
|
||||
self.connections = {}
|
||||
if FFlagLuaChatToSplitRbxConnections then
|
||||
for _, connection in pairs(self.rbx_connections) do
|
||||
connection:Disconnect()
|
||||
end
|
||||
self.rbx_connections = {}
|
||||
end
|
||||
|
||||
self.header:Destroy()
|
||||
self.responseIndicator:Destruct()
|
||||
Roact.unmount(self.mainContent)
|
||||
|
||||
self.rbx:Destroy()
|
||||
end
|
||||
|
||||
return BrowseGames
|
||||
@@ -0,0 +1,35 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local AppState = require(LuaChat.AppState)
|
||||
local BrowseGames = require(LuaChat.Components.BrowseGames)
|
||||
local FormFactor = require(Modules.LuaApp.Enum.FormFactor)
|
||||
local SetFormFactor = require(Modules.LuaApp.Actions.SetFormFactor)
|
||||
|
||||
describe("new", function()
|
||||
it("should create and destruct BrowseGames page on mobile phone with no errors", function()
|
||||
local appState = AppState.mock()
|
||||
appState.store:dispatch(SetFormFactor(FormFactor.PHONE))
|
||||
|
||||
local browseGames = BrowseGames.new(appState)
|
||||
expect(browseGames).to.be.ok()
|
||||
|
||||
browseGames:Destruct()
|
||||
expect(browseGames).to.be.ok()
|
||||
end)
|
||||
|
||||
it("should create and destruct BrowseGames page on tablet with no errors", function()
|
||||
local appState = AppState.mock()
|
||||
appState.store:dispatch(SetFormFactor(FormFactor.TABLET))
|
||||
|
||||
local browseGames = BrowseGames.new(appState)
|
||||
expect(browseGames).to.be.ok()
|
||||
|
||||
browseGames:Destruct()
|
||||
expect(browseGames).to.be.ok()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user