add gs
This commit is contained in:
+240
@@ -0,0 +1,240 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local HttpService = game:GetService("HttpService")
|
||||
local PlatformService = nil
|
||||
pcall(function() PlatformService = game:GetService("PlatformService") end)
|
||||
local Roact = require(Modules.Common.Roact)
|
||||
|
||||
local Components = Modules.Shell.Components
|
||||
local PresenceCard = require(Components.Social.PresenceCard)
|
||||
local WindowedScrollingFrame = require(Components.Common.WindowedScrollingFrame)
|
||||
local Immutable = require(Modules.Common.Immutable)
|
||||
local Spinner = require(Components.Common.Spinner)
|
||||
local SideBarComponent = require(Components.Common.SideBar)
|
||||
local Utility = require(Modules.Shell.Utility)
|
||||
local EventHub = require(Modules.Shell.EventHub)
|
||||
local GameJoinModule = require(Modules.Shell.GameJoin)
|
||||
local Strings = require(Modules.Shell.LocalizedStrings)
|
||||
local SoundManager = require(Modules.Shell.SoundManager)
|
||||
local RedirectComponent = require(Modules.Shell.Components.Common.RedirectComponent)
|
||||
local UserThumbnailLoader = require(Components.Common.UserThumbnailLoader)
|
||||
|
||||
local SIDE_BAR_ITEMS = {
|
||||
JoinGame = Strings:LocalizedString("JoinGameWord"),
|
||||
ViewDetails = Strings:LocalizedString("ViewGameDetailsWord"),
|
||||
ViewProfile = Strings:LocalizedString("ViewGamerCardWord"),
|
||||
EmptyFriendSideBar = Strings:LocalizedString("EmptyFriendSideBarWord"),
|
||||
}
|
||||
|
||||
local FriendsScrollingView = Roact.PureComponent:extend("FriendsScrollingView")
|
||||
|
||||
function FriendsScrollingView:init()
|
||||
self.state = {
|
||||
sideBarInFocus = false,
|
||||
sideBarShow = false,
|
||||
currentSelectedIndex = 1,
|
||||
}
|
||||
|
||||
self.onSideBarClose = function()
|
||||
self:setState({
|
||||
sideBarInFocus = false,
|
||||
sideBarShow = false,
|
||||
})
|
||||
end
|
||||
self.onSideBarOpen = function(data)
|
||||
Utility.SetSelectedCoreObject(nil)
|
||||
self:setState({
|
||||
sideBarInFocus = true,
|
||||
sideBarShow = true,
|
||||
})
|
||||
end
|
||||
|
||||
self.groupKey = HttpService:GenerateGUID(false)
|
||||
end
|
||||
|
||||
function FriendsScrollingView:render()
|
||||
local props = self.props
|
||||
local friendsData = props.friendsData
|
||||
local initialized = props.initialized
|
||||
local actionPriority = self.props.actionPriority or 0
|
||||
|
||||
local hide = props.hide
|
||||
local inFocus = props.inFocus
|
||||
local sideBarInFocus = false
|
||||
local friendsScrollingFrameInFocus = false
|
||||
|
||||
local children = {}
|
||||
if not hide and inFocus then
|
||||
sideBarInFocus = self.state.sideBarShow and self.state.sideBarInFocus
|
||||
if not sideBarInFocus and #friendsData > 0 then
|
||||
friendsScrollingFrameInFocus = true
|
||||
end
|
||||
end
|
||||
|
||||
if initialized and friendsData then
|
||||
if #friendsData > 0 then
|
||||
local itemSize = Vector2.new(440, 120)
|
||||
local itemsPaddingOffset = 20
|
||||
local itemTotalSizeY = itemSize.Y + itemsPaddingOffset
|
||||
local itemsCount = math.floor(self.props.size.Y.Offset / itemTotalSizeY)
|
||||
assert(itemsCount ~= 0, "The scrolling window is too small to accommodate any presence card.")
|
||||
--We should have at least two items to ensure we can always select the top second item
|
||||
--while keep the top first item fully in view.
|
||||
--If the window is too small, we will always select the top first item.
|
||||
local itemOffsetStart = itemsCount > 2 and itemTotalSizeY or 0
|
||||
--This make sure when we scroll down the top card won't be clipped
|
||||
local itemOffsetEnd = self.props.size.Y.Offset - itemsCount * itemTotalSizeY + itemsPaddingOffset
|
||||
children.FriendsScrollingFrame = Roact.createElement(WindowedScrollingFrame, {
|
||||
items = friendsData,
|
||||
itemSize = itemSize,
|
||||
itemsPaddingOffset = itemsPaddingOffset,
|
||||
itemOffsetStart = itemOffsetStart,
|
||||
itemOffsetEnd = itemOffsetEnd,
|
||||
scrollingDirection = Enum.ScrollingDirection.Y,
|
||||
inFocus = friendsScrollingFrameInFocus,
|
||||
renderItem = function(data, index)
|
||||
local presenceCardProps = Immutable.JoinDictionaries(data, {
|
||||
layoutOrder = index,
|
||||
size = UDim2.new(0, itemSize.X, 0, itemSize.Y),
|
||||
focused = inFocus and self.state.currentSelectedIndex == index,
|
||||
selected = friendsScrollingFrameInFocus and self.state.currentSelectedIndex == index,
|
||||
})
|
||||
--Set up callbacks
|
||||
presenceCardProps.onActivated = function(bt)
|
||||
SoundManager:Play("SideMenuSlideIn")
|
||||
self.onSideBarOpen()
|
||||
end
|
||||
presenceCardProps.onSelectionGained = function()
|
||||
if self.state.currentSelectedIndex ~= index then
|
||||
self:setState({
|
||||
currentSelectedIndex = index,
|
||||
})
|
||||
end
|
||||
end
|
||||
return Roact.createElement(PresenceCard, presenceCardProps)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
local data = friendsData[self.state.currentSelectedIndex]
|
||||
if inFocus and data and data.robloxuid then
|
||||
children.ProfileImage = Roact.createElement(UserThumbnailLoader, {
|
||||
rbxuid = data.robloxuid,
|
||||
thumbnailType = Enum.ThumbnailType.AvatarThumbnail,
|
||||
thumbnailSize = Enum.ThumbnailSize.Size352x352,
|
||||
position = UDim2.new(1, 101, 0, 0),
|
||||
size = UDim2.new(0, 680, 0, 680),
|
||||
backgroundTransparency = 1,
|
||||
showSpinner = true
|
||||
})
|
||||
end
|
||||
|
||||
if self.state.sideBarShow and data then
|
||||
local sideBarButtons = {}
|
||||
if data.robloxuid and data.robloxuid > 0 and data.robloxStatus == "InGame" then
|
||||
local placeId = data.placeId
|
||||
local lastLocation = data.lastLocation
|
||||
local robloxuid = data.robloxuid
|
||||
table.insert(sideBarButtons, {
|
||||
text = SIDE_BAR_ITEMS.JoinGame,
|
||||
callback = function()
|
||||
GameJoinModule:StartGame(GameJoinModule.JoinType.Follow, robloxuid)
|
||||
end
|
||||
})
|
||||
table.insert(sideBarButtons, {
|
||||
text = SIDE_BAR_ITEMS.ViewDetails,
|
||||
callback = function()
|
||||
EventHub:dispatchEvent(EventHub.Notifications["OpenGameDetail"], placeId, lastLocation, nil)
|
||||
end
|
||||
})
|
||||
end
|
||||
if data.xuid and #data.xuid > 0 and PlatformService then
|
||||
local xuid = data.xuid
|
||||
table.insert(sideBarButtons, {
|
||||
text = SIDE_BAR_ITEMS.ViewProfile,
|
||||
callback = function()
|
||||
-- NOTE: This will try to pop up the xbox system gamer card, failure will be handled by the xbox.
|
||||
pcall(function()
|
||||
PlatformService:PopupProfileUI(Enum.UserInputType.Gamepad1, xuid)
|
||||
end)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
local sideBarText = nil
|
||||
if #sideBarButtons == 0 then
|
||||
sideBarText = SIDE_BAR_ITEMS.EmptyFriendSideBar
|
||||
sideBarButtons = nil
|
||||
end
|
||||
children.SideBar = Roact.createElement(SideBarComponent, {
|
||||
actionPriority = actionPriority + 1,
|
||||
text = sideBarText,
|
||||
buttons = sideBarButtons,
|
||||
inFocus = sideBarInFocus,
|
||||
onClose = self.onSideBarClose,
|
||||
onRemoveFocus = function()
|
||||
self:setState({
|
||||
sideBarInFocus = false
|
||||
})
|
||||
end,
|
||||
})
|
||||
end
|
||||
else
|
||||
children.NoFriendsView = props.noFriendsView
|
||||
end
|
||||
else
|
||||
children.Spinner = Roact.createElement(Spinner)
|
||||
end
|
||||
|
||||
children.NavObj = Roact.createElement(RedirectComponent, {
|
||||
ActionPriority = actionPriority,
|
||||
Key = self.groupKey,
|
||||
InFocus = inFocus,
|
||||
RedirectBack = props.redirectBack,
|
||||
RedirectLeft = props.redirectLeft,
|
||||
RedirectRight = props.redirectRight,
|
||||
RedirectUp = props.redirectUp,
|
||||
RedirectDown = props.redirectDown,
|
||||
})
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
BackgroundTransparency = 1,
|
||||
Size = self.props.size,
|
||||
Position = self.props.position,
|
||||
[Roact.Ref] = function(rbx)
|
||||
self.ref = rbx
|
||||
end,
|
||||
Visible = not hide,
|
||||
}, children)
|
||||
end
|
||||
|
||||
|
||||
function FriendsScrollingView:didMount()
|
||||
delay(0, function()
|
||||
if self.props.hide == false and self.props.inFocus then
|
||||
if self.ref ~= nil then
|
||||
Utility.RemoveSelectionGroup(self.groupKey)
|
||||
Utility.AddSelectionParent(self.groupKey, self.ref)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function FriendsScrollingView:didUpdate(previousProps, previousState)
|
||||
if self.props.hide or self.props.inFocus == previousProps.inFocus then
|
||||
return
|
||||
end
|
||||
if self.props.inFocus then
|
||||
if self.ref then
|
||||
Utility.RemoveSelectionGroup(self.groupKey)
|
||||
Utility.AddSelectionParent(self.groupKey, self.ref)
|
||||
end
|
||||
else
|
||||
Utility.RemoveSelectionGroup(self.groupKey)
|
||||
end
|
||||
end
|
||||
|
||||
function FriendsScrollingView:willUnmount()
|
||||
Utility.RemoveSelectionGroup(self.groupKey)
|
||||
end
|
||||
|
||||
return FriendsScrollingView
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local Roact = require(Modules.Common.Roact)
|
||||
local memoize = require(Modules.Common.memoize)
|
||||
local RoactRodux = require(Modules.Common.RoactRodux)
|
||||
local CategoryMenuView = require(Modules.Shell.Components.Common.CategoryMenuView)
|
||||
local SplitViewLR = require(Modules.Shell.Components.Common.SplitViewLR)
|
||||
local Utility = require(Modules.Shell.Utility)
|
||||
local SoundManager = require(Modules.Shell.SoundManager)
|
||||
local Strings = require(Modules.Shell.LocalizedStrings)
|
||||
local FriendsScrollingView = require(Modules.Shell.Components.Social.FriendsScrollingView)
|
||||
local NoFriendsView = require(Modules.Shell.Components.Social.NoFriendsView)
|
||||
local PageKeys = require(Modules.Shell.PageKeys)
|
||||
|
||||
local FriendsView = Roact.PureComponent:extend("FriendsView")
|
||||
|
||||
local MenuKey = PageKeys.FriendCategories.Key
|
||||
local FriendCategoriesKeys = {
|
||||
OnlineFriends = PageKeys.FriendCategories.OnlineFriends.Key,
|
||||
AllFriends = PageKeys.FriendCategories.AllFriends.Key,
|
||||
}
|
||||
local FriendCategories = {}
|
||||
FriendCategories[FriendCategoriesKeys.OnlineFriends] = { Order = 1, StringKey = "OnlineWord" }
|
||||
FriendCategories[FriendCategoriesKeys.AllFriends] = { Order = 2, StringKey = "AllWord" }
|
||||
|
||||
local function onSelectSection(self, key)
|
||||
if self.state.currentPage ~= key then
|
||||
self:setState({
|
||||
currentPage = key,
|
||||
selectedPage = MenuKey,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function FriendsView:init()
|
||||
self.selectedPage = MenuKey
|
||||
self.onSelectionGained = function(key)
|
||||
onSelectSection(self,key)
|
||||
end
|
||||
|
||||
self.state = {
|
||||
currentPage = FriendCategoriesKeys.OnlineFriends,
|
||||
selectedPage = MenuKey,
|
||||
}
|
||||
|
||||
self.enterSection = function()
|
||||
SoundManager:Play("OverlayOpen")
|
||||
Utility.SetSelectedCoreObject(nil)
|
||||
self:setState({
|
||||
selectedPage = self.state.currentPage,
|
||||
})
|
||||
end
|
||||
self.exitSection = function()
|
||||
SoundManager:Play("PopUp")
|
||||
self:setState({
|
||||
selectedPage = MenuKey,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function FriendsView:render()
|
||||
local actionPriority = self.props.actionPriority or 0
|
||||
local currentPage = self.state.currentPage
|
||||
local friendsViewInFocus = self.props.inFocus
|
||||
local friendsViewHide = self.props.hide
|
||||
local friendCategoriesMenuInFocus = false
|
||||
local friendPagesInFocus = false
|
||||
if not friendsViewHide and friendsViewInFocus then
|
||||
if self.state.selectedPage == MenuKey then
|
||||
friendCategoriesMenuInFocus = true
|
||||
end
|
||||
if self.state.selectedPage ~= MenuKey then
|
||||
friendPagesInFocus = true
|
||||
end
|
||||
end
|
||||
|
||||
local enterSection = self.enterSection
|
||||
if currentPage == PageKeys.FriendCategories.OnlineFriends.Key and #self.props.onlineFriendsData == 0 then
|
||||
enterSection = nil
|
||||
elseif currentPage == PageKeys.FriendCategories.AllFriends.Key and #self.props.allFriendsData == 0 then
|
||||
enterSection = nil
|
||||
end
|
||||
|
||||
return Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, -58, 1, 0),
|
||||
Position = UDim2.new(0, 58, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
},{
|
||||
Mainview = Roact.createElement(SplitViewLR, {
|
||||
Bias = 0.265,
|
||||
LeftView = Roact.createElement(CategoryMenuView, {
|
||||
Key = MenuKey,
|
||||
Categories = FriendCategories,
|
||||
InFocus = friendCategoriesMenuInFocus,
|
||||
DefaultCategoryFocus = FriendCategoriesKeys.OnlineFriends,
|
||||
OnSelectSection = self.onSelectionGained,
|
||||
EnterSection = enterSection,
|
||||
RedirectUp = self.props.redirectUp,
|
||||
ActionPriority = actionPriority,
|
||||
}),
|
||||
RightView = Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundTransparency = 1,
|
||||
},{
|
||||
OnlineFriendsView = Roact.createElement(FriendsScrollingView, {
|
||||
friendsData = self.props.onlineFriendsData,
|
||||
initialized = self.props.initialized,
|
||||
hide = currentPage ~= PageKeys.FriendCategories.OnlineFriends.Key,
|
||||
inFocus = friendPagesInFocus,
|
||||
redirectLeft = self.exitSection,
|
||||
redirectBack = self.exitSection,
|
||||
redirectUp = self.props.redirectUp,
|
||||
redirectRight = self.props.redirectRight,
|
||||
size = UDim2.new(0, 440, 0, 770),
|
||||
noFriendsView = Roact.createElement(NoFriendsView, {
|
||||
text = Strings:LocalizedString("NoFriendsOnlinePhrase"),
|
||||
}),
|
||||
actionPriority = actionPriority + 1,
|
||||
}),
|
||||
AllFriendsView = Roact.createElement(FriendsScrollingView, {
|
||||
friendsData = self.props.allFriendsData,
|
||||
initialized = self.props.initialized,
|
||||
hide = currentPage ~= PageKeys.FriendCategories.AllFriends.Key,
|
||||
inFocus = friendPagesInFocus,
|
||||
redirectLeft = self.exitSection,
|
||||
redirectBack = self.exitSection,
|
||||
redirectUp = self.props.redirectUp,
|
||||
redirectRight = self.props.redirectRight,
|
||||
size = UDim2.new(0, 440, 0, 770),
|
||||
noFriendsView = Roact.createElement(NoFriendsView, {
|
||||
text = Strings:LocalizedString("PlayAndMakeFriendsPhrase"),
|
||||
}),
|
||||
actionPriority = actionPriority + 1,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
local filterOnlineFriends = memoize(function(friendsData)
|
||||
local onlineFriendsData = {}
|
||||
for _, data in ipairs(friendsData) do
|
||||
if data.robloxStatus ~= "Offline" or data.xboxStatus == "Online" then
|
||||
table.insert(onlineFriendsData, data)
|
||||
end
|
||||
end
|
||||
return onlineFriendsData
|
||||
end)
|
||||
|
||||
local function mapStateToProps(state, props)
|
||||
local friendsData = state.RenderedFriends.data
|
||||
return {
|
||||
allFriendsData = friendsData,
|
||||
onlineFriendsData = filterOnlineFriends(friendsData),
|
||||
initialized = state.RenderedFriends.initialized
|
||||
}
|
||||
end
|
||||
|
||||
return RoactRodux.UNSTABLE_connect2(mapStateToProps)(FriendsView)
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
--[[
|
||||
Creates a component for no friends
|
||||
]]
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Roact = require(Modules.Common.Roact)
|
||||
local GlobalSettings = require(Modules.Shell.GlobalSettings)
|
||||
|
||||
return function(props)
|
||||
return Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundTransparency = 1
|
||||
}, {
|
||||
NoFriendsIcon = Roact.createElement("ImageLabel", {
|
||||
Size = UDim2.new(0, 296, 0, 259),
|
||||
Position = UDim2.new(0.5, -148, 0, 100),
|
||||
BackgroundTransparency = 1,
|
||||
Image = "rbxasset://textures/ui/Shell/Icons/FriendsIcon@1080.png",
|
||||
}),
|
||||
NoFriendsText = Roact.createElement("TextLabel", {
|
||||
Size = UDim2.new(0, 440, 0, 72),
|
||||
Position = UDim2.new(0.5, -220, 0, 392),
|
||||
BackgroundTransparency = 1,
|
||||
Font = GlobalSettings.RegularFont,
|
||||
FontSize = GlobalSettings.ButtonSize,
|
||||
TextColor3 = GlobalSettings.WhiteTextColor,
|
||||
Text = props.text,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
TextWrapped = true
|
||||
}),
|
||||
})
|
||||
end
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
--[[
|
||||
Creates a PresenceCard component
|
||||
Props:
|
||||
gamertag: string - Xbox Gamertag.
|
||||
robloxName: string - Roblox name.
|
||||
robloxuid: int - Roblox user id.
|
||||
xuid: int - Xbox user id.
|
||||
robloxStatus: string - User's roblox xboxStatus.
|
||||
xboxStatus: string - User's xbox xboxStatus.
|
||||
lastLocation: string - User's last location info.
|
||||
layoutOrder: int - Controls the sorting priority of this button.
|
||||
size: UDim2 - The size of the presence card.
|
||||
onSelectionGained : function(guiObject : Ref<GuiObject>) -
|
||||
Fires when the GuiObject is being focused on with the Gamepad selector.
|
||||
onSelectionLost : function(guiObject : Ref<GuiObject>) -
|
||||
Fires when the Gamepad selector stops focusing on the GuiObject.
|
||||
onActivated : function(guiObject : Ref<GuiObject>) -
|
||||
Fires when the button is activated.
|
||||
]]
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
|
||||
local Roact = require(Modules.Common.Roact)
|
||||
local GlobalSettings = require(Modules.Shell.GlobalSettings)
|
||||
local Components = Modules.Shell.Components
|
||||
local UserThumbnailLoader = require(Components.Common.UserThumbnailLoader)
|
||||
local Strings = require(Modules.Shell.LocalizedStrings)
|
||||
local Utility = require(Modules.Shell.Utility)
|
||||
local SoundComponent = require(Modules.Shell.Components.Common.SoundComponent)
|
||||
|
||||
local PresenceCard = Roact.PureComponent:extend("PresenceCard")
|
||||
|
||||
function PresenceCard:init()
|
||||
self.selectionImageObject = Utility.Create "ImageLabel"({
|
||||
Name = "SelectorImage",
|
||||
Image = GlobalSettings.Images.ButtonSelector,
|
||||
Position = UDim2.new(0, -7, 0, -7),
|
||||
Size = UDim2.new(1, 14, 1, 14),
|
||||
BackgroundTransparency = 1,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = Rect.new(31, 31, 63, 63),
|
||||
})
|
||||
self.onCreate = function(rbx)
|
||||
self.ref = rbx
|
||||
end
|
||||
self.defaultProps = {
|
||||
buttonColor3 = GlobalSettings.Colors.WhiteButton,
|
||||
buttonTransparency = 0.8,
|
||||
textColor3 = GlobalSettings.Colors.WhiteText,
|
||||
iconColor3 = GlobalSettings.Colors.WhiteText,
|
||||
}
|
||||
self.focusedProps = {
|
||||
buttonColor3 = GlobalSettings.Colors.BlueButton,
|
||||
buttonTransparency = 0,
|
||||
textColor3 = GlobalSettings.Colors.BlackText,
|
||||
iconColor3 = GlobalSettings.Colors.BlackText,
|
||||
}
|
||||
self.buttonImage = GlobalSettings.Images.ButtonDefault
|
||||
end
|
||||
|
||||
function PresenceCard:render()
|
||||
local props = self.props
|
||||
|
||||
local focused = self.props.focused
|
||||
local currProps = focused and self.focusedProps or self.defaultProps
|
||||
local gamertagText = props.gamertag or ""
|
||||
local robloxNameText = props.robloxName or ""
|
||||
local showGamertag = gamertagText ~= ""
|
||||
local showRobloxName = robloxNameText ~= ""
|
||||
local statusText = ""
|
||||
local statusImageColor3 = GlobalSettings.Colors.GreySelectedButton
|
||||
|
||||
local function setPresence(statusStr, statusColor)
|
||||
statusImageColor3 = statusColor
|
||||
if statusStr and statusStr ~= "" then
|
||||
statusText = statusStr
|
||||
end
|
||||
end
|
||||
if props.robloxStatus == "InGame" then
|
||||
setPresence(props.lastLocation, GlobalSettings.Colors.GreenText)
|
||||
elseif props.robloxStatus == "InStudio" then
|
||||
setPresence(props.lastLocation, GlobalSettings.Colors.OrangeText)
|
||||
elseif props.robloxStatus == "Online" then
|
||||
setPresence("Roblox", GlobalSettings.Colors.BlueText)
|
||||
else
|
||||
if props.xboxStatus and props.xboxStatus == "Online" then
|
||||
setPresence(Strings:LocalizedString("OnlineWord"), GlobalSettings.Colors.BlueText)
|
||||
else
|
||||
setPresence(Strings:LocalizedString("OfflineWord"), GlobalSettings.Colors.GreyText)
|
||||
end
|
||||
end
|
||||
|
||||
return Roact.createElement("ImageButton", {
|
||||
Image = self.buttonImage,
|
||||
Position = UDim2.new(0.5, 0, 0.5, 0),
|
||||
AnchorPoint = Vector2.new(0.5, 0.5),
|
||||
LayoutOrder = props.layoutOrder,
|
||||
Size = props.size or UDim2.new(0, 440, 0, 120),
|
||||
ImageColor3 = currProps.buttonColor3,
|
||||
ImageTransparency = currProps.buttonTransparency,
|
||||
ScaleType = Enum.ScaleType.Slice,
|
||||
SliceCenter = Rect.new(8, 8, 9, 9),
|
||||
SelectionImageObject = self.selectionImageObject,
|
||||
BackgroundTransparency = 1,
|
||||
[Roact.Event.SelectionGained] = props.onSelectionGained,
|
||||
[Roact.Event.SelectionLost] = props.onSelectionLost,
|
||||
[Roact.Event.Activated] = props.onActivated,
|
||||
[Roact.Ref] = self.onCreate,
|
||||
},{
|
||||
MoveSelection = Roact.createElement(SoundComponent, {
|
||||
SoundName = "MoveSelection",
|
||||
}),
|
||||
|
||||
AvatarImage = Roact.createElement(UserThumbnailLoader, {
|
||||
rbxuid = props.robloxuid,
|
||||
thumbnailType = Enum.ThumbnailType.HeadShot,
|
||||
thumbnailSize = Enum.ThumbnailSize.Size100x100,
|
||||
position = UDim2.new(0, 10, 0, 10),
|
||||
size = UDim2.new(0, 100, 0, 100),
|
||||
}),
|
||||
|
||||
ContentContainer = Roact.createElement("Frame",{
|
||||
Size = UDim2.new(1, -140, 1, 0),
|
||||
Position = UDim2.new(0, 126, 0, 0),
|
||||
BackgroundTransparency = 1,
|
||||
ClipsDescendants = true,
|
||||
}, {
|
||||
UIPadding = Roact.createElement("UIPadding", {
|
||||
PaddingTop = UDim.new(0, 10),
|
||||
PaddingBottom = UDim.new(0, 10)
|
||||
}),
|
||||
|
||||
UIListLayout = Roact.createElement("UIListLayout", {
|
||||
Padding = UDim.new(0, 7),
|
||||
SortOrder = Enum.SortOrder.LayoutOrder,
|
||||
HorizontalAlignment = Enum.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Enum.VerticalAlignment.Center,
|
||||
}),
|
||||
|
||||
GamertagContainer = showGamertag and Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, 0, 0, 30),
|
||||
LayoutOrder = 1,
|
||||
BackgroundTransparency = 1
|
||||
},{
|
||||
GamertagLabel = Roact.createElement("TextLabel", {
|
||||
Text = gamertagText,
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Position = UDim2.new(0, 0, 0, 0),
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextColor3 = currProps.textColor3,
|
||||
Font = GlobalSettings.Fonts.Regular,
|
||||
TextSize = 30,
|
||||
TextScaled = true,
|
||||
BackgroundTransparency = 1,
|
||||
}),
|
||||
}),
|
||||
|
||||
RobloxNameContainer = showRobloxName and Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, 0, 0, 30),
|
||||
LayoutOrder = 2,
|
||||
BackgroundTransparency = 1
|
||||
},{
|
||||
RobloxIcon = Roact.createElement("ImageLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Image = GlobalSettings.Images.RobloxIcon,
|
||||
ImageColor3 = currProps.iconColor3,
|
||||
Position = UDim2.new(0, 0, 0, 1),
|
||||
Size = UDim2.new(0, 28, 0, 28),
|
||||
}),
|
||||
RobloxNameLabel = Roact.createElement("TextLabel", {
|
||||
Text = robloxNameText,
|
||||
Size = UDim2.new(1, -38, 1, 0),
|
||||
Position = UDim2.new(0, 38, 0, 0),
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextColor3 = currProps.textColor3,
|
||||
Font = GlobalSettings.Fonts.Regular,
|
||||
TextSize = 30,
|
||||
TextScaled = true,
|
||||
BackgroundTransparency = 1,
|
||||
})
|
||||
}),
|
||||
|
||||
StatusContainer = Roact.createElement("Frame", {
|
||||
Size = UDim2.new(1, 0, 0, 26),
|
||||
LayoutOrder = 3,
|
||||
BackgroundTransparency = 1
|
||||
},{
|
||||
PresenceStatusImage = Roact.createElement("ImageLabel", {
|
||||
BackgroundTransparency = 1,
|
||||
Image = GlobalSettings.Images.OnlineStatusIcon,
|
||||
Size = UDim2.new(0, 18, 0, 18),
|
||||
Position = UDim2.new(0, 5, 0, 4),
|
||||
ImageColor3 = statusImageColor3,
|
||||
}),
|
||||
PresenceLabel = Roact.createElement("TextLabel", {
|
||||
Text = statusText,
|
||||
Size = UDim2.new(1, -38, 1, 0),
|
||||
Position = UDim2.new(0, 33, 0, 0),
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextColor3 = currProps.textColor3,
|
||||
Font = GlobalSettings.Fonts.Regular,
|
||||
TextSize = 26,
|
||||
BackgroundTransparency = 1,
|
||||
})
|
||||
}),
|
||||
})
|
||||
})
|
||||
end
|
||||
|
||||
function PresenceCard:didMount()
|
||||
delay(0, function()
|
||||
if self.props.selected then
|
||||
Utility.SetSelectedCoreObject(self.ref)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function PresenceCard:didUpdate(previousProps, previousState)
|
||||
if not previousProps.selected and self.props.selected then
|
||||
Utility.SetSelectedCoreObject(self.ref)
|
||||
end
|
||||
end
|
||||
|
||||
return PresenceCard
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
local GuiService = game:GetService("GuiService")
|
||||
local Modules = game:GetService("CoreGui").RobloxGui.Modules
|
||||
local ShellModules = Modules:FindFirstChild("Shell")
|
||||
local Roact = require(Modules.Common.Roact)
|
||||
local RoactRodux = require(Modules.Common.RoactRodux)
|
||||
local Strings = require(ShellModules:FindFirstChild("LocalizedStrings"))
|
||||
local ScreenManager = require(ShellModules.ScreenManager)
|
||||
local AppState = require(ShellModules.AppState)
|
||||
local Analytics = require(ShellModules:FindFirstChild("Analytics"))
|
||||
local Utility = require(ShellModules:FindFirstChild("Utility"))
|
||||
local Components = ShellModules.Components
|
||||
local FriendsView = require(Components.Social.FriendsView)
|
||||
local FriendsData = require(ShellModules.FriendsData)
|
||||
|
||||
local function CreateSocialPane(parent)
|
||||
local this = {}
|
||||
local isPaneFocused = false
|
||||
local HubContainer = parent.Parent
|
||||
local UpSelector = HubContainer:FindFirstChild("TabContainer")
|
||||
|
||||
local noSelectionObject = Utility.Create"ImageLabel"({
|
||||
BackgroundTransparency = 1,
|
||||
})
|
||||
|
||||
local SocialPaneContainer = Utility.Create"Frame"({
|
||||
Name = "SocialPane",
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
BackgroundTransparency = 1,
|
||||
Visible = false,
|
||||
SelectionImageObject = noSelectionObject,
|
||||
Parent = parent,
|
||||
})
|
||||
|
||||
local FriendsContainer = Utility.Create"Frame"({
|
||||
Name = "FriendsContainer",
|
||||
Size = UDim2.new(1, 0, 1, 0),
|
||||
Position = UDim2.new(0, 0, 0, 23),
|
||||
BackgroundTransparency = 1,
|
||||
Parent = SocialPaneContainer,
|
||||
})
|
||||
|
||||
local friendsScrollerInstance;
|
||||
local function ReconcileFriendsScrollerInstance()
|
||||
if not friendsScrollerInstance then
|
||||
return
|
||||
end
|
||||
local friendsScroller = Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = AppState.store,
|
||||
}, {
|
||||
FriendsView = Roact.createElement(FriendsView, {
|
||||
inFocus = isPaneFocused,
|
||||
hide = not SocialPaneContainer.Visible,
|
||||
redirectUp = function()
|
||||
Utility.SetSelectedCoreObject(UpSelector)
|
||||
end,
|
||||
})
|
||||
})
|
||||
friendsScrollerInstance = Roact.reconcile(friendsScrollerInstance, friendsScroller)
|
||||
end
|
||||
|
||||
function this:GetName()
|
||||
return Strings:LocalizedString("FriendsWord")
|
||||
end
|
||||
|
||||
function this:IsFocused()
|
||||
return isPaneFocused
|
||||
end
|
||||
|
||||
--[[ Public API ]]--
|
||||
function this:GetAnalyticsInfo()
|
||||
return {[Analytics.WidgetNames("WidgetId")] = Analytics.WidgetNames("SocialPaneId")}
|
||||
end
|
||||
|
||||
function this:Show(fromAppHub)
|
||||
SocialPaneContainer.Visible = true
|
||||
--Suspend Friends BG Update whenever we are on GamesPane
|
||||
FriendsData:SuspendUpdate()
|
||||
|
||||
--We rebuild Friends Scroller only if we navigate from other tabs
|
||||
if fromAppHub then
|
||||
if friendsScrollerInstance then
|
||||
Roact.unmount(friendsScrollerInstance)
|
||||
end
|
||||
local friendsScroller = Roact.createElement(RoactRodux.StoreProvider, {
|
||||
store = AppState.store,
|
||||
}, {
|
||||
FriendsView = Roact.createElement(FriendsView, {
|
||||
hide = not SocialPaneContainer.Visible,
|
||||
inFocus = isPaneFocused,
|
||||
redirectUp = function()
|
||||
Utility.SetSelectedCoreObject(UpSelector)
|
||||
end,
|
||||
})
|
||||
})
|
||||
friendsScrollerInstance = Roact.mount(friendsScroller, FriendsContainer, "FriendsViewContainer")
|
||||
else
|
||||
ReconcileFriendsScrollerInstance()
|
||||
end
|
||||
ScreenManager:PlayDefaultOpenSound()
|
||||
end
|
||||
|
||||
function this:Hide(fromAppHub)
|
||||
SocialPaneContainer.Visible = false
|
||||
|
||||
--We destroy Friends Scroller if we navigate to other tabs
|
||||
if fromAppHub then
|
||||
if friendsScrollerInstance then
|
||||
Roact.unmount(friendsScrollerInstance)
|
||||
end
|
||||
friendsScrollerInstance = nil
|
||||
--We resume Friends Update only if we navigate to other tabs
|
||||
FriendsData:ResumeUpdate()
|
||||
else
|
||||
ReconcileFriendsScrollerInstance()
|
||||
end
|
||||
end
|
||||
|
||||
function this:Focus()
|
||||
isPaneFocused = true
|
||||
ReconcileFriendsScrollerInstance()
|
||||
end
|
||||
|
||||
function this:RemoveFocus()
|
||||
isPaneFocused = false
|
||||
ReconcileFriendsScrollerInstance()
|
||||
local selectedObject = GuiService.SelectedCoreObject
|
||||
if selectedObject and selectedObject:IsDescendantOf(SocialPaneContainer) then
|
||||
Utility.SetSelectedCoreObject(nil)
|
||||
end
|
||||
end
|
||||
|
||||
function this:SetPosition(newPosition)
|
||||
SocialPaneContainer.Position = newPosition
|
||||
end
|
||||
|
||||
function this:SetParent(newParent)
|
||||
SocialPaneContainer.Parent = newParent
|
||||
end
|
||||
|
||||
function this:IsAncestorOf(object)
|
||||
return SocialPaneContainer and SocialPaneContainer:IsAncestorOf(object)
|
||||
end
|
||||
|
||||
return this
|
||||
end
|
||||
|
||||
return CreateSocialPane
|
||||
Reference in New Issue
Block a user