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

499 lines
16 KiB
Lua

--[[
// PurchasePackagePrompt.lua
// Kip Turner
// Copyright Roblox 2015
]]
local CoreGui = game:GetService("CoreGui")
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
local Modules = GuiRoot:FindFirstChild("Modules")
local ShellModules = Modules:FindFirstChild("Shell")
local ContextActionService = game:GetService("ContextActionService")
local GuiService = game:GetService('GuiService')
local UserDataModule = require(ShellModules:FindFirstChild('UserData'))
local Http = require(ShellModules:FindFirstChild('Http'))
local ScrollingTextBox = require(ShellModules:FindFirstChild('ScrollingTextBox'))
local CreateConfirmPrompt = require(ShellModules:FindFirstChild('ConfirmPrompt'))
local LoadingWidget = require(ShellModules:FindFirstChild('LoadingWidget'))
local AssetManager = require(ShellModules:FindFirstChild('AssetManager'))
local GlobalSettings = require(ShellModules:FindFirstChild('GlobalSettings'))
local Utility = require(ShellModules:FindFirstChild('Utility'))
local Strings = require(ShellModules:FindFirstChild('LocalizedStrings'))
local ScreenManager = require(ShellModules:FindFirstChild('ScreenManager'))
local EventHub = require(ShellModules:FindFirstChild('EventHub'))
local ErrorOverlayModule = require(ShellModules:FindFirstChild('ErrorOverlay'))
local Errors = require(ShellModules:FindFirstChild('Errors'))
local SoundManager = require(ShellModules:FindFirstChild('SoundManager'))
local Analytics = require(ShellModules:FindFirstChild('Analytics'))
local CurrencyWidgetModule = require(ShellModules:FindFirstChild('CurrencyWidget'))
local MOCKUP_WIDTH = 1920
local MOCKUP_HEIGHT = 1080
local CONTENT_WIDTH = 1920
local CONTENT_HEIGHT = 690
local PACKAGE_CONTAINER_WIDTH = 780
local PACKAGE_CONTAINER_HEIGHT = 690
local PACKAGE_BACKGROUND_WIDTH = 580
local PACKAGE_BACKGROUND_HEIGHT = 640
local CONTENT_POSITION = Vector2.new(0, 225)
local DETAILS_CONTAINER_WIDTH = CONTENT_WIDTH - PACKAGE_CONTAINER_WIDTH
local DETAILS_CONTAINER_HEIGHT = 690
local DESCRIPTION_WIDTH = 800
local DESCRIPTION_HEIGHT = 320
local BUY_BUTTON_WIDTH = 320
local BUY_BUTTON_HEIGHT = 64
local BUY_BUTTON_OFFSET = Vector2.new(0, -50)
local function CreatePurchasePackagePrompt(packageInfo)
local this = {}
local MyParent = nil
local Result = nil
local purchasing = false
local finishedLoading = false
local balance = nil
local inFocus = false
local ResultEvent = Utility.Signal()
local packageName = packageInfo:GetFullName()
local robuxPrice = packageInfo:GetRobuxPrice()
local creatorId = packageInfo:GetCreatorId()
local ModalBackground = Utility.Create'Frame'
{
Name = "PurchasePackagePrompt";
Size = UDim2.new(1, 0, 1, 0);
BackgroundTransparency = 1;
BackgroundColor3 = GlobalSettings.ModalBackgroundColor;
BorderSizePixel = 0;
}
local ContentContainer = Utility.Create'Frame'
{
Name = "ContentContainer";
Size = UDim2.new(CONTENT_WIDTH/MOCKUP_WIDTH, 0, CONTENT_HEIGHT/MOCKUP_HEIGHT, 0);
Position = UDim2.new(CONTENT_POSITION.x/MOCKUP_WIDTH, 0, CONTENT_POSITION.y/MOCKUP_HEIGHT, 0);
BackgroundTransparency = 0;
BackgroundColor3 = GlobalSettings.OverlayColor;
BorderSizePixel = 0;
Parent = ModalBackground;
}
local PackageContainer = Utility.Create'Frame'
{
Name = "PackageContainer";
Size = UDim2.new(PACKAGE_CONTAINER_WIDTH/CONTENT_WIDTH, 0, PACKAGE_CONTAINER_HEIGHT/CONTENT_HEIGHT, 0);
Position = UDim2.new(0,0,0,0);
BackgroundTransparency = 1;
BorderSizePixel = 0;
Parent = ContentContainer;
}
local PackageBackground = Utility.Create'Frame'
{
Name = "PackageBackground";
Size = UDim2.new(PACKAGE_BACKGROUND_WIDTH/PACKAGE_CONTAINER_WIDTH, 0, PACKAGE_BACKGROUND_HEIGHT/CONTENT_HEIGHT, 0);
BackgroundTransparency = 0;
BackgroundColor3 = GlobalSettings.ForegroundGreyColor;
BorderSizePixel = 0;
ZIndex = 2;
Parent = PackageContainer;
AssetManager.CreateShadow(1);
AnchorPoint = Vector2.new(0.5, 0.5);
Position = UDim2.new(0.5, 0, 0.5, 0);
}
local PackageImage = Utility.Create'ImageLabel'
{
Name = 'PackageImage';
Size = UDim2.new(1,0,1,0);
Image = Http.GetThumbnailUrlForAsset(packageInfo:GetAssetId());
BackgroundTransparency = 1;
ZIndex = PackageBackground.ZIndex;
Parent = PackageBackground;
};
local DetailsContainer = Utility.Create'Frame'
{
Name = "DetailsContainer";
Size = UDim2.new(DETAILS_CONTAINER_WIDTH/CONTENT_WIDTH, 0, DETAILS_CONTAINER_HEIGHT/CONTENT_HEIGHT, 0);
Position = UDim2.new(PACKAGE_CONTAINER_WIDTH/CONTENT_WIDTH,0,0,0);
BackgroundTransparency = 1;
BorderSizePixel = 0;
Parent = ContentContainer;
}
local PurchasingTitle = Utility.Create'TextLabel'
{
Name = 'PurchasingTitle';
Text = Strings:LocalizedString('PurchasingTitle');
Position = UDim2.new(0, 0, 0, 66);
Size = UDim2.new(1,0,0,25);
TextXAlignment = 'Left';
TextColor3 = GlobalSettings.WhiteTextColor;
Font = GlobalSettings.HeadingFont;
FontSize = GlobalSettings.HeaderSize;
BackgroundTransparency = 1;
Visible = false;
Parent = DetailsContainer;
};
local DetailsContent = Utility.Create'Frame'
{
Name = "DetailsContent";
Size = UDim2.new(1, 0, 1, 0);
Position = UDim2.new(0,0,0,0);
BackgroundTransparency = 1;
BorderSizePixel = 0;
Parent = DetailsContainer;
}
local PackageName = Utility.Create'TextLabel'
{
Name = 'PackageName';
Text = packageName or "Unknown Package";
Position = UDim2.new(0, 0, 0, 66);
Size = UDim2.new(1,0,0,25);
TextXAlignment = 'Left';
TextColor3 = GlobalSettings.WhiteTextColor;
Font = GlobalSettings.HeadingFont;
FontSize = GlobalSettings.HeaderSize;
BackgroundTransparency = 1;
Parent = DetailsContent;
};
local RobuxIcon = Utility.Create'ImageLabel'
{
Name = 'RobuxIcon';
Position = UDim2.new(0,0,0,125);
Size = UDim2.new(0,50,0,50);
BackgroundTransparency = 1;
Parent = DetailsContent;
Image = "rbxasset://textures/ui/Shell/Icons/ROBUXIcon@1080.png";
Size = UDim2.new(0,42,0,42);
};
local PackageCost = Utility.Create'TextLabel'
{
Name = 'PackageCost';
Text = '';
Size = UDim2.new(0,0,1,0);
Position = UDim2.new(1.3,0,0,0);
TextXAlignment = 'Left';
TextColor3 = GlobalSettings.GreenTextColor;
Font = GlobalSettings.RegularFont;
FontSize = GlobalSettings.HeaderSize;
BackgroundTransparency = 1;
Parent = RobuxIcon;
};
local AlreadyOwnTextLabel = Utility.Create'TextLabel'
{
Name = 'AlreadyOwnTextLabel';
Text = '';
Size = UDim2.new(0,0,0,50);
Position = UDim2.new(0,0,0,125);
TextXAlignment = 'Left';
TextColor3 = GlobalSettings.GreenTextColor;
Font = GlobalSettings.ItalicFont;
FontSize = GlobalSettings.DescriptionSize;
BackgroundTransparency = 1;
Visible = false;
Parent = DetailsContent;
};
local descriptionScrollingTextBox = ScrollingTextBox(UDim2.new(DESCRIPTION_WIDTH/DETAILS_CONTAINER_WIDTH, 0, DESCRIPTION_HEIGHT/DETAILS_CONTAINER_HEIGHT, 0),
UDim2.new(0, 0, 0, 200),
DetailsContent)
descriptionScrollingTextBox:SetFontSize(GlobalSettings.TitleSize)
descriptionScrollingTextBox:SetFont(GlobalSettings.LightFont)
local BuyButton = Utility.Create'ImageButton'
{
Name = "BuyButton";
Size = UDim2.new(0, BUY_BUTTON_WIDTH, 0, BUY_BUTTON_HEIGHT);
BorderSizePixel = 0;
BackgroundColor3 = GlobalSettings.BlueButtonColor;
BackgroundTransparency = 0;
Parent = DetailsContent;
AnchorPoint = Vector2.new(0, 1);
Position = UDim2.new(0, 0, 1 + BUY_BUTTON_OFFSET.Y/DETAILS_CONTAINER_HEIGHT, 0);
}
local BuyText = Utility.Create'TextLabel'
{
Name = 'BuyText';
Text = '';
Size = UDim2.new(1,0,1,0);
TextColor3 = GlobalSettings.TextSelectedColor;
Font = GlobalSettings.HeadingFont;
FontSize = GlobalSettings.MediumLargeHeadingSize;
BackgroundTransparency = 1;
Parent = BuyButton;
};
--Make the BuyButton big enough
Utility.ResizeButtonWithDynamicText(BuyButton, BuyText,
{Strings:LocalizedString("OkWord"), Strings:LocalizedString("BuyWord"), Strings:LocalizedString("GetRobuxPhrase"), Strings:LocalizedString("TakeWord")},
GlobalSettings.TextHorizontalPadding)
local function OnOwnedUpdate()
if packageInfo:IsOwned() or robuxPrice == nil then
if packageInfo:IsOwned() then
if robuxPrice and robuxPrice > 0 then
AlreadyOwnTextLabel.Text = string.format(Strings:LocalizedString('PurchasedThisPhrase'), Utility.FormatNumberString(tostring(robuxPrice)))
else
AlreadyOwnTextLabel.Text = Strings:LocalizedString('AlreadyOwnedPhrase')
end
end
AlreadyOwnTextLabel.Visible = (packageInfo:IsOwned() == true)
RobuxIcon.Visible = false
BuyText.Text = Strings:LocalizedString("OkWord")
--V1: Show buy button for Xbox add ons (boy/girl avatar) if they aren't owned
if packageInfo:IsXboxAddOn() and not packageInfo:IsOwned() then
BuyText.Text = Strings:LocalizedString('BuyWord')
end
else
if robuxPrice and robuxPrice == 0 then
PackageCost.Text = Strings:LocalizedString('FreeWord');
else
PackageCost.Text = robuxPrice and Utility.FormatNumberString(tostring(robuxPrice)) or '-';
end
RobuxIcon.Visible = true
AlreadyOwnTextLabel.Visible = false
if robuxPrice == 0 then
BuyText.Text = Strings:LocalizedString('TakeWord');
elseif balance and robuxPrice > balance then
BuyText.Text = Strings:LocalizedString('GetRobuxPhrase');
else
BuyText.Text = Strings:LocalizedString('BuyWord');
end
end
end
local function SetBalance(newBalance)
balance = newBalance
OnOwnedUpdate()
end
function this:UpdateOwned()
OnOwnedUpdate()
end
function this:ResultAsync()
if Result then
return Result
end
ResultEvent:wait()
return Result
end
do
local function loadBalanceAsync()
local balance = UserDataModule.GetPlatformUserBalanceAsync()
SetBalance(balance)
end
local function loadDescription()
local descriptionText = packageInfo:GetDescriptionAsync()
descriptionScrollingTextBox:SetText(descriptionText or "")
end
DetailsContent.Visible = false
local loader = LoadingWidget({Parent = DetailsContainer}, {loadBalanceAsync, loadDescription})
spawn(function()
loader:AwaitFinished()
loader:Cleanup()
loader = nil
ScreenManager:DefaultFadeIn(DetailsContent)
DetailsContent.Visible = true
if inFocus then
Utility.SetSelectedCoreObject(this:GetDefaultSelectableObject())
end
finishedLoading = true
end)
end
local function DoPurchase()
purchasing = true
local wasOwned = packageInfo:IsOwned()
local purchaseResult = packageInfo:BuyAsync()
local newBalance = purchaseResult and purchaseResult['balanceAfterSale'] or UserDataModule.GetPlatformUserBalanceAsync()
SetBalance(newBalance)
local nowOwns = packageInfo:IsOwned() and not wasOwned
Result = nowOwns
if nowOwns then
this:UpdateOwned()
end
purchasing = false
if not wasOwned and not nowOwns then
if ScreenManager:GetTopScreen() == this then
ScreenManager:CloseCurrent()
end
ScreenManager:OpenScreen(ErrorOverlayModule(Errors.PackagePurchase[1]), false)
end
Utility.DebugLog("Done with purchase")
end
OnOwnedUpdate()
function this:GetAnalyticsInfo()
return
{
[Analytics.WidgetNames('WidgetId')] = Analytics.WidgetNames('PurchasePackagePromptId');
AssetId = packageInfo:GetAssetId();
IsOwned = packageInfo:IsOwned();
}
end
function this:GetDefaultSelectableObject()
return BuyButton
end
function this:FadeInBackground()
Utility.PropertyTweener(ModalBackground, "BackgroundTransparency", 1, GlobalSettings.ModalBackgroundTransparency, 0.25, Utility.EaseInOutQuad, true)
end
function this:GetPriority()
return GlobalSettings.OverlayPriority
end
local currencyWidget = nil
local RobuxChangedConn = nil
function this:Show()
ModalBackground.Visible = true
ModalBackground.Parent = ScreenManager:GetScreenGuiByPriority(self:GetPriority())
local function onPackageBackgroundResize()
PackageImage.Size = Utility.CalculateFill(PackageBackground, Vector2.new(420, 420))
PackageImage.AnchorPoint = Vector2.new(0.5, 0.5)
PackageImage.Position = UDim2.new(0.5, 0, 0.5, 0)
end
self.PackageBackgroundChangedConn = Utility.DisconnectEvent(self.PackageBackgroundChangedConn)
self.PackageBackgroundChangedConn = PackageBackground:GetPropertyChangedSignal('AbsoluteSize'):connect(function()
onPackageBackgroundResize()
end)
onPackageBackgroundResize()
if not currencyWidget then
currencyWidget = CurrencyWidgetModule({Parent = ModalBackground; Position = UDim2.new(0.052, 0, 0.88, 0); })
end
Utility.DisconnectEvent(RobuxChangedConn)
RobuxChangedConn = currencyWidget.RobuxChanged:connect(SetBalance)
SoundManager:Play('OverlayOpen')
end
function this:Hide()
ModalBackground.Visible = false
ModalBackground.Parent = nil
self.PackageBackgroundChangedConn = Utility.DisconnectEvent(self.PackageBackgroundChangedConn)
RobuxChangedConn = Utility.DisconnectEvent(RobuxChangedConn)
end
function this:ScreenRemoved()
if currencyWidget then
currencyWidget:Destroy()
currencyWidget = nil
end
ResultEvent:fire()
end
function this:Focus()
inFocus = true
ContextActionService:BindCoreAction("ReturnFromPurchasePackageScreen",
function(actionName, inputState, inputObject)
if not purchasing then
if inputState == Enum.UserInputState.End then
ScreenManager:CloseCurrent()
end
end
end,
false,
Enum.KeyCode.ButtonB)
local buyButtonDebounce = false
self.BuyButtonConn = Utility.DisconnectEvent(self.BuyButtonConn)
self.BuyButtonConn = BuyButton.MouseButton1Click:connect(function()
if buyButtonDebounce or purchasing or not finishedLoading then
return
end
buyButtonDebounce = true
if packageInfo:IsOwned() or robuxPrice == nil then
SoundManager:Play('ButtonPress')
ScreenManager:CloseCurrent()
--Open the product detail if it's a xbox add-on and not owned
if packageInfo:IsXboxAddOn() and not packageInfo:IsOwned() then
packageInfo:OpenAvatarDetailInXboxStore()
end
else
if balance then
if robuxPrice > 0 and balance < robuxPrice then
Utility.DebugLog("Goto robux screen")
EventHub:dispatchEvent(EventHub.Notifications["NavigateToRobuxScreen"])
else
local confirmPrompt = CreateConfirmPrompt({ProductId = packageInfo and packageInfo:GetAssetId() or "Unknown"; ProductName = packageName; Cost = robuxPrice; Balance = balance; ProductImage = Http.GetThumbnailUrlForAsset(packageInfo:GetAssetId()); Currency = "Robux"; CurrencySymbol = ""},
{ShowRemainingBalance = true; ShowRobuxIcon = true;})
ScreenManager:OpenScreen(confirmPrompt)
local result = confirmPrompt:ResultAsync()
if result == true then
local loader = LoadingWidget({Parent = DetailsContainer}, {DoPurchase})
DetailsContent.Visible = false
PurchasingTitle.Visible = true
spawn(function()
loader:AwaitFinished()
loader:Cleanup()
loader = nil
ScreenManager:DefaultFadeIn(DetailsContent)
DetailsContent.Visible = true
PurchasingTitle.Visible = false
if ScreenManager:GetTopScreen() == this then
ScreenManager:CloseCurrent()
end
end)
else
Utility.DebugLog("Declined to buy")
end
end
end
end
buyButtonDebounce = false
end)
GuiService:AddSelectionParent("PurchasePackagePromptSelectionGroup", ContentContainer)
Utility.SetSelectedCoreObject(self:GetDefaultSelectableObject())
end
function this:RemoveFocus()
inFocus = false
ContextActionService:UnbindCoreAction("ReturnFromPurchasePackageScreen")
GuiService:RemoveSelectionGroup("PurchasePackagePromptSelectionGroup")
self.BuyButtonConn = Utility.DisconnectEvent(self.BuyButtonConn)
Utility.SetSelectedCoreObject(nil)
end
function this:SetParent(parent)
MyParent = parent
ModalBackground.Parent = MyParent
end
return this
end
return CreatePurchasePackagePrompt