Shop UI Works on PC but not Tablet & Phone

Hi, I am trying to fix a bug in my roblox game, basically what happens is on PC, the shop UI (purchase buttons) work, when you click them, it prompts you to buy a gamepass, however when you are on tablet or phone, and you click on the buy button, nothing happens, I can’t seem to figure out why. If anyone can help me that would be create, I’ll provide a copy of my shop ui script below.

Does anyone know where in my script that I’m missing something? Thanks!

I’ve also removed some of my IDs for privacy reasons! Please help me if you can.

local ShopUIHandler = {
	ActiveBoosts = {
		Speed = 0	
	},
	
	Gifting = nil
}

local Players = game:GetService("Players")
local Market = game:GetService("MarketplaceService")
local RS = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer

local main = player:WaitForChild("PlayerGui"):WaitForChild("Main")
local menus = main:WaitForChild("Menus")
local shopFrame = menus:WaitForChild("Shop")
local giftFrame = menus:WaitForChild("Gift")
local giftContents = giftFrame:WaitForChild("PlayerList")
local hudleft = main:WaitForChild("HUDLeft")
local menuButton = hudleft:WaitForChild("Buttons"):WaitForChild("Top"):WaitForChild("Shop")
local shopContents = shopFrame:WaitForChild("Contents")
local boostDisplay = main:WaitForChild("Boosts")
local hoverTooltips = main:WaitForChild("Tooltips"):WaitForChild("Hover")

local GUIHandler = require(script.Parent)
local TooltipHandler = require(script.Parent.Parent.TooltipHandler)
local EventsHandler = require(RS.Modules.EventsHandler)
local FormatTime = require(RS.Modules.FormatTime)
local ViewportHandler = require(RS.Modules.ViewportHandler)
local WorldsConfig = require(RS.Modules.Configuration.WorldConfig)
local WorldsList = require(RS.Modules.Configuration.WorldConfig.WorldsList)
local HeroUIHandler = require(script.Parent.HeroUIHandler)
local HeroesConfig = require(RS.Modules.Configuration.HeroesConfig)
local Abbreviate = require(RS.Modules.AbbreviateHandler)
local ShopConfig = require(RS.Modules.Configuration.ShopConfig)
local CommaNumber = require(RS.Modules.CommaNumber)
local TwitterVerifyUIHandler = require(script.Parent.TwitterVerifyUIHandler)
local NotificationHandler = require(script.Parent.Parent.NotificationHandler)

local Passes = { REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE}

local mainPasses = {
	[REMOVEDFROMEXAMPLE] = Color3.fromRGB(0, 174, 255),
	[REMOVEDFROMEXAMPLE] = Color3.fromRGB(0, 174, 0),
	[REMOVEDFROMEXAMPLE] = Color3.fromRGB(255, 0, 72),
	[REMOVEDFROMEXAMPLE] = Color3.fromRGB(255, 198, 0)
}

local Coins = { REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE, REMOVEDFROMEXAMPLE}

local Boosts = {
	Coins = {
		["15mins"] = REMOVEDFROMEXAMPLE,
		["1hour"] = REMOVEDFROMEXAMPLE
	},
	Damage = {
		["15mins"] = REMOVEDFROMEXAMPLE,
		["1hour"] = REMOVEDFROMEXAMPLE
	},
	Luck = {
		["15mins"] = REMOVEDFROMEXAMPLE,
		["1hour"] = REMOVEDFROMEXAMPLE
	}
}

local Heroes = {
	Common = REMOVEDFROMEXAMPLE,
	Rare = REMOVEDFROMEXAMPLE,
	Epic = REMOVEDFROMEXAMPLE,
	Legendary = REMOVEDFROMEXAMPLE
}

local boostImgs = {
	Coins = "rbxassetid://REMOVEDFROMEXAMPLE",
	Damage = "rbxassetid://REMOVEDFROMEXAMPLE",
	Luck = "rbxassetid://REMOVEDFROMEXAMPLE",
	Pack = "rbxassetid://REMOVEDFROMEXAMPLE"
}

local rarities = {
	Common = { ColorSequence.new(Color3.fromRGB(154, 154, 154), Color3.fromRGB(231, 231, 231)), 1 },
	Rare = { ColorSequence.new(Color3.fromRGB(0, 114, 220), Color3.fromRGB(0, 234, 255)), 2 },
	Epic = { ColorSequence.new(Color3.fromRGB(67, 0, 220), Color3.fromRGB(180, 0, 255)), 3 },
	Legendary = { ColorSequence.new(Color3.fromRGB(220, 83, 0), Color3.fromRGB(255, 186, 0)), 4 }
}

local currentDay

function ShopUIHandler:OpenFrame(FrameChosen)
	local frameFound = shopContents:FindFirstChild(FrameChosen)
	if not frameFound then return end
	
	for _,v in pairs(shopContents:GetChildren()) do
		v.Visible = false
	end
	
	frameFound.Visible = true
end

local function cacheProperty(object: Instance, property: string)
	if not object:GetAttribute("OG"..property) then
		object:SetAttribute("OG"..property, object[property])
	end

	return object:GetAttribute("OG"..property)
end

