mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
205 lines
6.6 KiB
Lua
205 lines
6.6 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 PlatformService = nil
|
|
pcall(function() PlatformService = game:GetService('PlatformService') end)
|
|
local UserInputService = game:GetService('UserInputService')
|
|
local GuiService = game:GetService('GuiService')
|
|
|
|
local FriendsData = require(Modules:FindFirstChild('FriendsData'))
|
|
local FriendPresenceItem = require(Modules:FindFirstChild('FriendPresenceItem'))
|
|
local SideBarModule = require(Modules:FindFirstChild('SideBar'))
|
|
local Strings = require(Modules:FindFirstChild('LocalizedStrings'))
|
|
local Utility = require(Modules:FindFirstChild('Utility'))
|
|
local GameJoinModule = require(Modules:FindFirstChild('GameJoin'))
|
|
local Errors = require(Modules:FindFirstChild('Errors'))
|
|
local ErrorOverlayModule = require(Modules:FindFirstChild('ErrorOverlay'))
|
|
local EventHub = require(Modules:FindFirstChild('EventHub'))
|
|
local ScreenManager = require(Modules:FindFirstChild('ScreenManager'))
|
|
|
|
-- Array of tables
|
|
-- see FriendsData - fetchXboxFriends() for full documentation
|
|
local myFriendsData = nil
|
|
|
|
local FOLLOW_MODE = 2
|
|
|
|
local SIDE_BAR_ITEMS = {
|
|
JoinGame = string.upper(Strings:LocalizedString("JoinGameWord"));
|
|
ViewDetails = string.upper(Strings:LocalizedString("ViewGameDetailsWord"));
|
|
ViewProfile = string.upper(Strings:LocalizedString("ViewGamerCardWord"));
|
|
}
|
|
|
|
-- side bar is shared between all views
|
|
local SideBar = SideBarModule()
|
|
|
|
local function setPresenceData(item, data)
|
|
if UserSettings().GameSettings:InStudioMode() then
|
|
item:SetAvatarImage(data.UserId)
|
|
item:SetNameText(data.Name)
|
|
item:SetPresence(data.LastLocation, data.PlaceId ~= nil)
|
|
elseif UserInputService:GetPlatform() == Enum.Platform.XBoxOne then
|
|
local rbxuid = data["robloxuid"]
|
|
item:SetAvatarImage(rbxuid)
|
|
item:SetNameText(data["display"])
|
|
if data["PlaceId"] and data["LastLocation"] then
|
|
item:SetPresence(data["LastLocation"], true)
|
|
elseif data["rich"] then
|
|
local richTbl = data["rich"]
|
|
local presence = richTbl[#richTbl]
|
|
item:SetPresence(presence["title"], false)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- viewGridContainer - ScrollingGrid
|
|
-- friendData - FriendsData
|
|
-- sizeConstraint - limit view to this many items
|
|
-- updateFunc - function that will be called when FriendData update
|
|
local createFriendsView = function(viewGridContainer, friendsData, sizeConstraint, updateFunc)
|
|
local this = {}
|
|
|
|
-- map of userId to presenceItem
|
|
local presenceItems = {}
|
|
local selectedItemOnFocus = nil
|
|
local guiObjectToSortIndex = {}
|
|
local presenceItemToData = {}
|
|
|
|
local count = #friendsData
|
|
if sizeConstraint then
|
|
count = math.min(count, sizeConstraint)
|
|
end
|
|
|
|
local function connectSideBar(item)
|
|
local container = item:GetContainer()
|
|
container.MouseButton1Click:connect(function()
|
|
local data = presenceItemToData[item]
|
|
if data then
|
|
-- rebuild side bar based on current data
|
|
SideBar:RemoveAllItems()
|
|
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
|
|
print("PlatformService:PopupProfileUI failed because,", result)
|
|
end
|
|
end
|
|
end)
|
|
ScreenManager:OpenScreen(SideBar, false)
|
|
else
|
|
ScreenManager:OpenScreen(ErrorOverlayModule(Errors.Default), false)
|
|
end
|
|
end)
|
|
end
|
|
|
|
-- initialize view
|
|
for i = 1, count do
|
|
local data = friendsData[i]
|
|
if data then
|
|
local idStr = tostring(data.UserId or data["robloxuid"])
|
|
local presenceItem = FriendPresenceItem(UDim2.new(0, 446, 0, 114), idStr)
|
|
presenceItems[idStr] = presenceItem
|
|
presenceItemToData[presenceItem] = data
|
|
viewGridContainer:AddItem(presenceItem:GetContainer())
|
|
setPresenceData(presenceItem, data)
|
|
connectSideBar(presenceItem)
|
|
if not selectedItemOnFocus then
|
|
selectedItemOnFocus = presenceItem:GetContainer()
|
|
end
|
|
guiObjectToSortIndex[presenceItem:GetContainer()] = i
|
|
end
|
|
end
|
|
|
|
local function onFriendsUpdated(newFriendsData)
|
|
local size = #newFriendsData
|
|
if sizeConstraint then
|
|
size = math.min(size, sizeConstraint)
|
|
end
|
|
|
|
-- map of valid userIds to bool
|
|
local validEntries = {}
|
|
|
|
-- a,b are guiObjects
|
|
local function sortGridItems(a, b)
|
|
if guiObjectToSortIndex[a] and guiObjectToSortIndex[b] then
|
|
return guiObjectToSortIndex[a] < guiObjectToSortIndex[b]
|
|
end
|
|
if guiObjectToSortIndex[a] then return true end
|
|
if guiObjectToSortIndex[b] then return false end
|
|
return a.Name < b.Name
|
|
end
|
|
|
|
-- refresh view
|
|
for i = 1, size do
|
|
local data = newFriendsData[i]
|
|
if data then
|
|
local idStr = tostring(data.UserId or data["robloxuid"])
|
|
local presenceItem = presenceItems[idStr]
|
|
if not presenceItem then
|
|
presenceItem = FriendPresenceItem(UDim2.new(0, 446, 0, 114), idStr)
|
|
presenceItems[idStr] = presenceItem
|
|
viewGridContainer:AddItem(presenceItem:GetContainer())
|
|
connectSideBar(presenceItem)
|
|
end
|
|
presenceItemToData[presenceItem] = data
|
|
setPresenceData(presenceItem, data)
|
|
validEntries[idStr] = true
|
|
guiObjectToSortIndex[presenceItem:GetContainer()] = i
|
|
if i == 1 then
|
|
selectedItemOnFocus = presenceItem:GetContainer()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- remove items if needed
|
|
for userId,presenceItem in pairs(presenceItems) do
|
|
if not validEntries[userId] then
|
|
local container = presenceItem:GetContainer()
|
|
guiObjectToSortIndex[container] = nil
|
|
viewGridContainer:RemoveItem(container)
|
|
presenceItems[userId] = nil
|
|
presenceItem:Destroy()
|
|
presenceItem = nil
|
|
end
|
|
end
|
|
|
|
viewGridContainer:SortItems(sortGridItems)
|
|
|
|
if updateFunc then
|
|
updateFunc(#newFriendsData)
|
|
end
|
|
end
|
|
|
|
FriendsData.ConnectUpdateEvent(onFriendsUpdated)
|
|
|
|
function this:GetDefaultFocusItem()
|
|
return selectedItemOnFocus
|
|
end
|
|
|
|
return this
|
|
end
|
|
|
|
return createFriendsView
|