add gs
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local SetActiveConversationId = require(Modules.LuaChat.Actions.SetActiveConversationId)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == SetActiveConversationId.name then
|
||||
return action.conversationId
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local SetAppLoaded = require(Modules.LuaChat.Actions.SetAppLoaded)
|
||||
|
||||
return function(state, action)
|
||||
state = state or false
|
||||
|
||||
if action.type == SetAppLoaded.name then
|
||||
return action.value
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local SetAppLoaded = require(LuaChat.Actions.SetAppLoaded)
|
||||
local AppLoaded = require(script.Parent.AppLoaded)
|
||||
describe("Action AppLoaded", function()
|
||||
it("should be unloaded by default", function()
|
||||
local state = AppLoaded(nil, {})
|
||||
|
||||
expect(state).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should be changed using SetAppLoaded", function()
|
||||
local state = AppLoaded(nil, {})
|
||||
|
||||
state = AppLoaded(state, SetAppLoaded(false))
|
||||
|
||||
expect(state).to.equal(false)
|
||||
|
||||
state = AppLoaded(state, SetAppLoaded(true))
|
||||
|
||||
expect(state).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local DeleteAlert = require(LuaChat.Actions.DeleteAlert)
|
||||
local ShowAlert = require(LuaChat.Actions.ShowAlert)
|
||||
|
||||
local Immutable = require(Common.Immutable)
|
||||
local OrderedMap = require(LuaChat.OrderedMap)
|
||||
|
||||
local function getAlertId(alert)
|
||||
return alert.id
|
||||
end
|
||||
|
||||
local function alertSortPredicate(alert1, alert2)
|
||||
return alert1.createdAt < alert2.createdAt
|
||||
end
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == ShowAlert.name then
|
||||
local alert = action.alert
|
||||
local alerts = state["alerts"] or OrderedMap.new(getAlertId, alertSortPredicate)
|
||||
alerts = OrderedMap.Insert(alerts, alert)
|
||||
state = Immutable.Set(state, "alerts", alerts)
|
||||
elseif action.type == DeleteAlert.name then
|
||||
local alert = action.alert
|
||||
local alerts = state["alerts"] or OrderedMap.new(getAlertId, alertSortPredicate)
|
||||
alerts = OrderedMap.Delete(alerts, alert.id)
|
||||
state = Immutable.Set(state, "alerts", alerts)
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local SetChatEnabled = require(Modules.LuaChat.Actions.SetChatEnabled)
|
||||
|
||||
return function(state, action)
|
||||
state = (state == nil) and true or state
|
||||
|
||||
if action.type == SetChatEnabled.name then
|
||||
return action.value
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local SetChatEnabled = require(LuaChat.Actions.SetChatEnabled)
|
||||
|
||||
local ChatEnabled = require(script.Parent.ChatEnabled)
|
||||
|
||||
it("should be enabled by default", function()
|
||||
local state = ChatEnabled(nil, {})
|
||||
|
||||
expect(state).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should be changed using SetChatEnabled", function()
|
||||
local state = ChatEnabled(nil, {})
|
||||
|
||||
state = ChatEnabled(state, SetChatEnabled(false))
|
||||
|
||||
expect(state).to.equal(false)
|
||||
|
||||
state = ChatEnabled(state, SetChatEnabled(true))
|
||||
|
||||
expect(state).to.equal(true)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local CorePackages = game:GetService("CorePackages")
|
||||
|
||||
local LuaChat = CoreGui.RobloxGui.Modules.LuaChat
|
||||
local Immutable = require(CorePackages.AppTempCommon.Common.Immutable)
|
||||
local RetrievalStatus = require(CorePackages.AppTempCommon.LuaApp.Enum.RetrievalStatus)
|
||||
|
||||
local FetchChatSettingsStarted = require(LuaChat.Actions.FetchChatSettingsStarted)
|
||||
local FetchChatSettingsCompleted = require(LuaChat.Actions.FetchChatSettingsCompleted)
|
||||
local FetchChatSettingsFailed = require(LuaChat.Actions.FetchChatSettingsFailed)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {
|
||||
retrievalStatus = RetrievalStatus.NotStarted,
|
||||
chatEnabled = true
|
||||
}
|
||||
|
||||
if action.type == FetchChatSettingsStarted.name then
|
||||
state = Immutable.Set(state, "retrievalStatus", RetrievalStatus.Fetching)
|
||||
|
||||
elseif action.type == FetchChatSettingsCompleted.name then
|
||||
state = Immutable.Set(state, "retrievalStatus", RetrievalStatus.Done)
|
||||
state = Immutable.JoinDictionaries(state, action.settings)
|
||||
|
||||
elseif action.type == FetchChatSettingsFailed.name then
|
||||
state = Immutable.Set(state, "retrievalStatus", RetrievalStatus.Failed)
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local FetchChatSettingsCompleted = require(LuaChat.Actions.FetchChatSettingsCompleted)
|
||||
|
||||
local ChatSettings = require(script.Parent.ChatSettings)
|
||||
|
||||
it("should be enabled by default", function()
|
||||
local state = ChatSettings(nil, {})
|
||||
|
||||
expect(state.chatEnabled).to.equal(true)
|
||||
expect(state.isActiveChatUser).to.equal(nil)
|
||||
end)
|
||||
|
||||
it("should be changed using ChatSettings", function()
|
||||
local state = ChatSettings(nil, {})
|
||||
|
||||
state = ChatSettings(state, FetchChatSettingsCompleted({}))
|
||||
|
||||
expect(state.chatEnabled).to.equal(true)
|
||||
expect(state.isActiveChatUser).to.equal(nil)
|
||||
|
||||
state = ChatSettings(state, FetchChatSettingsCompleted({
|
||||
chatEnabled = false,
|
||||
isActiveChatUser = false
|
||||
}))
|
||||
|
||||
expect(state.chatEnabled).to.equal(false)
|
||||
expect(state.isActiveChatUser).to.equal(false)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
|
||||
local SetConnectionState = require(Modules.LuaChat.Actions.SetConnectionState)
|
||||
|
||||
return function(state, action)
|
||||
state = state or Enum.ConnectionState.Connected
|
||||
|
||||
if action.type == SetConnectionState.name then
|
||||
state = action.connectionState
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local SetConnectionState = require(LuaChat.Actions.SetConnectionState)
|
||||
local ConnectionStateReducer = require(script.Parent.ConnectionState)
|
||||
|
||||
it("should default to Connected", function()
|
||||
local state = ConnectionStateReducer(nil, {})
|
||||
|
||||
expect(state).to.equal(Enum.ConnectionState.Connected)
|
||||
end)
|
||||
|
||||
it("should update the ConnectionState", function()
|
||||
local state = ConnectionStateReducer(nil, {})
|
||||
|
||||
state = ConnectionStateReducer(state, SetConnectionState(Enum.ConnectionState.Disconnected))
|
||||
|
||||
expect(state).to.equal(Enum.ConnectionState.Disconnected)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,248 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local ChangedParticipants = require(Actions.ChangedParticipants)
|
||||
local FetchedOldestMessage = require(Actions.FetchedOldestMessage)
|
||||
local FetchingOlderMessages = require(Actions.FetchingOlderMessages)
|
||||
local MessageFailedToSend = require(Actions.MessageFailedToSend)
|
||||
local MessageModerated = require(Actions.MessageModerated)
|
||||
local ReadConversation = require(Actions.ReadConversation)
|
||||
local ReceivedConversation = require(Actions.ReceivedConversation)
|
||||
local ReceivedMessages = require(Actions.ReceivedMessages)
|
||||
local RemovedConversation = require(Actions.RemovedConversation)
|
||||
local RenamedGroupConversation = require(Actions.RenamedGroupConversation)
|
||||
local SendingMessage = require(Actions.SendingMessage)
|
||||
local SentMessage = require(Actions.SentMessage)
|
||||
local SetConversationLoadingStatus = require(Actions.SetConversationLoadingStatus)
|
||||
local SetPinnedGameForConversation = require(Actions.SetPinnedGameForConversation)
|
||||
local SetUserLeavingConversation = require(Actions.SetUserLeavingConversation)
|
||||
local SetUserTyping = require(Actions.SetUserTyping)
|
||||
|
||||
local ConversationModel = require(LuaChat.Models.Conversation)
|
||||
local Immutable = require(Common.Immutable)
|
||||
local OrderedMap = require(LuaChat.OrderedMap)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == ReceivedConversation.name then
|
||||
local conversation = action.conversation
|
||||
|
||||
if conversation.conversationType == ConversationModel.Type.ONE_TO_ONE_CONVERSATION then
|
||||
local idForFake = ConversationModel.IdForFakeOneOnOne(conversation.participants)
|
||||
if state[idForFake] ~= nil then
|
||||
state = Immutable.Set(state, idForFake, nil)
|
||||
end
|
||||
end
|
||||
|
||||
if not state[conversation.id] then
|
||||
state = Immutable.Set(state, conversation.id, conversation)
|
||||
end
|
||||
elseif action.type == ReceivedMessages.name then
|
||||
local conversationId = action.conversationId
|
||||
local conversation = state[conversationId]
|
||||
|
||||
if conversation then
|
||||
|
||||
local lastMessage = nil
|
||||
for i = 1, #action.messages do
|
||||
local message = action.messages[i]
|
||||
local existing = conversation.messages:Get(message.id)
|
||||
if existing then
|
||||
if lastMessage then
|
||||
lastMessage.previousMessageId = existing.id
|
||||
end
|
||||
if message.previousMessageId == nil and existing.previousMessageId ~= nil then
|
||||
message.previousMessageId = existing.previousMessageId
|
||||
end
|
||||
message.read = message.read or existing.read
|
||||
end
|
||||
lastMessage = message
|
||||
end
|
||||
|
||||
local messages = OrderedMap.Insert(conversation.messages, unpack(action.messages))
|
||||
|
||||
if action.exclusiveStartMessageId and #action.messages > 0 then
|
||||
if messages:Get(action.exclusiveStartMessageId) then
|
||||
local prevMessage = action.messages[1]
|
||||
local nextMessage = messages:Get(action.exclusiveStartMessageId)
|
||||
nextMessage = Immutable.Set(nextMessage, "previousMessageId", prevMessage.id)
|
||||
messages = messages:Insert(nextMessage)
|
||||
end
|
||||
end
|
||||
|
||||
local lastConversationKey = messages.keys[#messages.keys]
|
||||
lastMessage = messages.values[lastConversationKey]
|
||||
|
||||
if lastMessage ~= nil then
|
||||
local lastUpdatedConvo = conversation.lastUpdated and conversation.lastUpdated:GetUnixTimestamp() or 0
|
||||
|
||||
local lastUpdated = (lastMessage.sent:GetUnixTimestamp() > lastUpdatedConvo) and
|
||||
lastMessage.sent or conversation.lastUpdated
|
||||
|
||||
local hasUnreadMessages = action.shouldMarkConversationUnread or conversation.hasUnreadMessages
|
||||
|
||||
local newConversation = Immutable.JoinDictionaries(conversation, {
|
||||
messages = messages;
|
||||
lastUpdated = lastUpdated;
|
||||
hasUnreadMessages = hasUnreadMessages;
|
||||
})
|
||||
|
||||
-- Mark all users as no longer typing
|
||||
-- We should only do this if a specific user sent a message and it's
|
||||
-- the last message in the list, but that check would be expensive
|
||||
-- to make every time we request more messages.
|
||||
-- Notably, this will fail for group conversations.
|
||||
newConversation = Immutable.Set(newConversation, "usersTyping", {})
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
end
|
||||
elseif action.type == SendingMessage.name then
|
||||
local conversationId = action.conversationId
|
||||
local conversation = state[conversationId]
|
||||
|
||||
if conversation then
|
||||
local sendingMessages = OrderedMap.Insert(conversation.sendingMessages, action.message)
|
||||
local newConversation = Immutable.Set(conversation, "sendingMessages", sendingMessages)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
elseif action.type == SentMessage.name then
|
||||
local conversationId = action.conversationId
|
||||
local conversation = state[conversationId]
|
||||
|
||||
if conversation then
|
||||
local sendingMessages = OrderedMap.Delete(conversation.sendingMessages, action.messageId)
|
||||
local newConversation = Immutable.Set(conversation, "sendingMessages", sendingMessages)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
elseif action.type == RenamedGroupConversation.name then
|
||||
local conversationId = action.conversationId
|
||||
|
||||
local conversation = state[conversationId]
|
||||
|
||||
if conversation then
|
||||
local newConversation = Immutable.JoinDictionaries(conversation, {
|
||||
lastUpdated = action.lastUpdated,
|
||||
title = action.title,
|
||||
isDefaultTitle = action.isDefaultTitle,
|
||||
})
|
||||
state = Immutable.Set(state, conversationId, newConversation)
|
||||
end
|
||||
elseif action.type == ChangedParticipants.name then
|
||||
local convoId = action.conversationId
|
||||
local newParticipants = action.participants
|
||||
|
||||
local conversation = state[convoId]
|
||||
|
||||
if conversation then
|
||||
local newConversation = Immutable.JoinDictionaries(conversation, {
|
||||
participants = newParticipants,
|
||||
lastUpdated = action.lastUpdated,
|
||||
title = action.title,
|
||||
})
|
||||
state = Immutable.Set(state, convoId, newConversation)
|
||||
end
|
||||
elseif action.type == RemovedConversation.name then
|
||||
local conversationId = action.conversationId
|
||||
state = Immutable.Set(state, conversationId, nil)
|
||||
|
||||
elseif action.type == SetUserTyping.name then
|
||||
local conversation = state[action.conversationId]
|
||||
|
||||
if conversation then
|
||||
local usersTyping = conversation.usersTyping
|
||||
local newUsersTyping = Immutable.Set(usersTyping, action.userId, action.value)
|
||||
local newConversation = Immutable.Set(conversation, "usersTyping", newUsersTyping)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
elseif action.type == FetchingOlderMessages.name then
|
||||
local conversation = state[action.conversationId]
|
||||
if conversation then
|
||||
local newConversation = Immutable.Set(conversation, "fetchingOlderMessages", action.fetchingOlderMessages)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
elseif action.type == FetchedOldestMessage.name then
|
||||
local conversation = state[action.conversationId]
|
||||
local newConversation = Immutable.Set(conversation, "fetchedOldestMessage", action.fetchedOldestMessage)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
|
||||
elseif action.type == ReadConversation.name then
|
||||
local conversation = state[action.conversationId]
|
||||
|
||||
if not conversation then
|
||||
warn("Conversation " .. action.conversationId .. " not found in ReadConversation reducer")
|
||||
return
|
||||
end
|
||||
|
||||
local newMessages = conversation.messages:Map(function(message)
|
||||
if message.read then
|
||||
return message
|
||||
else
|
||||
return Immutable.Set(message, "read", true)
|
||||
end
|
||||
end)
|
||||
|
||||
local newConversation = Immutable.Set(conversation, "messages", newMessages)
|
||||
newConversation = Immutable.Set(newConversation, "hasUnreadMessages", false)
|
||||
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
|
||||
elseif action.type == MessageModerated.name then
|
||||
local conversation = state[action.conversationId]
|
||||
local message = conversation.sendingMessages:Get(action.messageId)
|
||||
|
||||
if message then
|
||||
local newMessage = Immutable.Set(message, "moderated", true)
|
||||
local newSendingMessages = conversation.sendingMessages:Insert(newMessage)
|
||||
local newConversation = Immutable.Set(conversation, "sendingMessages", newSendingMessages)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
|
||||
elseif action.type == MessageFailedToSend.name then
|
||||
local conversation = state[action.conversationId]
|
||||
local message = conversation.sendingMessages:Get(action.messageId)
|
||||
|
||||
if message then
|
||||
local newMessage = Immutable.Set(message, "failed", true)
|
||||
local newSendingMessages = conversation.sendingMessages:Insert(newMessage)
|
||||
local newConversation = Immutable.Set(conversation, "sendingMessages", newSendingMessages)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
|
||||
elseif action.type == SetConversationLoadingStatus.name then
|
||||
local conversation = state[action.conversationId]
|
||||
local newConversation = Immutable.Set(conversation, "initialLoadingStatus", action.value)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
|
||||
elseif action.type == SetUserLeavingConversation.name then
|
||||
local conversation = state[action.id]
|
||||
if conversation then
|
||||
local newConversation = Immutable.Set(conversation, "isUserLeaving", action.isLeaving)
|
||||
state = Immutable.Set(state, newConversation.id, newConversation)
|
||||
end
|
||||
|
||||
elseif action.type == SetPinnedGameForConversation.name then
|
||||
|
||||
local conversationId = action.conversationId
|
||||
local conversation = state[conversationId]
|
||||
|
||||
if conversation then
|
||||
local newPinnedGame = {
|
||||
rootPlaceId = action.rootPlaceId;
|
||||
universeId = action.universeId;
|
||||
}
|
||||
|
||||
local newConversation = Immutable.JoinDictionaries(conversation, {
|
||||
pinnedGame = newPinnedGame;
|
||||
})
|
||||
|
||||
state = Immutable.Set(state, conversationId, newConversation)
|
||||
end
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,455 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local ChangedParticipants = require(LuaChat.Actions.ChangedParticipants)
|
||||
local Constants = require(LuaChat.Constants)
|
||||
local Conversation = require(LuaChat.Models.Conversation)
|
||||
local DateTime = require(LuaChat.DateTime)
|
||||
local FetchedOldestMessage = require(LuaChat.Actions.FetchedOldestMessage)
|
||||
local FetchingOlderMessages = require(LuaChat.Actions.FetchingOlderMessages)
|
||||
local Message = require(LuaChat.Models.Message)
|
||||
local MessageFailedToSend = require(LuaChat.Actions.MessageFailedToSend)
|
||||
local MessageModerated = require(LuaChat.Actions.MessageModerated)
|
||||
local MockId = require(LuaApp.MockId)
|
||||
local ReadConversation = require(LuaChat.Actions.ReadConversation)
|
||||
local ReceivedConversation = require(LuaChat.Actions.ReceivedConversation)
|
||||
local ReceivedMessages = require(LuaChat.Actions.ReceivedMessages)
|
||||
local RemovedConversation = require(LuaChat.Actions.RemovedConversation)
|
||||
local RenamedGroupConversation = require(LuaChat.Actions.RenamedGroupConversation)
|
||||
local SendingMessage = require(LuaChat.Actions.SendingMessage)
|
||||
local SentMessage = require(LuaChat.Actions.SentMessage)
|
||||
local SetConversationLoadingStatus = require(LuaChat.Actions.SetConversationLoadingStatus)
|
||||
local SetPinnedGameForConversation = require(LuaChat.Actions.SetPinnedGameForConversation)
|
||||
local SetUserTyping = require(LuaChat.Actions.SetUserTyping)
|
||||
local User = require(LuaApp.Models.User)
|
||||
|
||||
local Conversations = require(script.Parent.Conversations)
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = Conversations(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action ReceivedConversation", function()
|
||||
it("should add a conversation to the store", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = nil
|
||||
local action = ReceivedConversation(conversation)
|
||||
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state).to.be.a("table")
|
||||
expect(state[conversation.id]).to.be.a("table")
|
||||
expect(state[conversation.id].id).to.equal(conversation.id)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action ReceivedMessages", function()
|
||||
it("should add messages to an existing conversation", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message = Message.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
local action = ReceivedMessages(conversation.id, {message})
|
||||
|
||||
state = Conversations(state, action)
|
||||
|
||||
local messages = state[conversation.id].messages
|
||||
expect(#messages.keys).to.equal(1)
|
||||
expect(messages.values[messages.keys[1]].id).to.equal(message.id)
|
||||
end)
|
||||
|
||||
it("should insert messages in-order", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message1 = Message.mock({ sent = DateTime.new(1992) })
|
||||
local message2 = Message.mock({ sent = DateTime.new(1990) })
|
||||
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action = ReceivedMessages(conversation.id, { message1, message2 })
|
||||
state = Conversations(state, action)
|
||||
|
||||
do
|
||||
local messages = state[conversation.id].messages
|
||||
expect(#messages.keys).to.equal(2)
|
||||
expect(messages.values[messages.keys[1]].id).to.equal(message2.id)
|
||||
expect(messages.values[messages.keys[2]].id).to.equal(message1.id)
|
||||
end
|
||||
|
||||
local message3 = Message.mock({ sent = DateTime.new(1991) })
|
||||
|
||||
action = ReceivedMessages(conversation.id, { message3 })
|
||||
state = Conversations(state, action)
|
||||
|
||||
do
|
||||
local messages = state[conversation.id].messages
|
||||
expect(#messages.keys).to.equal(3)
|
||||
expect(messages.values[messages.keys[1]].id).to.equal(message2.id)
|
||||
expect(messages.values[messages.keys[2]].id).to.equal(message3.id)
|
||||
expect(messages.values[messages.keys[3]].id).to.equal(message1.id)
|
||||
end
|
||||
end)
|
||||
|
||||
it("should set hasUnreadMessages if action.shouldMarkConversationUnread is true", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message1 = Message.mock({ read = true })
|
||||
local message2 = Message.mock({ read = false })
|
||||
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(false)
|
||||
|
||||
local action = ReceivedMessages(conversation.id, { message1, message2 }, true)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(true)
|
||||
end)
|
||||
|
||||
it("should not change hasUnreadMessages if action.shouldMarkConversationUnread is false", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message1 = Message.mock({ read = false })
|
||||
local message2 = Message.mock({ read = false })
|
||||
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(false)
|
||||
|
||||
local action = ReceivedMessages(conversation.id, { message1, message2 }, false)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action SendingMessage", function()
|
||||
it("should add to the list of sending messages", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message = Message.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action = SendingMessage(conversation.id, message)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id)).to.be.ok()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action SentMessage", function()
|
||||
it("should remove from the list of sending messages", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message = Message.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action1 = SendingMessage(conversation.id, message)
|
||||
state = Conversations(state, action1)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id)).to.be.ok()
|
||||
|
||||
local action2 = SentMessage(conversation.id, message.id)
|
||||
state = Conversations(state, action2)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id)).to.never.be.ok()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action RenamedGroupConversation", function()
|
||||
it("should rename the conversation", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
local action = RenamedGroupConversation(conversation.id, "Fleebledegoop, Ham Sammich and Lemur Face")
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].title).to.equal("Fleebledegoop, Ham Sammich and Lemur Face")
|
||||
end)
|
||||
|
||||
it("should update isDefaultTitle value", function()
|
||||
local conversation = Conversation.mock({
|
||||
isDefaultTitle = true,
|
||||
})
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
state = Conversations(state, RenamedGroupConversation(conversation.id, "test", false))
|
||||
|
||||
expect(state[conversation.id].isDefaultTitle).to.equal(false)
|
||||
end)
|
||||
|
||||
it("should update lastUpdated value", function()
|
||||
local oldTick = 0
|
||||
local newTick = 1
|
||||
local conversation = Conversation.mock({
|
||||
isDefaultTitle = true,
|
||||
lastUpdated = oldTick,
|
||||
})
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
state = Conversations(state, RenamedGroupConversation(conversation.id, "test", nil, newTick))
|
||||
|
||||
expect(state[conversation.id].lastUpdated).to.equal(newTick)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action ChangedParticipants", function()
|
||||
it("should update the participant list", function()
|
||||
local conversation = Conversation.mock()
|
||||
local user1 = User.mock()
|
||||
local user2 = User.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action = ChangedParticipants(conversation.id, { user1.id, user2.id })
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(#state[conversation.id].participants).to.equal(2)
|
||||
expect(state[conversation.id].participants[1]).to.equal(user1.id)
|
||||
expect(state[conversation.id].participants[2]).to.equal(user2.id)
|
||||
|
||||
action = ChangedParticipants(conversation.id, { user2.id })
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(#state[conversation.id].participants).to.equal(1)
|
||||
expect(state[conversation.id].participants[1]).to.equal(user2.id)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action RemovedConversation", function()
|
||||
it("should update the conversation list", function()
|
||||
local conversation1 = Conversation.mock()
|
||||
local conversation2 = Conversation.mock()
|
||||
local state = {
|
||||
[conversation1.id] = conversation1,
|
||||
[conversation2.id] = conversation2
|
||||
}
|
||||
|
||||
local action = RemovedConversation(conversation1.id)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation1.id]).to.equal(nil)
|
||||
expect(state[conversation2.id]).to.be.a("table")
|
||||
expect(state[conversation2.id].id).to.equal(conversation2.id)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action SetUserTyping", function()
|
||||
it("should set userTyping flag for user", function()
|
||||
local user = User.mock()
|
||||
local conversation = Conversation.mock({ participants = { user.id } })
|
||||
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].usersTyping[user.id]).to.never.be.ok()
|
||||
|
||||
local action1 = SetUserTyping(conversation.id, user.id, true)
|
||||
state = Conversations(state, action1)
|
||||
|
||||
expect(state[conversation.id].usersTyping[user.id]).to.equal(true)
|
||||
|
||||
local action2 = SetUserTyping(conversation.id, user.id, false)
|
||||
state = Conversations(state, action2)
|
||||
|
||||
expect(state[conversation.id].usersTyping[user.id]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action FetchingOlderMessages", function()
|
||||
it("sets the fetchingOlderMessages flag", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].fetchingOlderMessages).to.equal(false)
|
||||
|
||||
local action1 = FetchingOlderMessages(conversation.id, true)
|
||||
state = Conversations(state, action1)
|
||||
|
||||
expect(state[conversation.id].fetchingOlderMessages).to.equal(true)
|
||||
|
||||
local action2 = FetchingOlderMessages(conversation.id, false)
|
||||
state = Conversations(state, action2)
|
||||
|
||||
expect(state[conversation.id].fetchingOlderMessages).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action FetchedOldestMessage", function()
|
||||
it("sets the fetchedOldestMessage flag", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].fetchedOldestMessage).to.equal(false)
|
||||
|
||||
local action1 = FetchedOldestMessage(conversation.id, true)
|
||||
state = Conversations(state, action1)
|
||||
|
||||
expect(state[conversation.id].fetchedOldestMessage).to.equal(true)
|
||||
|
||||
local action2 = FetchedOldestMessage(conversation.id, false)
|
||||
state = Conversations(state, action2)
|
||||
|
||||
expect(state[conversation.id].fetchedOldestMessage).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action ReadConversation", function()
|
||||
it("should read messages and mark the conversation's unread state", function()
|
||||
local message1 = Message.mock({ sent = DateTime.new(1992), read = true })
|
||||
local message2 = Message.mock({ sent = DateTime.new(1993), read = false })
|
||||
local message3 = Message.mock({ sent = DateTime.new(1994), read = false })
|
||||
local message4 = Message.mock({ sent = DateTime.new(1995), read = false })
|
||||
local message5 = Message.mock({ sent = DateTime.new(1996), read = false })
|
||||
local conversation = Conversation.mock()
|
||||
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local actionAddMessages = ReceivedMessages(conversation.id, { message1, message2, message3, message4 }, true)
|
||||
state = Conversations(state, actionAddMessages)
|
||||
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(true)
|
||||
|
||||
local actionReadAll = ReadConversation(conversation.id)
|
||||
state = Conversations(state, actionReadAll)
|
||||
|
||||
do
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(false)
|
||||
local messages = state[conversation.id].messages
|
||||
expect(messages.values[message1.id].read).to.equal(true)
|
||||
expect(messages.values[message2.id].read).to.equal(true)
|
||||
expect(messages.values[message3.id].read).to.equal(true)
|
||||
end
|
||||
|
||||
local action2 = ReceivedMessages(conversation.id, { message4, message5 }, true)
|
||||
|
||||
state = Conversations(state, action2)
|
||||
|
||||
do
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(true)
|
||||
local messages = state[conversation.id].messages
|
||||
expect(messages.values[message1.id].read).to.equal(true)
|
||||
expect(messages.values[message2.id].read).to.equal(true)
|
||||
expect(messages.values[message3.id].read).to.equal(true)
|
||||
expect(messages.values[message4.id].read).to.equal(true)
|
||||
expect(messages.values[message5.id].read).to.equal(false)
|
||||
end
|
||||
|
||||
local actionReadAll2 = ReadConversation(conversation.id)
|
||||
state = Conversations(state, actionReadAll2)
|
||||
|
||||
do
|
||||
expect(state[conversation.id].hasUnreadMessages).to.equal(false)
|
||||
local messages = state[conversation.id].messages
|
||||
expect(messages.values[message1.id].read).to.equal(true)
|
||||
expect(messages.values[message2.id].read).to.equal(true)
|
||||
expect(messages.values[message3.id].read).to.equal(true)
|
||||
expect(messages.values[message4.id].read).to.equal(true)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action MessageModerated", function()
|
||||
it("should mark the sending message as moderated", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message = Message.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action = SendingMessage(conversation.id, message)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id).moderated).to.never.be.ok()
|
||||
|
||||
action = MessageModerated(conversation.id, message.id)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id).moderated).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action MessageFailedToSend", function()
|
||||
it("should mark the sending message as failed", function()
|
||||
local conversation = Conversation.mock()
|
||||
local message = Message.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local action = SendingMessage(conversation.id, message)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id).failed).to.equal(nil)
|
||||
|
||||
action = MessageFailedToSend(conversation.id, message.id)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].sendingMessages:Get(message.id).failed).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action SetConversationLoadingStatus", function()
|
||||
it("should set the conversation loading status", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
expect(state[conversation.id].initialLoadingStatus).to.never.be.ok()
|
||||
|
||||
local action = SetConversationLoadingStatus(conversation.id, Constants.ConversationLoadingState.LOADING)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].initialLoadingStatus).to.equal(Constants.ConversationLoadingState.LOADING)
|
||||
|
||||
action = SetConversationLoadingStatus(conversation.id, Constants.ConversationLoadingState.DONE)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].initialLoadingStatus).to.equal(Constants.ConversationLoadingState.DONE)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action SetPinnedGameForConversation", function()
|
||||
it("should set the pinned game for conversation", function()
|
||||
local conversation = Conversation.mock()
|
||||
local state = {
|
||||
[conversation.id] = conversation
|
||||
}
|
||||
|
||||
local mockRootPlaceId = MockId()
|
||||
local mockUniverseId = MockId()
|
||||
|
||||
local action = SetPinnedGameForConversation(mockUniverseId, mockRootPlaceId, conversation.id)
|
||||
state = Conversations(state, action)
|
||||
|
||||
expect(state[conversation.id].pinnedGame.rootPlaceId).to.equal(mockRootPlaceId)
|
||||
expect(state[conversation.id].pinnedGame.universeId).to.equal(mockUniverseId)
|
||||
end)
|
||||
end)
|
||||
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local ReceivedLatestMessages = require(LuaChat.Actions.ReceivedLatestMessages)
|
||||
local ReceivedOldestConversation = require(LuaChat.Actions.ReceivedOldestConversation)
|
||||
local ReceivedPageConversations = require(LuaChat.Actions.ReceivedPageConversations)
|
||||
local RequestLatestMessages = require(LuaChat.Actions.RequestLatestMessages)
|
||||
local RequestPageConversations = require(LuaChat.Actions.RequestPageConversations)
|
||||
|
||||
local Immutable = require(Modules.Common.Immutable)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == RequestPageConversations.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
pageConversationsIsFetching = true,
|
||||
})
|
||||
elseif action.type == ReceivedPageConversations.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
pageConversationsIsFetching = false,
|
||||
})
|
||||
elseif action.type == RequestLatestMessages.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
latestMessagesIsFetching = true,
|
||||
})
|
||||
elseif action.type == ReceivedLatestMessages.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
latestMessagesIsFetching = false,
|
||||
})
|
||||
elseif action.type == ReceivedOldestConversation.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
oldestConversationIsFetched = true,
|
||||
})
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
return function()
|
||||
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local ConversationsAsyncReducer = require(LuaChat.Reducers.ConversationsAsync)
|
||||
|
||||
local ReceivedLatestMessages = require(LuaChat.Actions.ReceivedLatestMessages)
|
||||
local ReceivedOldestConversation = require(LuaChat.Actions.ReceivedOldestConversation)
|
||||
local ReceivedPageConversations = require(LuaChat.Actions.ReceivedPageConversations)
|
||||
local RequestLatestMessages = require(LuaChat.Actions.RequestLatestMessages)
|
||||
local RequestPageConversations = require(LuaChat.Actions.RequestPageConversations)
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("RequestPageConversations", function()
|
||||
it("should set the async state to true", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
state = ConversationsAsyncReducer(state, RequestPageConversations())
|
||||
|
||||
expect(state.pageConversationsIsFetching).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedPageConversations", function()
|
||||
it("should set the async state to false", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
state = ConversationsAsyncReducer(state, ReceivedPageConversations())
|
||||
|
||||
expect(state.pageConversationsIsFetching).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("RequestLatestMessages", function()
|
||||
it("should set the async state to true", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
state = ConversationsAsyncReducer(state, RequestLatestMessages())
|
||||
|
||||
expect(state.latestMessagesIsFetching).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedLatestMessages", function()
|
||||
it("should set the async state to false", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
state = ConversationsAsyncReducer(state, ReceivedLatestMessages())
|
||||
|
||||
expect(state.latestMessagesIsFetching).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedOldestConversation", function()
|
||||
it("should set the oldestConversationIsFetched flag to true", function()
|
||||
local state = ConversationsAsyncReducer(nil, {})
|
||||
state = ConversationsAsyncReducer(state, ReceivedOldestConversation())
|
||||
|
||||
expect(state.oldestConversationIsFetched).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
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.Reducers.FriendCount)
|
||||
@@ -0,0 +1,18 @@
|
||||
return function()
|
||||
local LuaChat = script.Parent.Parent
|
||||
local FriendCount = require(script.Parent.FriendCount)
|
||||
local SetFriendCount = require(LuaChat.Actions.SetFriendCount)
|
||||
|
||||
it("should be zero by default", function()
|
||||
local state = FriendCount(nil, {})
|
||||
|
||||
expect(state).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should respond to SetFriendCount", function()
|
||||
local state = FriendCount(nil, {})
|
||||
state = FriendCount(state, SetFriendCount(520))
|
||||
|
||||
expect(state).to.equal(520)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local PopRoute = require(LuaChat.Actions.PopRoute)
|
||||
local RemoveRoute = require(LuaChat.Actions.RemoveRoute)
|
||||
local SetRoute = require(LuaChat.Actions.SetRoute)
|
||||
|
||||
local Immutable = require(Common.Immutable)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {
|
||||
current = {},
|
||||
history = {}
|
||||
}
|
||||
|
||||
if action.type == SetRoute.name then
|
||||
local current = state.current
|
||||
local history = state.history
|
||||
|
||||
local routeData = {
|
||||
intent = action.intent,
|
||||
popToIntent = action.popToIntent,
|
||||
parameters = action.parameters
|
||||
}
|
||||
|
||||
if action.popToIntent then
|
||||
local found = false
|
||||
for i = #history, 1, -1 do
|
||||
local loc = history[i]
|
||||
if loc.intent == action.popToIntent then
|
||||
history = Immutable.RemoveRangeFromList(history, i + 1, #history - i)
|
||||
current = history[#history]
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
warn("Could not pop to unavailable intent: " .. action.popToIntent)
|
||||
end
|
||||
end
|
||||
|
||||
if routeData.intent ~= nil then
|
||||
current = routeData
|
||||
history = Immutable.Append(history, routeData)
|
||||
end
|
||||
|
||||
return {
|
||||
current = current,
|
||||
history = history
|
||||
}
|
||||
|
||||
elseif action.type == PopRoute.name then
|
||||
local current
|
||||
local history = state.history
|
||||
|
||||
if #history <= 1 then
|
||||
return state
|
||||
end
|
||||
|
||||
history = Immutable.RemoveFromList(history, #history)
|
||||
current = history[#history]
|
||||
if not current then
|
||||
current = {}
|
||||
end
|
||||
|
||||
return {
|
||||
current = current,
|
||||
history = history
|
||||
}
|
||||
|
||||
elseif action.type == RemoveRoute.name then
|
||||
local intent = action.intent
|
||||
local history = state.history
|
||||
|
||||
for i = #history, 1, -1 do
|
||||
local loc = history[i]
|
||||
if loc.intent == intent then
|
||||
history = Immutable.RemoveFromList(history, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local current = history[#history] or {}
|
||||
|
||||
return {
|
||||
current = current,
|
||||
history = history
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,236 @@
|
||||
return function()
|
||||
local LuaChat = script.Parent.Parent
|
||||
local Location = require(script.Parent.Location)
|
||||
|
||||
local DialogInfo = require(LuaChat.DialogInfo)
|
||||
local Intent = DialogInfo.Intent
|
||||
|
||||
local PopRoute = require(LuaChat.Actions.PopRoute)
|
||||
local RemoveRoute = require(LuaChat.Actions.RemoveRoute)
|
||||
local SetRoute = require(LuaChat.Actions.SetRoute)
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = Location(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
expect(state.current).to.be.a("table")
|
||||
expect(state.history).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetRoute", function()
|
||||
it("should set route to ConversationHub", function()
|
||||
local intent = Intent.ConversationHub
|
||||
|
||||
local state = Location(nil, SetRoute(intent, {}))
|
||||
|
||||
expect(state.current.intent).to.equal(intent)
|
||||
end)
|
||||
|
||||
it("should set route to Conversation with correct conversationId", function()
|
||||
local intent = Intent.Conversation
|
||||
local conversationId = "testConvoId"
|
||||
|
||||
local state = Location(nil, SetRoute(
|
||||
intent,
|
||||
{
|
||||
conversationId = conversationId,
|
||||
}
|
||||
))
|
||||
|
||||
expect(state.current.intent).to.equal(intent)
|
||||
expect(state.current.parameters.conversationId).to.equal(conversationId)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("SetRoute with popToIntent", function()
|
||||
it("should pop to the right intent first and then add the new intent on top", function()
|
||||
local state = Location(nil, SetRoute(Intent.ConversationHub, {}))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId1",
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(Intent.NewChatGroup))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId2",
|
||||
}
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(4)
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId3",
|
||||
},
|
||||
Intent.ConversationHub
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(2)
|
||||
expect(state.history[1].intent).to.equal(Intent.ConversationHub)
|
||||
expect(state.current.parameters.conversationId).to.equal("testConvoId3")
|
||||
expect(state.history[#state.history].parameters.conversationId).to.equal("testConvoId3")
|
||||
end)
|
||||
it("should pop to the right intent and stop if the new intent is nil", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId1",
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(Intent.NewChatGroup))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId2",
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
nil,
|
||||
{
|
||||
conversationId = "testConvoId3",
|
||||
},
|
||||
Intent.NewChatGroup
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(3)
|
||||
expect(state.current.intent).to.equal(Intent.NewChatGroup)
|
||||
expect(state.history[#state.history].intent).to.equal(Intent.NewChatGroup)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("route history", function()
|
||||
it("should push history", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(1)
|
||||
end)
|
||||
|
||||
it("should push history twice and have correct number of history entries", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId",
|
||||
}
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(2)
|
||||
end)
|
||||
|
||||
it("should have current be equal to top of history", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
expect(state.history[1].intent).to.equal(state.current.intent)
|
||||
end)
|
||||
|
||||
it("should pop history", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId",
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, PopRoute())
|
||||
|
||||
expect(state.current.intent).to.equal(Intent.ConversationHub)
|
||||
expect(#state.history).to.equal(1)
|
||||
expect(state.history[1].intent).to.equal(state.current.intent)
|
||||
end)
|
||||
|
||||
it("should never pop routes where the history is empty", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId",
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, PopRoute())
|
||||
|
||||
expect(state.current.intent).to.equal(Intent.ConversationHub)
|
||||
expect(#state.history).to.equal(1)
|
||||
expect(state.history[1].intent).to.equal(state.current.intent)
|
||||
|
||||
state = Location(state, PopRoute())
|
||||
|
||||
expect(state.current.intent).to.equal(Intent.ConversationHub)
|
||||
expect(#state.history).to.equal(1)
|
||||
expect(state.history[1].intent).to.equal(state.current.intent)
|
||||
end)
|
||||
|
||||
it("should remove from history properly", function()
|
||||
local state = Location(nil, SetRoute(
|
||||
Intent.ConversationHub,
|
||||
{}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId1"
|
||||
}
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.NewChatGroup
|
||||
))
|
||||
|
||||
state = Location(state, SetRoute(
|
||||
Intent.Conversation,
|
||||
{
|
||||
conversationId = "testConvoId2"
|
||||
}
|
||||
))
|
||||
|
||||
expect(#state.history).to.equal(4)
|
||||
|
||||
state = Location(state, RemoveRoute(Intent.NewChatGroup))
|
||||
|
||||
expect(#state.history).to.equal(3)
|
||||
|
||||
state = Location(state, RemoveRoute(Intent.EditChatGroup))
|
||||
|
||||
expect(#state.history).to.equal(3)
|
||||
|
||||
state = Location(state, RemoveRoute(Intent.Conversation))
|
||||
|
||||
expect(state.current.intent).to.equal(Intent.Conversation)
|
||||
expect(state.current.parameters.conversationId).to.equal("testConvoId1")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local SetMostRecentlyPlayedGamesForUser = require(Actions.SetMostRecentlyPlayedGamesForUser)
|
||||
local SetMostRecentlyPlayedPlayableGameForUser = require(Actions.SetMostRecentlyPlayedPlayableGameForUser)
|
||||
|
||||
local Immutable = require(Common.Immutable)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == SetMostRecentlyPlayedGamesForUser.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
games = action.games
|
||||
})
|
||||
elseif action.type == SetMostRecentlyPlayedPlayableGameForUser.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
playableGamePlaceId = action.placeId,
|
||||
setPlayableGame = true
|
||||
})
|
||||
end
|
||||
|
||||
return state
|
||||
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.Reducers.PlaceInfos)
|
||||
@@ -0,0 +1,33 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local Immutable = require(Modules.Common.Immutable)
|
||||
|
||||
local RequestMultiplePlaceInfos = require(Actions.RequestMultiplePlaceInfos)
|
||||
local FailedToFetchMultiplePlaceInfos = require(Actions.FailedToFetchMultiplePlaceInfos)
|
||||
local ReceivedMultiplePlaceInfos = require(Actions.ReceivedMultiplePlaceInfos)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
if action.type == RequestMultiplePlaceInfos.name then
|
||||
local newFlags = {}
|
||||
for _, placeId in ipairs(action.placeIds) do
|
||||
newFlags[placeId] = true
|
||||
end
|
||||
return Immutable.JoinDictionaries(state, newFlags)
|
||||
elseif action.type == ReceivedMultiplePlaceInfos.name then
|
||||
local newFlags = {}
|
||||
for _, placeInfo in ipairs(action.placeInfos) do
|
||||
newFlags[placeInfo.placeId] = false
|
||||
end
|
||||
return Immutable.JoinDictionaries(state, newFlags)
|
||||
elseif action.type == FailedToFetchMultiplePlaceInfos.name then
|
||||
local newFlags = {}
|
||||
for _, placeId in ipairs(action.placeIds) do
|
||||
newFlags[placeId] = false
|
||||
end
|
||||
return Immutable.JoinDictionaries(state, newFlags)
|
||||
end
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local Immutable = require(Common.Immutable)
|
||||
local ReceivedPlaceThumbnail = require(LuaChat.Actions.ReceivedPlaceThumbnail)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
if action.type == ReceivedPlaceThumbnail.name then
|
||||
state = Immutable.Set(state, action.imageToken, action.thumbnail)
|
||||
end
|
||||
return state
|
||||
end
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ReceivedPlaceThumbnail = require(LuaChat.Actions.ReceivedPlaceThumbnail)
|
||||
local PlaceThumbnailsReducer = require(script.Parent.PlaceThumbnails)
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = PlaceThumbnailsReducer(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedPlaceThumbnail", function()
|
||||
it("should add place thumbnail to the store", function()
|
||||
local state = PlaceThumbnailsReducer(nil, {})
|
||||
|
||||
local returnedThumbnail = ReceivedPlaceThumbnail("imageToken", "thumbnail")
|
||||
state = PlaceThumbnailsReducer(state, returnedThumbnail)
|
||||
|
||||
expect(state["imageToken"]).to.equal("thumbnail")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Immutable = require(Modules.Common.Immutable)
|
||||
|
||||
local RequestPlaceThumbnail = require(Modules.LuaChat.Actions.RequestPlaceThumbnail)
|
||||
local ReceivedPlaceThumbnail = require(Modules.LuaChat.Actions.ReceivedPlaceThumbnail)
|
||||
local FailedToFetchPlaceThumbnail = require(Modules.LuaChat.Actions.FailedToFetchPlaceThumbnail)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
if action.type == RequestPlaceThumbnail.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
[action.imageToken] = true,
|
||||
})
|
||||
elseif action.type == ReceivedPlaceThumbnail.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
[action.imageToken] = false,
|
||||
})
|
||||
elseif action.type == FailedToFetchPlaceThumbnail.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
[action.imageToken] = false,
|
||||
})
|
||||
end
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,74 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local FailedToFetchMostRecentlyPlayedGames = require(Actions.FailedToFetchMostRecentlyPlayedGames)
|
||||
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 UnpinnedGame = require(Actions.UnpinnedGame)
|
||||
local UnpinningGame = require(Actions.UnpinningGame)
|
||||
|
||||
local Immutable = require(Common.Immutable)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {
|
||||
pinningGames = {},
|
||||
unPinningGames = {},
|
||||
}
|
||||
-- play together async
|
||||
if action.type == PinningGame.name then
|
||||
local newPinningGames = Immutable.Set(state.pinningGames, action.conversationId, true)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
pinningGames = newPinningGames;
|
||||
})
|
||||
elseif action.type == PinnedGame.name then
|
||||
local newPinningGames = Immutable.Set(state.pinningGames, action.conversationId, false)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
pinningGames = newPinningGames;
|
||||
})
|
||||
elseif action.type == GameFailedToPin.name then
|
||||
local newPinningGames = Immutable.Set(state.pinningGames, action.conversationId, false)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
pinningGames = newPinningGames;
|
||||
})
|
||||
elseif action.type == UnpinningGame.name then
|
||||
local newUnpinningGames = Immutable.Set(state.unPinningGames, action.conversationId, true)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
unPinningGames = newUnpinningGames;
|
||||
})
|
||||
elseif action.type == UnpinnedGame.name then
|
||||
local newUnpinningGames = Immutable.Set(state.unPinningGames, action.conversationId, false)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
unPinningGames = newUnpinningGames;
|
||||
})
|
||||
elseif action.type == GameFailedToUnpin.name then
|
||||
local newUnpinningGames = Immutable.Set(state.unPinningGames, action.conversationId, false)
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
unPinningGames = newUnpinningGames;
|
||||
})
|
||||
elseif action.type == FetchingMostRecentlyPlayedGames.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingMostRecentlyPlayedGames = true,
|
||||
fetchedMostRecentlyPlayedGames = false
|
||||
})
|
||||
elseif action.type == FetchedMostRecentlyPlayedGames.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingMostRecentlyPlayedGames = false,
|
||||
fetchedMostRecentlyPlayedGames = true,
|
||||
})
|
||||
elseif action.type == FailedToFetchMostRecentlyPlayedGames.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingMostRecentlyPlayedGames = false,
|
||||
fetchedMostRecentlyPlayedGames = false
|
||||
})
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
local Actions = LuaChat.Actions
|
||||
|
||||
local MockId = require(LuaApp.MockId)
|
||||
|
||||
local PlayTogetherAsync = require(script.Parent.PlayTogetherAsync)
|
||||
|
||||
local FailedToFetchMostRecentlyPlayedGames = require(Actions.FailedToFetchMostRecentlyPlayedGames)
|
||||
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 UnpinnedGame = require(Actions.UnpinnedGame)
|
||||
local UnpinningGame = require(Actions.UnpinningGame)
|
||||
|
||||
return function()
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
expect(state.pinningGames).to.be.a("table")
|
||||
expect(state.unPinningGames).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("PinningGame", function()
|
||||
it("should set the pinning game async state to true", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, PinningGame(testConversationId))
|
||||
|
||||
expect(state.pinningGames[testConversationId]).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("PinnedGame", function()
|
||||
it("should set the pinning game async state to false", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, PinnedGame(testConversationId))
|
||||
|
||||
expect(state.pinningGames[testConversationId]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("GameFailedToPin", function()
|
||||
it("should set the pinning game async state to false", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, GameFailedToPin(testConversationId))
|
||||
|
||||
expect(state.pinningGames[testConversationId]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("UnpinningGame", function()
|
||||
it("should set the unpinning game async state to true", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, UnpinningGame(testConversationId))
|
||||
|
||||
expect(state.unPinningGames[testConversationId]).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("UnpinnedGame", function()
|
||||
it("should set the unpinning game async state to false", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, UnpinnedGame(testConversationId))
|
||||
|
||||
expect(state.unPinningGames[testConversationId]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("GameFailedToUnpin", function()
|
||||
it("should set the unpinning game async state to false", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
local testConversationId = MockId()
|
||||
state = PlayTogetherAsync(state, GameFailedToUnpin(testConversationId))
|
||||
|
||||
expect(state.unPinningGames[testConversationId]).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
describe("FetchingMostRecentlyPlayedGames", function()
|
||||
it("should update fecth state of most recently played games", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
state = PlayTogetherAsync(state, FetchingMostRecentlyPlayedGames())
|
||||
|
||||
expect(state.fetchingMostRecentlyPlayedGames).to.equal(true)
|
||||
expect(state.fetchedMostRecentlyPlayedGames).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
describe("FetchedMostRecentlyPlayedGames", function()
|
||||
it("should update fecth state of most recently played games", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
state = PlayTogetherAsync(state, FetchedMostRecentlyPlayedGames())
|
||||
|
||||
expect(state.fetchingMostRecentlyPlayedGames).to.equal(false)
|
||||
expect(state.fetchedMostRecentlyPlayedGames).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
describe("FailedToFetchMostRecentlyPlayedGames", function()
|
||||
it("should update fecth state of most recently played games", function()
|
||||
local state = PlayTogetherAsync(nil, {})
|
||||
state = PlayTogetherAsync(state, FailedToFetchMostRecentlyPlayedGames())
|
||||
|
||||
expect(state.fetchingMostRecentlyPlayedGames).to.equal(false)
|
||||
expect(state.fetchedMostRecentlyPlayedGames).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Immutable = require(Common.Immutable)
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ShareGameToChatActions = LuaChat.Actions.ShareGameToChatFromChat
|
||||
|
||||
local FailedToFetchGamesBySort = require(ShareGameToChatActions.FailedToFetchGamesBySortShareGameToChatFromChat)
|
||||
local FailedToShareGameToChat = require(ShareGameToChatActions.FailedToShareGameToChatFromChat)
|
||||
local FetchedGamesBySort = require(ShareGameToChatActions.FetchedGamesBySortShareGameToChatFromChat)
|
||||
local FetchingGamesBySort = require(ShareGameToChatActions.FetchingGamesBySortShareGameToChatFromChat)
|
||||
local ResetShareGameToChatAsync = require(ShareGameToChatActions.ResetShareGameToChatFromChatAsync)
|
||||
local ResetShareGame = require(ShareGameToChatActions.ResetShareGameToChatFromChat)
|
||||
local SharedGameToChat = require(ShareGameToChatActions.SharedGameToChatFromChat)
|
||||
local SharingGameToChat = require(ShareGameToChatActions.SharingGameToChatFromChat)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {
|
||||
fetchingGamesBySort = {},
|
||||
fetchedGamesBySort = {},
|
||||
failedToFetchGamesBySort = {},
|
||||
}
|
||||
|
||||
if action.type == FetchingGamesBySort.name then
|
||||
local newFetchingGamesBySort = Immutable.Set(state.fetchingGamesBySort, action.gameSortName, true)
|
||||
local newFetchedGamesBySort = Immutable.Set(state.fetchedGamesBySort, action.gameSortName, false)
|
||||
local newFailedToFetchGamesBySort = Immutable.Set(state.failedToFetchGamesBySort, action.gameSortName, false)
|
||||
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingGamesBySort = newFetchingGamesBySort;
|
||||
fetchedGamesBySort = newFetchedGamesBySort;
|
||||
failedToFetchGamesBySort = newFailedToFetchGamesBySort;
|
||||
})
|
||||
elseif action.type == FetchedGamesBySort.name then
|
||||
local newFetchingGamesBySort = Immutable.Set(state.fetchingGamesBySort, action.gameSortName, false)
|
||||
local newFetchedGamesBySort = Immutable.Set(state.fetchedGamesBySort, action.gameSortName, true)
|
||||
local newFailedToFetchGamesBySort = Immutable.Set(state.failedToFetchGamesBySort, action.gameSortName, false)
|
||||
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingGamesBySort = newFetchingGamesBySort;
|
||||
fetchedGamesBySort = newFetchedGamesBySort;
|
||||
failedToFetchGamesBySort = newFailedToFetchGamesBySort;
|
||||
})
|
||||
elseif action.type == FailedToFetchGamesBySort.name then
|
||||
local newFetchingGamesBySort = Immutable.Set(state.fetchingGamesBySort, action.gameSortName, false)
|
||||
local newFetchedGamesBySort = Immutable.Set(state.fetchedGamesBySort, action.gameSortName, false)
|
||||
local newFailedToFetchGamesBySort = Immutable.Set(state.failedToFetchGamesBySort, action.gameSortName, true)
|
||||
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
fetchingGamesBySort = newFetchingGamesBySort;
|
||||
fetchedGamesBySort = newFetchedGamesBySort;
|
||||
failedToFetchGamesBySort = newFailedToFetchGamesBySort;
|
||||
})
|
||||
elseif action.type == ResetShareGameToChatAsync.name then
|
||||
return {
|
||||
fetchingGamesBySort = {},
|
||||
fetchedGamesBySort = {},
|
||||
failedToFetchGamesBySort = {},
|
||||
}
|
||||
elseif action.type == SharingGameToChat.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
sharingGame = true,
|
||||
sharedGame = false,
|
||||
})
|
||||
elseif action.type == SharedGameToChat.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
sharingGame = false,
|
||||
sharedGame = true,
|
||||
})
|
||||
elseif action.type == FailedToShareGameToChat.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
sharedGame = false,
|
||||
sharingGame = false,
|
||||
})
|
||||
elseif action.type == ResetShareGame.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
sharedGame = false,
|
||||
sharingGame = false,
|
||||
})
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Immutable = require(Common.Immutable)
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ShareGameToChatActions = LuaChat.Actions.ShareGameToChatFromChat
|
||||
|
||||
local AddGamesBySort = require(ShareGameToChatActions.AddGamesBySortShareGameToChatFromChat)
|
||||
local UpdateGameSortsTokens = require(ShareGameToChatActions.UpdateGameSortsTokensShareGameToChatFromChat)
|
||||
local ClearAllGamesInSorts = require(ShareGameToChatActions.ClearAllGamesInSortsShareGameToChatFromChat)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == AddGamesBySort.name then
|
||||
local sort = state[action.name] or {}
|
||||
local newSort = Immutable.JoinDictionaries(sort, {
|
||||
token = sort.token,
|
||||
tokenExpiry = sort.tokenExpiry,
|
||||
placeIds = action.placeIds
|
||||
})
|
||||
state = Immutable.Set(state, action.name, newSort)
|
||||
elseif action.type == UpdateGameSortsTokens.name then
|
||||
for _, gameSort in pairs(action.gameSorts) do
|
||||
local sort = state[gameSort.name] or {}
|
||||
local placeIds = state[gameSort.name] ~= nil and state[gameSort.name].placeIds or nil
|
||||
local newSort = Immutable.JoinDictionaries(sort, {
|
||||
token = gameSort.token,
|
||||
tokenExpiry = gameSort.tokenExpiryInSeconds + tick(),
|
||||
placeIds = placeIds
|
||||
})
|
||||
state = Immutable.Set(state, gameSort.name, newSort)
|
||||
end
|
||||
elseif action.type == ClearAllGamesInSorts.name then
|
||||
state = {}
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local Common = Modules.Common
|
||||
local Immutable = require(Common.Immutable)
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ShareGameToChatActions = LuaChat.Actions.ShareGameToChatFromChat
|
||||
|
||||
local AddGamesInformation = require(ShareGameToChatActions.AddGamesInformationShareGameToChatFromChat)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
if action.type == AddGamesInformation.name then
|
||||
local tmpTable = {}
|
||||
for _, gameInfo in pairs(action.games) do
|
||||
tmpTable[gameInfo.placeId] = gameInfo
|
||||
end
|
||||
state = Immutable.JoinDictionaries(state, tmpTable)
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,16 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local ShowToast = require(Modules.LuaChat.Actions.ShowToast)
|
||||
local ToastComplete = require(Modules.LuaChat.Actions.ToastComplete)
|
||||
|
||||
return function(state, action)
|
||||
state = state or nil
|
||||
|
||||
if action.type == ShowToast.name then
|
||||
state = action.toast
|
||||
elseif action.type == ToastComplete.name then
|
||||
state = nil
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
return function()
|
||||
local CoreGui = game:GetService("CoreGui")
|
||||
local Modules = CoreGui.RobloxGui.Modules
|
||||
local LuaChat = Modules.LuaChat
|
||||
local ShowToast = require(LuaChat.Actions.ShowToast)
|
||||
local ToastComplete = require(LuaChat.Actions.ToastComplete)
|
||||
local ToastReducer = require(script.Parent.Toast)
|
||||
local ToastModel = require(LuaChat.Models.ToastModel)
|
||||
describe("Action Toast", function()
|
||||
it("should return nil when passed nil", function()
|
||||
local state = ToastReducer(nil, {})
|
||||
expect(state).to.equal(nil)
|
||||
end)
|
||||
|
||||
it("Action ShowToast", function()
|
||||
local state = ToastReducer(nil, {})
|
||||
local myToast = ToastModel.new()
|
||||
state = ToastReducer(state, ShowToast(myToast))
|
||||
|
||||
expect(state).to.equal(myToast)
|
||||
end)
|
||||
|
||||
it("Action ToastComplete", function()
|
||||
local state = ToastReducer(nil, {})
|
||||
state = ToastReducer(state, ToastComplete())
|
||||
|
||||
expect(state).to.equal(nil)
|
||||
end)
|
||||
|
||||
it("ToastComplete should clear current toast", function()
|
||||
local state = ToastReducer(nil, {})
|
||||
local myToast = ToastModel.new()
|
||||
state = ToastReducer(state, ShowToast(myToast))
|
||||
|
||||
expect(state).to.equal(myToast)
|
||||
|
||||
state = ToastReducer(state, ToastComplete())
|
||||
|
||||
expect(state).to.equal(nil)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local ToggleChatPaused = require(Modules.LuaChat.Actions.ToggleChatPaused)
|
||||
|
||||
return function(state, action)
|
||||
state = state or false
|
||||
|
||||
if action.type == ToggleChatPaused.name then
|
||||
state = action.value
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
return function()
|
||||
local LuaChat = script.Parent.Parent
|
||||
local ToggleChatPaused = require(script.Parent.ToggleChatPaused)
|
||||
local ActionToggleChatPaused = require(LuaChat.Actions.ToggleChatPaused)
|
||||
|
||||
describe("Action ToggleChatPaused", function()
|
||||
it("sets the ToggleChatPaused flag", function()
|
||||
local state = ToggleChatPaused(nil, {})
|
||||
|
||||
expect(state).to.equal(false)
|
||||
|
||||
state = ToggleChatPaused(state, ActionToggleChatPaused(false))
|
||||
|
||||
expect(state).to.equal(false)
|
||||
|
||||
state = ToggleChatPaused(state, ActionToggleChatPaused(true))
|
||||
|
||||
expect(state).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local SetUnreadConversationCount = require(Modules.LuaChat.Actions.SetUnreadConversationCount)
|
||||
local IncrementUnreadConversationCount = require(Modules.LuaChat.Actions.IncrementUnreadConversationCount)
|
||||
local DecrementUnreadConversationCount = require(Modules.LuaChat.Actions.DecrementUnreadConversationCount)
|
||||
|
||||
return function(state, action)
|
||||
state = state or 0
|
||||
|
||||
if action.type == SetUnreadConversationCount.name then
|
||||
state = action.count
|
||||
elseif action.type == IncrementUnreadConversationCount.name then
|
||||
state = state + 1
|
||||
elseif action.type == DecrementUnreadConversationCount.name then
|
||||
state = state - 1
|
||||
end
|
||||
return state
|
||||
end
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
return function()
|
||||
local LuaChat = script.Parent.Parent
|
||||
local UnreadConversationCount = require(LuaChat.Reducers.UnreadConversationCount)
|
||||
local SetUnreadConversationCount = require(LuaChat.Actions.SetUnreadConversationCount)
|
||||
local IncrementUnreadConversationCount = require(LuaChat.Actions.IncrementUnreadConversationCount)
|
||||
local DecrementUnreadConversationCount = require(LuaChat.Actions.DecrementUnreadConversationCount)
|
||||
|
||||
describe("Action SetUnreadConversationCount", function()
|
||||
it("should set the value of UnreadConversationCount", function()
|
||||
local state = nil
|
||||
local action = SetUnreadConversationCount(5)
|
||||
|
||||
state = UnreadConversationCount(state, action)
|
||||
|
||||
expect(state).to.equal(5)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action IncrementUnreadConversationCount", function()
|
||||
it("should increment the value of UnreadConversationCount", function()
|
||||
local state = nil
|
||||
local action = SetUnreadConversationCount(5)
|
||||
|
||||
state = UnreadConversationCount(state, action)
|
||||
|
||||
action = IncrementUnreadConversationCount()
|
||||
|
||||
state = UnreadConversationCount(state, action)
|
||||
|
||||
expect(state).to.equal(6)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("Action DecrementUnreadConversationCount", function()
|
||||
it("should decrement the value of UnreadConversationCount", function()
|
||||
local state = nil
|
||||
local action = SetUnreadConversationCount(5)
|
||||
|
||||
state = UnreadConversationCount(state, action)
|
||||
|
||||
action = DecrementUnreadConversationCount()
|
||||
|
||||
state = UnreadConversationCount(state, action)
|
||||
|
||||
expect(state).to.equal(4)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local ReceivedAllFriends = require(Modules.LuaChat.Actions.ReceivedAllFriends)
|
||||
local ReceivedUserPresence = require(Modules.LuaChat.Actions.ReceivedUserPresence)
|
||||
local RequestAllFriends = require(Modules.LuaChat.Actions.RequestAllFriends)
|
||||
local RequestUserPresence = require(Modules.LuaChat.Actions.RequestUserPresence)
|
||||
|
||||
local Immutable = require(Modules.Common.Immutable)
|
||||
|
||||
return function(state, action)
|
||||
state = state or {}
|
||||
|
||||
if action.type == RequestAllFriends.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
allFriendsIsFetching = true,
|
||||
})
|
||||
elseif action.type == ReceivedAllFriends.name then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
allFriendsIsFetching = false,
|
||||
})
|
||||
elseif action.type == RequestUserPresence.name then
|
||||
local userAsync = state[action.userId] or {}
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
[action.userId] = Immutable.JoinDictionaries(userAsync, {
|
||||
presenceIsFetching = true,
|
||||
}),
|
||||
})
|
||||
elseif action.type == ReceivedUserPresence.name then
|
||||
local userAsync = state[action.userId]
|
||||
if userAsync then
|
||||
return Immutable.JoinDictionaries(state, {
|
||||
[action.userId] = Immutable.JoinDictionaries(userAsync, {
|
||||
presenceIsFetching = false,
|
||||
}),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return state
|
||||
end
|
||||
@@ -0,0 +1,59 @@
|
||||
return function()
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local LuaApp = Modules.LuaApp
|
||||
local LuaChat = Modules.LuaChat
|
||||
|
||||
local UsersAsyncReducer = require(script.Parent.UsersAsync)
|
||||
local User = require(LuaApp.Models.User)
|
||||
|
||||
local ReceivedAllFriends = require(LuaChat.Actions.ReceivedAllFriends)
|
||||
local ReceivedUserPresence = require(LuaChat.Actions.ReceivedUserPresence)
|
||||
local RequestAllFriends = require(LuaChat.Actions.RequestAllFriends)
|
||||
local RequestUserPresence = require(LuaChat.Actions.RequestUserPresence)
|
||||
|
||||
describe("initial state", function()
|
||||
it("should return an initial table when passed nil", function()
|
||||
local state = UsersAsyncReducer(nil, {})
|
||||
expect(state).to.be.a("table")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("RequestAllFriends", function()
|
||||
it("should set the async state to true", function()
|
||||
local state = UsersAsyncReducer(nil, {})
|
||||
state = UsersAsyncReducer(state, RequestAllFriends())
|
||||
|
||||
expect(state.allFriendsIsFetching).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedAllFriends", function()
|
||||
it("should set the async state to false", function()
|
||||
local state = UsersAsyncReducer(nil, {})
|
||||
state = UsersAsyncReducer(state, ReceivedAllFriends())
|
||||
|
||||
expect(state.allFriendsIsFetching).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("RequestUserPresence", function()
|
||||
it("should set the async state to true", function()
|
||||
local user = User.mock()
|
||||
local state = UsersAsyncReducer(nil, {})
|
||||
state = UsersAsyncReducer(state, RequestUserPresence(user.id))
|
||||
|
||||
expect(state[user.id].presenceIsFetching).to.equal(true)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("ReceivedUserPresence", function()
|
||||
it("should set the async state to false", function()
|
||||
local user = User.mock()
|
||||
local state = UsersAsyncReducer({[user.id] = {presenceIsFetching = true}}, {})
|
||||
state = UsersAsyncReducer(state, ReceivedUserPresence(user.id))
|
||||
|
||||
expect(state[user.id].presenceIsFetching).to.equal(false)
|
||||
end)
|
||||
end)
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user