local function UpdateScaling(viewportSize, resolutionScale)
	local newSize = 50
	if resolutionScale <= 0.55 then
		newSize = 35
	elseif resolutionScale <= 0.75 then
		newSize = 45
	end
	boostDisplay:FindFirstChildOfClass("UIGridLayout").CellSize = UDim2.fromOffset(newSize, newSize)

	RunService.RenderStepped:Wait()

	for _, item: Instance in ipairs(shopContents:GetDescendants()) do
		if item.ClassName == "UIListLayout" then
			local ogPadding = cacheProperty(item, "Padding")
			item.Padding = UDim.new(ogPadding.Scale, ogPadding.Offset * resolutionScale)
		elseif item.ClassName == "UIGridLayout" then
			local ogPadding = cacheProperty(item, "CellPadding")
			item.CellPadding = UDim2.new(ogPadding.X.Scale, ogPadding.X.Offset * resolutionScale, ogPadding.Y.Scale, ogPadding.Y.Offset * resolutionScale)
		end
	end

	for _, section in ipairs(shopContents:GetChildren()) do
		if not section:IsA("GuiBase2d") then continue end

		local ogSize = cacheProperty(section, "Size")
		section.Size = UDim2.new(0.975, 0, 0, ogSize.Y.Offset * resolutionScale)

		local ogTextSize = cacheProperty(section.Title, "Size")
		section.Title.Size = UDim2.new(0.5, 0, 0, ogTextSize.Y.Offset * resolutionScale)

		local contentsSize = section.Contents.Size
		section.Contents.Size = UDim2.new(contentsSize.X.Scale, contentsSize.X.Offset, contentsSize.Y.Scale, -(ogTextSize.Y.Offset * resolutionScale))
	end

	-- gift
	local playersToShow
	if resolutionScale <= 0.5 then
		playersToShow = 3
	elseif resolutionScale <= 1.2 then
		playersToShow = 4
	else
		playersToShow = 5
	end

	local giftCell = giftContents.AbsoluteSize.Y / playersToShow - giftContents.UIListLayout.Padding.Offset
	for _, setting in ipairs(giftContents:GetChildren()) do
		if not setting:IsA("GuiBase2d") then continue end
		setting.Size = UDim2.new(.92, 0, 0, giftCell)
	end
	giftContents.CanvasSize = UDim2.fromOffset(0, giftContents.UIListLayout.AbsoluteContentSize.Y + 10)

	-- featured heroes
	local heroCell = shopContents.Featured.Contents.AbsoluteSize.X / 4 - shopContents.Featured.Contents.UIListLayout.Padding.Offset
	for _, hero in ipairs(shopContents.Featured.Contents:GetChildren()) do
		if not hero:IsA("GuiBase2d") then continue end
		hero.Size = UDim2.new(0, heroCell, 1, 0)
	end

	 --passes
	--local mainPassCellX = shopContents.Passes.Contents.Main.AbsoluteSize.X / 2 - shopContents.Passes.Contents.Main.UIGridLayout.CellPadding.X.Offset
	--local mainPassCellY = shopContents.Passes.Contents.Main.AbsoluteSize.Y / 2 - shopContents.Passes.Contents.Main.UIGridLayout.CellPadding.Y.Offset
	--shopContents.Passes.Contents.Main.UIGridLayout.CellSize = UDim2.fromOffset(mainPassCellX, mainPassCellY)

	--local passCell = shopContents.Passes.Contents.Normal.AbsoluteSize.X / 4 - shopContents.Passes.Contents.Normal.UIGridLayout.CellPadding.X.Offset
	--shopContents.Passes.Contents.Normal.UIGridLayout.CellSize = UDim2.new(0, passCell, .281, 0)

	 --boosts
	local boostSize = shopContents.Boosts.Contents.AbsoluteSize.Y / (#shopContents.Boosts.Contents:GetChildren() - 1) - shopContents.Boosts.Contents.UIListLayout.Padding.Offset
	for _, setting in ipairs(shopContents.Boosts.Contents:GetChildren()) do
		if not setting:IsA("GuiBase2d") then continue end
		setting.Size = UDim2.new(1, 0, 0, boostSize)
	end

	-- coins
	local coinCell = shopContents.Coins.Contents.Group.AbsoluteSize.X / 3 - shopContents.Coins.Contents.Group.UIGridLayout.CellPadding.X.Offset
	shopContents.Coins.Contents.Group.UIGridLayout.CellSize = UDim2.new(0, coinCell, .475, 0)

	--shopContents.CanvasSize = UDim2.fromOffset(0, shopContents.UIListLayout.AbsoluteContentSize.Y + 10)
end

local function UpdateOwnedPasses(passesData)
	for _, location in ipairs({ "Main", "Normal" }) do
		for _, pass in ipairs(shopContents:WaitForChild("Passes"):WaitForChild("Contents"):WaitForChild(location):GetChildren()) do
			if not pass:IsA("GuiBase2d") then continue end
			local passOwned = table.find(passesData, tostring(pass.GamepassID.Value))
			pass.Price.Robux.Text = if passOwned then "OWNED" else (if pass.PriceInRobux.Value == -1 then "Not For Sale" else pass.PriceInRobux.Value)
			pass.Price.Robux.TextColor3 = if passOwned then Color3.new(0, 1, 0) else Color3.new(1, 1, 1)
			pass.Price.RobuxIcon.Visible = not (pass.PriceInRobux.Value == -1 or passOwned)
		end	
	end
end

local function UpdateGift()
	for _, frame in ipairs(giftContents:GetChildren()) do
		if frame:IsA("GuiBase2d") then
			frame:Destroy()
		end
	end

	for _, plr in ipairs(Players:GetPlayers()) do
		if plr == player then continue end

		local GiftTemplate = RS.GUITemplates.GiftTemplate:Clone()

		GiftTemplate.Name = plr.Name
		GiftTemplate.PlayerName.Text = if (plr.DisplayName == "" or plr.DisplayName == plr.Name) then plr.Name else string.format("%s (@%s)", plr.DisplayName, plr.Name)

		local s, AvatarImage = pcall(function()
			return Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
		end)
		GiftTemplate.PlayerIcon.Image = s and AvatarImage or ""

		GiftTemplate.Activated:Connect(function()
			local ownedGamepasses, highestWorld = EventsHandler:ClientCall("Gift", plr)

			if ownedGamepasses and highestWorld and type(ownedGamepasses) == "table" then
				ShopUIHandler.Gifting = plr

				local name = if (plr.DisplayName == "" or plr.DisplayName == plr.Name) then plr.Name else plr.DisplayName
				shopFrame.Gifting.Text = "Gifting ".. name

				UpdateOwnedPasses(ownedGamepasses)
				ShopUIHandler:UpdateShopValues(highestWorld)

				NotificationHandler:SetOutput("You are now gifting ".. name .."!")
			end

			GUIHandler:OpenFrame("Shop")
		end)

		GiftTemplate.Visible = true
		GiftTemplate.Parent = giftContents
	end

	if GUIHandler.ViewportSize ~= nil then
		UpdateScaling(GUIHandler.ViewportSize, GUIHandler.ResolutionScale)
	end
end

local function GetHighestWorld(plr)
	local ownedWorlds = EventsHandler:ClientCall("GetWorlds", plr)

	local highestWorld = "Superhero Island"
	for _, world in ipairs(WorldsList) do
		if world:split(" ")[1] == "Dungeon" or table.find({ "Dungeons Hub", "Raid", "Boss" }, world) then continue end

		if table.find(ownedWorlds, world) then
			highestWorld = world
		else
			break
		end
	end
	return highestWorld
end

function ShopUIHandler:UpdateShopValues(highestWorld: string?)
	if highestWorld == nil then
		highestWorld = GetHighestWorld(ShopUIHandler.Gifting)
	end

	for i, productID in ipairs(Coins) do
		local parent = if i == 7 then shopContents.Coins.Contents else shopContents.Coins.Contents.Group
		local coinButton = parent:WaitForChild("Coins"..i)

		if not coinButton then
			warn("[ShopUIHandler] Coin button #"..i.." does not exist! ("..productID..")")
			continue
		end

		coinButton.Amount.Text = CommaNumber(WorldsConfig[highestWorld][4] * ShopConfig.CoinMultipliers[i])
	end

	for rarity, data in pairs(rarities) do
		local heroButton = shopContents:WaitForChild("Featured"):WaitForChild("Contents"):WaitForChild(rarity)

		local level = WorldsConfig[highestWorld][5]
		local damage = HeroUIHandler:GetHeroDamage(HeroesConfig[heroButton.HeroName.Text], level)

		heroButton.Damage.Text = Abbreviate(damage)
	end
end

function ShopUIHandler:ResetGiftingPerson()
	if shopFrame.Gifting.Text == "" and self.Gifting == nil then return end

	local name = if (self.Gifting.DisplayName == "" or self.Gifting.DisplayName == self.Gifting.Name) then self.Gifting.Name else self.Gifting.DisplayName

	EventsHandler:ClientCall("Gift", nil)
	UpdateOwnedPasses(EventsHandler:ClientCall("GetOwnedPasses"))
	self.Gifting = nil
	self:UpdateShopValues()
	shopFrame.Gifting.Text = ""

	NotificationHandler:SetOutput("Removed ".. name .." from gifting!", nil, Color3.fromRGB(255, 0, 0))
end

local tooltips = {}
local function createBoost(boostName)
	if boostDisplay:FindFirstChild(boostName) or not ShopConfig.Boosts[boostName] then return end

	local boost = RS.GUITemplates.Boost:Clone()
	boost.Name = boostName
	boost.TimeLeft.Text = ""
	boost.Icon.Image = ShopConfig.Boosts[boostName][1]
	boost.LayoutOrder = table.find(ShopConfig.Boosts, boostName)
	boost.Parent = boostDisplay

	tooltips[boostName] = TooltipHandler(boost, ShopConfig.Boosts[boostName][2], 1, boostName.."Boost")

	return boost
end

function ShopUIHandler:Insufficient()
	GUIHandler:OpenFrame("Shop")
	ShopUIHandler:OpenFrame("Coins")
end

function ShopUIHandler:UpdateBoostInventory(data, silent)
	for boostID, amount in pairs(data) do
		if not ShopConfig.Inventory[boostID] then continue end
		local boostName, duration = unpack(boostID:split("-"))

		local boost = shopContents.Boosts.Contents:FindFirstChild(boostID)
		if not boost then continue end

		boost.Buttons.Use.TextLabel.Text = "Use"..(if amount > 0 then " ("..amount..")" else "")
	end

	if (not menuButton.Notification.Visible) and (not silent) then
		menuButton.Notification.Visible = true
	end
end

local function updateFeaturedHeroes(newHeroes: table, silent: boolean?)
	if newHeroes == nil then
		newHeroes = EventsHandler:ClientCall("UpdateExcShop")
	end
	for rarity, hero in pairs(newHeroes) do
		shopContents.Featured.Contents:WaitForChild(rarity).HeroName.Text = hero
		if shopContents.Featured.Contents[rarity].Photo:FindFirstChildOfClass("ViewportFrame") then
			shopContents.Featured.Contents[rarity].Photo:FindFirstChildOfClass("ViewportFrame"):Destroy()
		end
		ViewportHandler:AddHeroIntoView(hero, shopContents.Featured.Contents[rarity].Photo, 5, { SetOffset = Vector3.new(0, 0.8, 0) })
		ShopUIHandler:UpdateShopValues()
	end
	if (not silent) then
		menuButton.Notification.Visible = true
	end
end

function ShopUIHandler:Init()
	EventsHandler:ClientListen("LoadInventory", function(inventoryData, silent)
		ShopUIHandler:UpdateBoostInventory(inventoryData.Boosts, silent)
	end)

	EventsHandler:ClientListen("CreateVerifiedBoostIcon", function()
		local boost = createBoost("Verified")
		boost.TimeLeft.Text = "∞"

		TwitterVerifyUIHandler:Verified()
	end)

	EventsHandler:ClientListen("UpdateExcShop", updateFeaturedHeroes)

	EventsHandler:ClientListen("UpdateBoosts", function(boostData)
		for boostName, duration in pairs(boostData) do
			if duration <= 0 then
				if tooltips[boostName] then
					tooltips[boostName]()
					tooltips[boostName] = nil
				end
				if boostDisplay:FindFirstChild(boostName) then
					boostDisplay[boostName]:Destroy()
				end
				continue
			end

			local boost = if boostDisplay:FindFirstChild(boostName) then boostDisplay[boostName] else createBoost(boostName)

			boost.TimeLeft.Text = if duration > 86400 then FormatTime:TimeString(duration) else FormatTime:AdaptiveTime(duration)

			if duration > 86400 then
				if hoverTooltips:FindFirstChild(boostName.."Boost") then
					hoverTooltips[boostName.."Boost"].Text = ShopConfig.Boosts[boostName][2].." ("..FormatTime:AdaptiveTime(duration)..")"
				end
				if tooltips[boostName] then
					tooltips[boostName]()
				end
				tooltips[boostName] = TooltipHandler(boost, ShopConfig.Boosts[boostName][2].." ("..FormatTime:AdaptiveTime(duration)..")", 1, boostName.."Boost")
			end
		end

		ShopUIHandler.ActiveBoosts = boostData
	end)

	EventsHandler:ClientListen("Gift", function(receiver, receiverPasses)
		if receiver == ShopUIHandler.Gifting then
			UpdateOwnedPasses(receiverPasses)
		end
	end)

	for i, gamepassID in ipairs(Passes) do
		task.spawn(function()
			local s, marketInfo = pcall(function()
				return Market:GetProductInfo(gamepassID, Enum.InfoType.GamePass)
			end)

			local template = if mainPasses[gamepassID] then RS.GUITemplates.MainPassesTemplate:Clone() else RS.GUITemplates.PassesTemplate:Clone()

			template.GamepassName.Text = if (s and marketInfo) then marketInfo.Name else "Failed to load"
			template:FindFirstChild("GamepassID").Value = gamepassID
			template.LayoutOrder = i
			if mainPasses[gamepassID] then
				template.BackgroundColor3 = mainPasses[gamepassID]
			end

			if s and marketInfo then
				template.Name = marketInfo.Name
				template:FindFirstChild("PriceInRobux").Value = if marketInfo.IsForSale then marketInfo.PriceInRobux else -1
				template.Price.Robux.Text = if (marketInfo.IsForSale and marketInfo.PriceInRobux) then marketInfo.PriceInRobux else "Not For Sale"
				template.Icon.Image = "rbxassetid://"..marketInfo.IconImageAssetId
				template.Description.Text = marketInfo.Description
			end

			template.Activated:Connect(function()
				EventsHandler:ClientCall("BuyPass", gamepassID)
			end)

			template.Parent = shopContents:WaitForChild("Passes"):WaitForChild("Contents"):WaitForChild(if mainPasses[gamepassID] then "Main" else "Normal")
		end)
	end

	local highestWorld = GetHighestWorld()
	for i, productID in ipairs(Coins) do
		task.spawn(function()
			local marketInfo
			local s, e = pcall(function()
				marketInfo = Market:GetProductInfo(productID, Enum.InfoType.Product)
			end)

			if i == 7 then
				local coins7 = shopContents.Coins.Contents.Coins7
				coins7.Amount.Text = CommaNumber(WorldsConfig[highestWorld][4] * ShopConfig.CoinMultipliers[i])
				coins7.Price.Robux.Text = if marketInfo and marketInfo.PriceInRobux then CommaNumber(marketInfo.PriceInRobux) else "Failed to load"

				coins7.Activated:Connect(function()
					Market:PromptProductPurchase(player, productID)
					GUIHandler:SetPurchaseLoading(true)
				end)
			else
				local template = RS.GUITemplates.CoinsTemplate:Clone()

				template.Name = "Coins"..i
				template.Amount.Text = CommaNumber(WorldsConfig[highestWorld][4] * ShopConfig.CoinMultipliers[i])
				template.Price.Text = if marketInfo and marketInfo.PriceInRobux then CommaNumber(marketInfo.PriceInRobux) else "Failed to load"
				template.LayoutOrder = -i

				if marketInfo then
					template.Icon.Image = "rbxassetid://"..marketInfo.IconImageAssetId
				end

				template.Activated:Connect(function()
					Market:PromptProductPurchase(player, productID)
					GUIHandler:SetPurchaseLoading(true)
				end)

				template.Parent = shopContents.Coins.Contents.Group
			end
		end)
	end

	local boostPack = shopContents.Boosts.Contents.BoostPack

	local s, boostPackInfo = pcall(function()
		return Market:GetProductInfo(1241483963, Enum.InfoType.Product)
	end)

	boostPack.Buttons.Buy.TextLabel.Text = if (s and boostPackInfo) then boostPackInfo.PriceInRobux else "Failed to load"
	boostPack.Buttons.Buy.Activated:Connect(function()
		Market:PromptProductPurchase(player, 1241483963)
		GUIHandler:SetPurchaseLoading(true)
	end)

	for boostName, data in pairs(Boosts) do
		task.spawn(function()
			local fifteentemplate = RS.GUITemplates.BoostsTemplate:Clone()
			fifteentemplate.Name = boostName.."-15"
			fifteentemplate.Image = boostImgs[boostName]
			fifteentemplate.Time.Text = "15 Minutes"

			local hourtemplate = RS.GUITemplates.BoostsTemplate:Clone()
			hourtemplate.Name = boostName.."-60"
			hourtemplate.Image = boostImgs[boostName]
			hourtemplate.Time.Text = "60 Minutes"

			local fifteenInfo, hourInfo

			local s, e = pcall(function()
				fifteenInfo = Market:GetProductInfo(data["15mins"], Enum.InfoType.Product)
				hourInfo = Market:GetProductInfo(data["1hour"], Enum.InfoType.Product)
			end)

			fifteentemplate.Buttons.Buy.TextLabel.Text = if fifteenInfo then fifteenInfo.PriceInRobux else "Failed to load"
			hourtemplate.Buttons.Buy.TextLabel.Text = if hourInfo then hourInfo.PriceInRobux else "Failed to load"

			fifteentemplate.Buttons.Buy.Activated:Connect(function()
				Market:PromptProductPurchase(player, data["15mins"])
				GUIHandler:SetPurchaseLoading(true)
			end)

			fifteentemplate.Buttons.Use.Activated:Connect(function()
				local success, response = EventsHandler:ClientCall("UseItem", "Boosts", boostName.."-15")

				if success == true then
					main.Sounds.Others.Boost:Play()
				else
					if response == "DontHave" then
						NotificationHandler:SetOutput("You don't have any of these boosts")
						Market:PromptProductPurchase(player, data["15mins"])
						GUIHandler:SetPurchaseLoading(true)
					else
						NotificationHandler:SetOutput("Unknown error")
					end
				end
			end)


			hourtemplate.Buttons.Buy.Activated:Connect(function()
				Market:PromptProductPurchase(player, data["1hour"])
				GUIHandler:SetPurchaseLoading(true)
			end)

			hourtemplate.Buttons.Use.Activated:Connect(function()
				local success, response = EventsHandler:ClientCall("UseItem", "Boosts", boostName.."-60")

				if success == true then
					main.Sounds.Others.Boost:Play()
				else
					if response == "DontHave" then
						NotificationHandler:SetOutput("You don't have any of these boosts")
						Market:PromptProductPurchase(player, data["1hour"])
						GUIHandler:SetPurchaseLoading(true)
					else
						NotificationHandler:SetOutput("Unknown error")
					end
				end
			end)

			fifteentemplate.Parent = shopContents.Boosts.Contents
			hourtemplate.Parent = shopContents.Boosts.Contents
		end)
	end

	for rarity, productID in pairs(Heroes) do
		local template = RS.GUITemplates.FeaturedTemplate:Clone()

		local marketInfo
		local s, e = pcall(function()
			marketInfo = Market:GetProductInfo(productID, Enum.InfoType.Product)
		end)

		template.Name = rarity
		template.Rarity.Text = rarity
		template.Rarity.UIGradient.Color = rarities[rarity][1]
		template.UIGradient.Color = rarities[rarity][1]
		template.LayoutOrder = rarities[rarity][2]

		if marketInfo then
			template.HeroName.Text = marketInfo.Name
			template.Price.Text = marketInfo.PriceInRobux
		end

		template.Activated:Connect(function()
			Market:PromptProductPurchase(player, productID)
			GUIHandler:SetPurchaseLoading(true)
		end)

		template.Parent = shopContents:WaitForChild("Featured"):WaitForChild("Contents")
	end
	updateFeaturedHeroes(nil, true)

	EventsHandler:ClientCall("LoadInventory", true)

	for _, button in ipairs(shopFrame.Buttons:GetChildren()) do
		if not button:IsA("GuiButton") then continue end

		button.Activated:Connect(function()
			main.Sounds.Frames.Open:Play()
			ShopUIHandler:OpenFrame(button.Name)
		end)
	end

	shopFrame.Exit.Activated:Connect(function()
		GUIHandler:CloseFrame("Shop")
		ShopUIHandler:ResetGiftingPerson()
	end)
	
	TooltipHandler(menuButton, "Shop", 999)

	shopFrame.Gift.Activated:Connect(function()
		if ShopUIHandler.Gifting == nil then
			GUIHandler:OpenFrame("Gift")
		else
			ShopUIHandler:ResetGiftingPerson()
		end
	end)

	menuButton.Activated:Connect(function()
		if menuButton.Notification.Visible then
			menuButton.Notification.Visible = false
		end
		if shopFrame.Visible then
			GUIHandler:CloseFrame("Shop")
			ShopUIHandler:ResetGiftingPerson()
		else
			GUIHandler:OpenFrame("Shop")
		end
	end)

	hudleft:WaitForChild("Stats").Buy.Activated:Connect(function()
		if shopFrame.Visible then
			GUIHandler:CloseFrame("Shop")
			ShopUIHandler:ResetGiftingPerson()
		else
			GUIHandler:OpenFrame("Shop")
			ShopUIHandler:OpenFrame("Coins")
		end
	end)

	giftFrame.Exit.Activated:Connect(function()
		GUIHandler:OpenFrame("Shop")
	end)	

	script.Parent.Parent["Resolution Changed"].Event:Connect(UpdateScaling)

	Players.PlayerAdded:Connect(UpdateGift)
	Players.PlayerRemoving:Connect(function(plrLeaving)
		if ShopUIHandler.Gifting == plrLeaving then
			ShopUIHandler:ResetGiftingPerson()
		end
		UpdateGift()
	end)
	UpdateGift()

	RS.Modules:WaitForChild("GamepassStatus"):WaitForChild("Replicate").OnClientEvent:Connect(function()
		UpdateOwnedPasses(EventsHandler:ClientCall("GetOwnedPasses"))
	end)
	UpdateOwnedPasses(EventsHandler:ClientCall("GetOwnedPasses"))

	task.spawn(function()
		while true do
			-- Using % gives us the remainder, which in our case is how far into a day we are
			-- Now we can easily calculate how much time is left by subtracting a day (86,400 seconds)
			shopContents.Featured.ResetTimer.Text = "RESETS IN: "..FormatTime:AdaptiveTime(86400 - (math.floor(workspace:GetServerTimeNow()) % 86400))
			task.wait(1)
		end
	end)
end

return ShopUIHandler
1 Like

Where do you check if the Button is clicked? I cant seem to find it

1 Like

Do you know what I words I can lookup to find it in scripts? Sorry, my programmer quit on me, so I’m trying to do this on my own.

1 Like

You can try MouseButton1Click, anything that involves MouseButton or Click

1 Like

Here’s the GUIHandler, i think this is where it is.

local GUIHandler = {
	Queue = {},
	CurrentlyOpen = nil,
	ViewportSize = nil,
	ResolutionScale = nil
}

local RS = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Lighting = game:GetService("Lighting")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local MarketplaceService = game:GetService("MarketplaceService")
local Debris = game:GetService("Debris")
local SocialService = game:GetService("SocialService")

local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local main = playerGui:WaitForChild("Main")
local menus = main:WaitForChild("Menus")
local hudleft = main:WaitForChild("HUDLeft")
local hudright = main:WaitForChild("HUDRight")
local hudbottom = main:WaitForChild("HUDBottom")
local hudtop = main:WaitForChild("HUDTop")
local questsSidebar = main:WaitForChild("Quests")
local Tooltips = main:WaitForChild("Tooltips")
local hoverTooltips = Tooltips:WaitForChild("Hover")
local TopbarThing = main:WaitForChild("Topbar")

local effectCircle = RS:WaitForChild("Effects"):WaitForChild("Circle")

if playerGui:FindFirstChild("TouchGui") then
	hudbottom.Position = UDim2.fromScale(0.5, 0.95)
end

local CurrentCamera = workspace.CurrentCamera
local blur = Lighting:FindFirstChild("GUIBlur")

local TweenInformation = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local CloseTweenInformation = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)

