Clients/Client2018/content/internal/AppShell/Modules/Shell/FriendsView.lua

204 lines
7.2 KiB
Lua

--[[
// FriendsView.lua
// Creates a view for the users friends.
// Handles user input, updating view
TODO:
Connect selected/deselected to change color
]]
local CoreGui = game:GetService("CoreGui")
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")
local ShellModules = Modules:FindFirstChild("Shell")
local PlatformService = nil
pcall(function() PlatformService = game:GetService('PlatformService') end)
local FriendsData = require(ShellModules:FindFirstChild('FriendsData'))
local FriendPresenceItem = require(ShellModules:FindFirstChild('FriendPresenceItem'))
local SideBarModule = require(ShellModules:FindFirstChild('SideBar'))
local Strings = require(ShellModules:FindFirstChild('LocalizedStrings'))
local GameJoinModule = require(ShellModules:FindFirstChild('GameJoin'))
local Errors = require(ShellModules:FindFirstChild('Errors'))
local ErrorOverlayModule = require(ShellModules:FindFirstChild('ErrorOverlay'))
local EventHub = require(ShellModules:FindFirstChild('EventHub'))
local ScreenManager = require(ShellModules:FindFirstChild('ScreenManager'))
local Analytics = require(ShellModules:FindFirstChild('Analytics'))
local Utility = require(ShellModules:FindFirstChild('Utility'))
local XboxRecommendedPeople = settings():GetFFlag("XboxRecommendedPeople2")
local SIDE_BAR_ITEMS = {
JoinGame = Strings:LocalizedString("JoinGameWord");
ViewDetails = Strings:LocalizedString("ViewGameDetailsWord");
ViewProfile = Strings:LocalizedString("ViewGamerCardWord");
EmptyFriendSideBar = Strings:LocalizedString("EmptyFriendSideBarWord");
}
-- side bar is shared between all views
local SideBar = SideBarModule()
local function setPresenceData(item, data)
item:SetDisplay(data)
end
-- viewGridContainer - ScrollingGrid
-- friendData - FriendsData
-- updateFunc - function that will be called when FriendData update
local createFriendsView = function(viewGridContainer, friendsData, updateFunc)
local this = {}
-- map of userId to presenceItem, for dynamic scrolling grid, we generate
-- the presenceItem for the user until the user's grid item is shown on screen
local presenceItems = {}
local presenceItemDirty = {}
local presenceItemToSidebarEvent = {}
local currentFriendsData = nil
local isNotConsole = UserSettings().GameSettings:InStudioMode() or game:GetService('UserInputService'):GetPlatform() == Enum.Platform.Windows
local function connectSideBar(item, data)
Utility.DisconnectEvent(presenceItemToSidebarEvent[item])
local container = item:GetContainer()
presenceItemToSidebarEvent[item] = container.MouseButton1Click:connect(function()
if data then
-- rebuild side bar based on current data
SideBar:RemoveAllItems()
function SideBar:GetAnalyticsInfo()
return {[Analytics.WidgetNames('WidgetId')] = "FriendsSideBar"}
end
if isNotConsole or XboxRecommendedPeople then
local emptySideBar = true
if data.robloxStatus == "InGame" then
local placeId = data.placeId
local lastLocation = data.lastLocation
local robloxuid = data.robloxuid
SideBar:AddItem(SIDE_BAR_ITEMS.JoinGame, function()
GameJoinModule:StartGame(GameJoinModule.JoinType.Follow, robloxuid)
end)
SideBar:AddItem(SIDE_BAR_ITEMS.ViewDetails, function()
-- pass nil for iconId, gameDetail will fetch
EventHub:dispatchEvent(EventHub.Notifications["OpenGameDetail"], placeId, lastLocation, nil)
end)
emptySideBar = false
end
if data.xuid and #data.xuid > 0 and PlatformService then
local xuid = data.xuid
SideBar:AddItem(SIDE_BAR_ITEMS.ViewProfile, function()
local success, result = pcall(function()
PlatformService:PopupProfileUI(Enum.UserInputType.Gamepad1, xuid)
end)
-- NOTE: This will try to pop up the xbox system gamer card, failure will be handled
-- by the xbox.
if not success then
Utility.DebugLog("PlatformService:PopupProfileUI failed because,", result)
end
end)
emptySideBar = false
end
if emptySideBar then
SideBar:SetText(SIDE_BAR_ITEMS.EmptyFriendSideBar)
end
else
local inGame = data["PlaceId"] ~= nil
if inGame and not data["IsPrivateSession"] then
SideBar:AddItem(SIDE_BAR_ITEMS.JoinGame, function()
GameJoinModule:StartGame(GameJoinModule.JoinType.Follow, data["robloxuid"])
end)
SideBar:AddItem(SIDE_BAR_ITEMS.ViewDetails, function()
-- pass nil for iconId, gameDetail will fetch
EventHub:dispatchEvent(EventHub.Notifications["OpenGameDetail"], data["PlaceId"], data["LastLocation"], nil)
end)
end
SideBar:AddItem(SIDE_BAR_ITEMS.ViewProfile, function()
if PlatformService and data["xuid"] then
local success, result = pcall(function()
PlatformService:PopupProfileUI(Enum.UserInputType.Gamepad1, data["xuid"])
end)
-- NOTE: This will try to pop up the xbox system gamer card, failure will be handled
-- by the xbox.
if not success then
Utility.DebugLog("PlatformService:PopupProfileUI failed because,", result)
end
end
end)
end
ScreenManager:OpenScreen(SideBar, false)
else
ScreenManager:OpenScreen(ErrorOverlayModule(Errors.Default), false)
end
end)
end
local function getPresenceItemByIndex(i)
local data = currentFriendsData[i]
if data then
local idStr = tostring(data.xuid and data.xuid or data["robloxuid"])
if isNotConsole or XboxRecommendedPeople then
local xuid = data.xuid or ""
local robloxuid = data.robloxuid or ""
idStr = tostring(xuid.."#"..robloxuid)
end
local presenceItem = presenceItems[idStr]
if presenceItem == nil then
presenceItem = FriendPresenceItem(UDim2.new(0, 446, 0, 114), idStr)
presenceItemDirty[idStr] = true
presenceItems[idStr] = presenceItem
end
if presenceItemDirty[idStr] then
setPresenceData(presenceItem, data)
connectSideBar(presenceItem, data)
presenceItemDirty[idStr] = nil
end
return presenceItem:GetContainer()
end
end
local function onFriendsUpdated(newFriendsData)
-- map of valid userIds to bool
local validEntries = {}
currentFriendsData = newFriendsData
for i = 1, #currentFriendsData do
local data = currentFriendsData[i]
if data then
local idStr = tostring(data.xuid and data.xuid or data["robloxuid"])
if XboxRecommendedPeople then
local xuid = data.xuid or ""
local robloxuid = data.robloxuid or ""
idStr = tostring(xuid.."#"..robloxuid)
if data.isUpdated then
presenceItemDirty[idStr] = true
end
end
validEntries[idStr] = true
end
end
-- remove items if needed
for idStr, presenceItem in pairs(presenceItems) do
if not validEntries[idStr] then
presenceItemDirty[idStr] = true
presenceItem:Destroy()
presenceItems[idStr] = nil
end
end
--Update scrolling grid with new list
viewGridContainer:SetItemCallback(getPresenceItemByIndex)
viewGridContainer:RecalcLayout(#currentFriendsData)
if updateFunc then
updateFunc(#currentFriendsData)
end
end
onFriendsUpdated(friendsData)
FriendsData.ConnectUpdateEvent(onFriendsUpdated)
function this:GetDefaultFocusItem()
return viewGridContainer:GetSelectableItem()
end
return this
end
return createFriendsView