204 lines
7.2 KiB
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
|