local debounce = false

local EventsHandler = require(RS.Modules.EventsHandler)
local spr = require(RS.Modules.spr)
local TooltipHandler = require(script.Parent.TooltipHandler)
local Abbreviate = require(RS.Modules.AbbreviateHandler)
local CommaNumber = require(RS.Modules.CommaNumber)
local SoundHandler = require(RS.Modules.SoundHandler)

local menuPositions = {}

function GUIHandler:TweenOutMain()
	spr.target(questsSidebar, 0.9, 1, {
		Position = UDim2.fromScale(1.5, 0.575)
	})

	spr.target(hudbottom, 0.9, 1, {
		Position = UDim2.fromScale(0.5, 1.5)
	})
end

function GUIHandler:TweenInMain()
	spr.target(questsSidebar, 0.9, 1, {
		Position = UDim2.fromScale(1, 0.575)
	})

	spr.target(hudbottom, 0.9, 1, {
		Position = (if playerGui:FindFirstChild("TouchGui") then UDim2.fromScale(0.5, 0.95) else UDim2.fromScale(0.5, 0.97))
	})
end

function GUIHandler:TweenOutSides()
	spr.target(hudleft, 0.9, 1, {
		Position = UDim2.fromScale(-0.5, .575)
	})
	spr.target(hudright, 0.9, 1, {
		Position = UDim2.fromScale(1.5, .425)
	})
end

function GUIHandler:TweenInSides()
	spr.target(hudleft, 0.9, 1, {
		Position = UDim2.fromScale(0, .575)
	})
	spr.target(hudright, 0.9, 1, {
		Position = UDim2.fromScale(1, .425)
	})
end

function GUIHandler:AddToQueue(MenuName: string, NoSound: boolean?)
	table.insert(self.Queue, { MenuName, NoSound })
end

function GUIHandler:OpenFrame(FrameName: string, NoSound: boolean?)
	if self.CurrentlyOpen == FrameName then
		return GUIHandler:CloseFrame(self.CurrentlyOpen, false)
	end
	
	if not table.find({ "Trading" }, self.CurrentlyOpen) then
		GUIHandler:CloseFrame(self.CurrentlyOpen, true)
	end

	local FrameToFind = menus:FindFirstChild(FrameName)

	if not FrameToFind then
		return warn("Tried to open menu "..FrameName.." but it wasn't found")
	end

	self.CurrentlyOpen = FrameName

	FrameToFind.Position = UDim2.fromScale(0.5, 1.5)
	FrameToFind.Visible = true
	
	if not NoSound then
		main.Sounds.Frames.Open:Play()
	end

	if FrameName == "Heroes" then
		hudleft.Buttons.Top.Heroes.Notification.Visible = false
	end

	local openingDur = 4

	blur.Enabled = true
	spr.target(blur, 1.3, (openingDur + 1), {
		Size = 20
	})
	spr.target(FrameToFind, 1.3, openingDur, {
		Position = menuPositions[FrameName] or UDim2.fromScale(0.5, 0.5)
	})

	GUIHandler:TweenOutMain()
	if table.find({ "ChooseAbility", "StarterHeroes", "UpdateLog" }, FrameName) then
		GUIHandler:TweenOutSides()
	end
end

function GUIHandler:CloseFrame(FrameName, DontStopBlur, NoSound)
	if not FrameName then return end

	local FrameToFind = menus:FindFirstChild(FrameName)

	if not FrameToFind then
		return warn("Tried to close menu "..FrameName.." but it wasn't found")
	end

	if self.CurrentlyOpen == FrameName then
		self.CurrentlyOpen = nil
	end

	if not FrameToFind.Visible then return end
	
	if not NoSound then
		main.Sounds.Frames.Close:Play()
	end

	if #self.Queue > 0 then
		DontStopBlur = true
	end

	if DontStopBlur ~= true then
		spr.target(blur, 1.3, 5, {
			Size = 0
		})
	end
	spr.target(FrameToFind, 0.7, 1.2, {
		Position = UDim2.fromScale(0.5, 2)
	})

	GUIHandler:TweenInMain()
	GUIHandler:TweenInSides()

	if #self.Queue > 0 then
		GUIHandler:OpenFrame(self.Queue[1][1], self.Queue[1][2])
		table.remove(self.Queue, 1)
	end

	task.delay(.5, function()
		if FrameToFind.Position.Y.Scale < 2 then return end

		FrameToFind.Visible = false
		if DontStopBlur ~= true and GUIHandler.CurrentlyOpen == nil then
			blur.Enabled = false
		end
	end)
end

function GUIHandler:UpdateResolution()
	self.ViewportSize = CurrentCamera.ViewportSize
	self.ResolutionScale = math.clamp(self.ViewportSize.Magnitude / 1800, 0.33, 2)
	script.Parent["Resolution Changed"]:Fire(self.ViewportSize, self.ResolutionScale)
end

local function fadeHUD(fadeTime: number, toFade: table)
	for _, location in ipairs(toFade) do
		for _, desc in ipairs(location:GetChildren()) do
			if desc:IsA("ImageButton") or desc:IsA("ImageLabel") then
				TweenService:Create(desc, TweenInfo.new(fadeTime), {
					ImageTransparency = if desc.ImageTransparency == 0 then 1 else 0
				}):Play()
			end
		end
	end
end

local bouncing = false
local function coinBounce()
	if bouncing then return end
	bouncing = true
	local oldSize = hudleft.Stats.Size
	hudleft.Stats.Size += UDim2.fromScale(hudleft.Stats.Size.X.Scale * 0.1, hudleft.Stats.Size.Y.Scale * 0.1)
	local tween = TweenService:Create(hudleft.Stats, TweenInfo.new(0.25, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out), {
		Size = oldSize
	})
	tween.Completed:Connect(function()
		bouncing = false
		tween:Destroy()
	end)
	tween:Play()
end

local lastCoins
local coinsEffect = hudleft:WaitForChild("Stats"):WaitForChild("Stat Bar"):WaitForChild("Coin")

function GUIHandler:MakeCoinPopup(Amount: number)
	local effect = coinsEffect:Clone()

	effect.Visible = true
	effect.Position = UDim2.fromScale((math.random(150, 300) / 100), (math.random(-100, 150) / 100))
	effect.Size = UDim2.new()
	effect.TextLabel.Text = Abbreviate(Amount)
	
	effect.Parent = coinsEffect.Parent

	task.spawn(function()
		local sizeNum = math.random(70, 90) / 100

		TweenService:Create(effect, TweenInfo.new(0.5, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut), { Size = UDim2.fromScale(sizeNum, sizeNum) }):Play()

		task.wait(0.6)

		TweenService:Create(effect, TweenInfo.new(0.9, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut), { Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.new() }):Play()

		task.wait(0.9)
		coinBounce()
		effect:Destroy()
	end)
end

local function createCoinEffect(newStat)
	local effect = coinsEffect:Clone()

	effect.Visible = true
	effect.Position = UDim2.fromScale((math.random(150, 300) / 100), (math.random(-100, 150) / 100))
	effect.Size = UDim2.new()

	if lastCoins then
		effect.TextLabel.Text = Abbreviate(newStat - lastCoins)
	end
	if lastCoins and (newStat - lastCoins) <= 0 then
		lastCoins = newStat
		return
	end
	lastCoins = newStat

	effect.Parent = coinsEffect.Parent

	task.spawn(function()
		local sizeNum = math.random(70, 90) / 100

		TweenService:Create(effect, TweenInfo.new(0.5, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut), { Size = UDim2.fromScale(sizeNum, sizeNum) }):Play()

		task.wait(0.6)

		TweenService:Create(effect, TweenInfo.new(0.9, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut), { Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.new() }):Play()

		task.wait(0.9)
		coinBounce()
		effect:Destroy()
	end)
end

local function UpdateEggBillboard(newStat)
	local EggHandler = require(script.Parent.EggHandler)
	EggHandler:UpdateBillboards(newStat)
end

local destroyCoinTooltip
local unitTooltips = {}
local gemTooltip
local function statChanged(stat, newStat)
	if stat == "Coins" then
		hudleft:WaitForChild("Stats"):WaitForChild("Stat Bar"):WaitForChild("CoinsValue").Value = newStat
		UpdateEggBillboard(newStat)
		createCoinEffect(newStat)
		task.wait(1.625)
		hudleft:WaitForChild("Stats"):WaitForChild("Stat Bar"):WaitForChild("TextLabel").Text = Abbreviate(newStat)
		if hoverTooltips:FindFirstChild("coinTooltip") then
			hoverTooltips.coinTooltip.Text = CommaNumber(newStat).." coins"
		end
		if destroyCoinTooltip then
			destroyCoinTooltip()
		end
		destroyCoinTooltip = TooltipHandler(hudleft:WaitForChild("Stats"):WaitForChild("Stat Bar"):WaitForChild("TextLabel"), CommaNumber(newStat).." coins", 1, "coinTooltip")
	elseif stat == "Units" then
		for _, panelName in ipairs({ "AbilitySpin", "DungeonShop", "MountsShop" }) do
			menus:WaitForChild(panelName):WaitForChild("CurrencyDisplay"):WaitForChild("Value").Text = Abbreviate(newStat)
			if hoverTooltips:FindFirstChild("unitTooltip") then
				hoverTooltips.unitTooltip.Text = CommaNumber(newStat).." units"
			end
			if unitTooltips[panelName] then
				unitTooltips[panelName]()
			end
			unitTooltips[panelName] = TooltipHandler(menus[panelName].CurrencyDisplay:FindFirstChild("Value"), CommaNumber(newStat).." units", 3, "unitTooltip")
		end
	elseif stat == "Gems" then
		hudleft:WaitForChild("StatsGems"):WaitForChild("Stat Bar"):WaitForChild("GemsValue").Value = newStat
		hudleft:WaitForChild("StatsGems"):WaitForChild("Stat Bar"):WaitForChild("TextLabel").Text = Abbreviate(newStat)
		if hoverTooltips:FindFirstChild("gemsTooltip") then
			hoverTooltips.gemsTooltip.Text = CommaNumber(newStat).." gems"
		end
		if gemTooltip then
			gemTooltip()
		end
		gemTooltip = TooltipHandler(hudleft:WaitForChild("StatsGems"):WaitForChild("Stat Bar"):WaitForChild("TextLabel"), CommaNumber(newStat).." gems", 2, "gemsTooltip")
	end
end

local alreadyCountingDown = false
function GUIHandler:SetPurchaseLoading(state, wasPurchased)
	if state and not self.loadConn then
		self.loadConn = RunService.RenderStepped:Connect(function()
			main.PurchaseLoading.Loading.Rotation += 3
		end)

		main.PurchaseLoading.Visible = true
		main.Sounds.Others.Purchase:Play()

		if alreadyCountingDown == false then
			task.delay(20, function()
				self:SetPurchaseLoading(false)
			end)
		end
	elseif not state and self.loadConn then
		main.PurchaseLoading.Visible = false
		if wasPurchased then main.Sounds.Egg.Purchase:Play() end

		self.loadConn:Disconnect()
		self.loadConn = nil

		alreadyCountingDown = false
	end
end

local function ClickExplosion()
	local Mouse = player:GetMouse()
	for i = 1, 20 do
		local Circle = effectCircle:Clone()
		Circle.Position = UDim2.fromOffset(Mouse.X, Mouse.Y)
		Circle.Parent = Tooltips

		Debris:AddItem(Circle, 0.3)

		local XFactor = math.random(-5, 5) / 100
		local YFactor = math.random(-5, 5) / 100

		TweenService:Create(Circle,  TweenInfo.new(.3), {
			Position = Circle.Position + UDim2.fromScale(XFactor, YFactor),
			Size = UDim2.new()
		}):Play()
	end
end

function GUIHandler:BoostEnded(BoostName: string)
	if not BoostName or type(BoostName) ~= "string" then
		return warn("[GUIHandler] Boost name is nil or not a string. Boost name: "..tostring(BoostName))
	end

	local RealBoostName, BoostID = (function()
		if table.find({ "Coins", "Coins-15", "Coins-60" }, BoostName) then
			return "Coin Boost", 1231927212
		elseif table.find({ "Luck", "Luck-15", "Luck-60" }, BoostName) then
			return "Luck Boost", 1231927346
		elseif table.find({ "Damage", "Damage-15", "Damage-60" }, BoostName) then
			return "Damage Boost", 1231927065
		elseif table.find({ "XP", "XP-15", "XP-60" }, BoostName) then
			return "XP Boost", "Dungeons Hub"
		elseif table.find({ "Speed", "Speed-15", "Speed-60" }, BoostName) then
			return "Speed Boost", "Dungeons Hub"
		elseif table.find({ "Coins4x", "Coins4x-15", "Coins4x-60" }, BoostName) then
			return "Super Coin Boost", "Dungeons Hub"
		elseif table.find({ "Damage4x", "Damage4x-15", "Damage4x-60" }, BoostName) then
			return "Super Damage Boost", "Dungeons Hub"
		elseif table.find({ "Luck4x", "Luck4x-15", "Luck4x-60" }, BoostName) then
			return "Super Luck Boost", "Dungeons Hub"
		end
	end)()
	if not (RealBoostName and BoostID) then
		return warn("[GUIHandler] Failed check for real boost name and boost id. Boost name: "..tostring(BoostName))
	end
	
	if self.CurrentlyOpen ~= nil then
		task.spawn(function()
			self:CloseFrame(self.CurrentlyOpen, false)
		end)
	end

	local ConfirmationUI = require(script.ConfirmationUIHandler)
	ConfirmationUI(
		"BOOST ENDED",
		"Your ".. RealBoostName .." ended! Would you like to buy more?",
		Color3.new(0, 1, 0),
		tostring(BoostID) ~= "Dungeons Hub",
		function()
			if tostring(BoostID) == "Dungeons Hub" then
				EventsHandler:ClientCall("Teleport", "Dungeons Hub")
			else
				self:SetPurchaseLoading(true)
				MarketplaceService:PromptProductPurchase(player, BoostID)

				GUIHandler:OpenFrame("Shop")
			end
		end,
		function()
			spr.target(blur, 1.3, 5, {
				Size = 0
			})
		end,
		true
	)
end

local function MakeTween(Object: Instance, Time: number, Key: string, Value: any): Tween
	local TweenInformation = TweenInfo.new(Time, Enum.EasingStyle.Quint, Enum.EasingDirection.Out);
	local TweenData = { [Key] = Value };
	local Tween = TweenService:Create(Object, TweenInformation, TweenData);
	Tween.Completed:Connect(function()
		if Tween then
			Tween:Destroy();
		end
	end);
	Tween:Play();
	return Tween;
end

function GUIHandler:ButtonAnimations(Object)
	if not Object:IsA("GuiButton") or Object:GetAttribute("ignoreEffects") or Object:GetAttribute("IgnoreEffects") then return end
	
	local TweenScale = Object:IsA("GuiButton") and Object:GetAttribute("TweenScale");
	local UIScale = TweenScale and Object:FindFirstChildWhichIsA("UIScale");
	
	if not UIScale then
		-- warn("[GUIHandler] Button '".. Object:GetFullName() .."' has no TweenScale attribute or UIScale parented in it.")
		return
	end
	
	Object.MouseEnter:Connect(function()
		MakeTween(UIScale, 0.2, "Scale", 1.1);
	end);
	
	Object.MouseLeave:Connect(function()
		MakeTween(UIScale, 0.2, "Scale", 1);
	end);
	
	Object.MouseButton1Down:Connect(function()
		MakeTween(UIScale, 0.2, "Scale", TweenScale);
	end);

	Object.MouseButton1Up:Connect(function()
		MakeTween(UIScale, 0.2, "Scale", 1);
	end);
end

function GUIHandler:Init()
	EventsHandler:ClientListen("StatChanged", statChanged)
	
	EventsHandler:ClientListen("CoinPopup", function(...)
		self:MakeCoinPopup(...)
	end)

	EventsHandler:ClientListen("PurchaseLoading", function(state)
		self:SetPurchaseLoading(state)
	end)

	EventsHandler:ClientListen("BoostEnded", function(...)
		self:BoostEnded(...)
	end)
	
	EventsHandler:ClientListen("PlaySound", function(SoundName)
		SoundHandler:PlaySound(SoundName)
	end)

	MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(_, _, wasPurchased)
		self:SetPurchaseLoading(false, wasPurchased)
	end)

	-- deprecated but the only way to detect dev product finishing... smh roblox
	MarketplaceService.PromptProductPurchaseFinished:Connect(function(_, _, wasPurchased)
		self:SetPurchaseLoading(false, wasPurchased)
	end)

	for _, menu in ipairs(menus:GetChildren()) do
		if menu.Name == "NPCDialogue" then continue end
		menuPositions[menu.Name] = menu.Position
		menu.Position = UDim2.fromScale(menu.Position.X.Scale, 2)
	end
	
	local buttons = {}
	for _, button in ipairs(hudleft:WaitForChild("Buttons"):GetDescendants()) do
		if button:IsA("GuiButton") and button.Name ~= "Minimize" then
			table.insert(buttons, button)
		end
	end
	for _, button in ipairs(hudright:WaitForChild("Buttons"):GetDescendants()) do
		if button:IsA("GuiButton") and button.Name ~= "Minimize" then
			table.insert(buttons, button)
		end
	end
	table.insert(buttons, hudtop:WaitForChild("Gifts"))

	for _, button in ipairs(buttons) do
		local isDown = false
		
		local y1, y2
		if button.Name == "DailySpin" or button.Name == "Mounts" or button.Name == "Trade" then
			y1, y2 = .4, .425
		elseif button.Name == "Gifts" then
			y1, y2 = .75, .8
		else	
			y1, y2 = 1, 1.05
		end
		
		button.MouseButton1Down:Connect(function()
			spr.target(button, 0.75, 2.1, {
				Size = UDim2.fromScale(.275, y1) 
			})
			ClickExplosion()
			isDown = true
		end)

		button.MouseButton1Up:Connect(function()
			spr.target(button, 0.75, 2.1, {
				Size = UDim2.fromScale(.3, y1) 
			})
			isDown = false
		end)

		button.MouseEnter:Connect(function()
			spr.target(button, 0.75, 2.1, {
				Size = UDim2.fromScale(.325, y2)
			})
			isDown = true
		end)

		button.MouseLeave:Connect(function()
			if not isDown then return end
			spr.target(button, 0.75, 2.1, {
				Size = UDim2.fromScale(.3, y1) 
			})
			isDown = false
		end)
	end
	
	--// Descendants Initialization
	for _, Descendant in ipairs(main:GetDescendants()) do
		self:ButtonAnimations(Descendant);
	end;
	
	playerGui.DescendantAdded:Connect(function(Descendant)
		self:ButtonAnimations(Descendant);
	end);

	hudleft.Buttons.Minimize.Activated:Connect(function()
		TweenService:Create(hudleft, TweenInfo.new(.5), {
			AnchorPoint = if hudleft.AnchorPoint == Vector2.new(0, 0.5) then Vector2.new(0.765, 0.5) else Vector2.new(0, 0.5)
		}):Play()
		fadeHUD(.5, { hudleft.Stats, hudleft.Buttons.Top })
		hudleft.Buttons.Minimize.Image = if hudleft.Buttons.Minimize.Image == "rbxassetid://9467713221" then "rbxassetid://9467713159" else "rbxassetid://9467713221"
	end)
	
	hudright.Buttons.Minimize.Activated:Connect(function()
		TweenService:Create(hudright, TweenInfo.new(.5), {
			AnchorPoint = if hudright.AnchorPoint == Vector2.new(1, 0.5) then Vector2.new(0.72, 0.5) else Vector2.new(1, 0.5)
		}):Play()
		fadeHUD(.5, { hudright.Buttons.Top })
		hudright.Buttons.Minimize.Image = if hudright.Buttons.Minimize.Image == "rbxassetid://9467713221" then "rbxassetid://9467713159" else "rbxassetid://9467713221"
	end)

	local SettingsUIHandler = require(script.SettingsUIHandler)
	hudbottom.AutoClicker.Activated:Connect(function()
		SettingsUIHandler:UpdateSetting("AutoClicker", not SettingsUIHandler.Settings.AutoClicker, true)
	end)

	EventsHandler:ClientListen("HeroesNotification", function()
		hudleft.Buttons.Top.Heroes.Notification.Visible = true
	end)

	CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
		self:UpdateResolution()
	end)

	UIS.WindowFocused:Connect(function()
		self:UpdateResolution()
	end)
	
	TopbarThing.Friends.Activated:Connect(function()
		if SocialService:CanSendGameInviteAsync(player) then
			SocialService:PromptGameInvite(player)
		end
	end)
	
	UIS.InputBegan:Connect(function(input, processed)
		if not processed and input.KeyCode == Enum.KeyCode.ButtonB then
			if self.CurrentlyOpen ~= nil then
				self:CloseFrame(self.CurrentlyOpen)
			end
		end
	end)
	
	TooltipHandler(hudbottom.Ability, "Ability", 11)
	TooltipHandler(hudbottom.Click, "Click", 11)
	TooltipHandler(hudbottom.AutoClicker, "Auto Clicker", 11)
	TooltipHandler(TopbarThing.Stats, "Stats", 11)
	TooltipHandler(TopbarThing.Friends, "Invite Friends", 11)
	TooltipHandler(TopbarThing.UpdateVersion, "Update Log", 11)
end

function GUIHandler:ToggleProximityPrompt(prompt, state, offset)
	prompt.Style = (state and Enum.ProximityPromptStyle.Default or Enum.ProximityPromptStyle.Custom)
	prompt.UIOffset = (state and (offset or Vector2.new(0, 0)) or Vector2.new(0, -math.huge))
	prompt.Enabled = state
end

function GUIHandler:ToggleSpecialGUI(state, exceptions)
	for _, set in ipairs({ workspace.Characters:GetDescendants(), workspace.Heroes:GetDescendants(), workspace.Enemies:GetDescendants() }) do
		for _, item in ipairs(set) do
			if not item:IsA("BillboardGui") and not item:IsA("ProximityPrompt") then continue end

			if exceptions then
				local isException = false
				for _, exception in ipairs(exceptions) do
					if item == exception or item:IsDescendantOf(exception) then
						isException = true
						break
					end
				end
				if isException then continue end
			end

			if state then
				local previousState = item:GetAttribute("previousToggleState")
				if not previousState then continue end

				if item:IsA("ProximityPrompt") then
					self:ToggleProximityPrompt(item, true, previousState)
				elseif item:IsA("BillboardGui") then
					item.Enabled = previousState
				end
			else
				if item:IsA("ProximityPrompt") then
					item:SetAttribute("previousToggleState", item.UIOffset)
					self:ToggleProximityPrompt(item, false)
				elseif item:IsA("BillboardGui") then
					item:SetAttribute("previousToggleState", item.Enabled)
					item.Enabled = false
				end
			end
		end
	end
end

return GUIHandler

Where is it in here, I don’t see it

I think it might be .Activated

Yeah I think your right, look into this thing called TouchTap, its made for buttons and is for mobile

https://create.roblox.com/docs/reference/engine/classes/UserInputService#TouchTap