local z=game:GetService("\084\101\120\116\083\101\114\118\105\099\101")local A=game:GetService("\082\117\110\083\101\114\118\105\099\101")local Y=game:GetService("\076\105\103\104\116\105\110\103")local m=(script:FindFirstAncestor("\067\109\100\114\065\100\100\105\116\105\111\110\115")).Packages local W=(script:FindFirstAncestor("\085\073")).Components local a=require(m.Roact)local H=require(m.Flipper)local X=require(m.RoactFlipper)local F=require(m.Util)local h=require(W.RadialProgress)local P=require(W.RoundedRectangle)local O=480 local r=Vector2.new(22,19)local function n(z)return 8 end local c=a.PureComponent:extend("\077\101\115\115\097\103\101\069\118\101\110\116")c.listenTo="\083\104\111\119\071\108\111\098\097\108\077\101\115\115\097\103\101"c.maxQuantity=1 function c.init(z)z.Motor=H.SingleMotor.new(0)z.TimeRemaining,z.SetTimeRemaining=a.createBinding(0)local A=z.props.Data z.ActiveTime=A.Duration or n(A.Text)end function c.didMount(z)z.Motor:setGoal(H.Spring.new(1,{frequency=6,dampingRatio=1.2}))local Y=tick()z.RenderListener=A.RenderStepped:Connect(function()local A=z.ActiveTime-math.clamp(tick()-Y,0,z.ActiveTime)if A==0 and z.props.Active then z:close()z.RenderListener:Disconnect()end z.SetTimeRemaining(A)end)end function c.close(z)if not z.IsClosing then z.IsClosing=true z.Motor:setGoal(H.Spring.new(0,{frequency=4,dampingRatio=.75}))z.Motor:onComplete(z.props.Destroy)end end function c.didUpdate(A,z)if A.props.Active~=z.Active and not A.props.Active then A:close()end end function c.willUnmount(z)if z.RenderListener then z.RenderListener:Disconnect()end end function c.render(A)local m=A.props.Data local W=z:GetTextSize(m.Content,26,Enum.Font.Gotham,Vector2.new(O,math.huge))local H=W.Y/26 W=W+Vector2.new(0,5.2*(H-1))local n=(X.getBinding(A.Motor)):map(function(z)return 1-z end)return a.createElement("\070\114\097\109\101",{BackgroundColor3=Color3.new(0,0,0);BackgroundTransparency=n:map(function(z)return F.Math.lerp(.5,1,z)end);Size=UDim2.new(1,0,1,0),LayoutOrder=1;BorderSizePixel=0},{Content=a.createElement(P,{Radius=12,Color=Color3.new(0,0,0),Transparency=n:map(function(z)return F.Math.lerp(.5,1,z)end),Size=UDim2.new(0,O+r.X*2,0,W.Y+r.Y*2)},{Text=a.createElement("\084\101\120\116\076\097\098\101\108",{Text=m.Content;Font=Enum.Font.Gotham,TextSize=26;LineHeight=1.2,TextColor3=Color3.new(1,1,1),TextTransparency=n,TextXAlignment=Enum.TextXAlignment.Left,TextWrapped=true,Size=UDim2.new(1,0,1,0);BackgroundTransparency=1});Padding=a.createElement("\085\073\080\097\100\100\105\110\103",{PaddingLeft=UDim.new(0,r.X),PaddingRight=UDim.new(0,r.X);PaddingTop=UDim.new(0,r.Y);PaddingBottom=UDim.new(0,r.Y)})}),Footer=a.createElement("\070\114\097\109\101",{Size=UDim2.new(0,O+r.X*2,0,44),BackgroundTransparency=1},{Author=m.Author and a.createElement("\070\114\097\109\101",{Size=UDim2.new(1,0,1,0);BackgroundTransparency=1},{Avatar=a.createElement("\070\114\097\109\101",{Size=UDim2.new(0,44,0,44);LayoutOrder=1;BackgroundTransparency=1},{Image=a.createElement("\073\109\097\103\101\076\097\098\101\108",{Image=("\114\098\120\116\104\117\109\098\058\047\047\116\121\112\101\061\065\118\097\116\097\114\072\101\097\100\083\104\111\116\038\105\100\061\037\100\038\119\061\054\048\038\104\061\054\048"):format(m.Author.Player.UserId),ImageTransparency=n,Size=UDim2.new(1,0,1,0),BackgroundTransparency=1},{Corner=a.createElement("\085\073\067\111\114\110\101\114",{CornerRadius=UDim.new(.5,0)})});Background=a.createElement("\073\109\097\103\101\076\097\098\101\108",{Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\050\054\048\048\056\052\053\055\051\052",ImageColor3=Color3.new(0,0,0),ImageTransparency=n:map(function(z)return F.Math.lerp(.7,1,z)end);Size=UDim2.new(1,0,1,0);ZIndex=0,BackgroundTransparency=1})});Details=a.createElement("\070\114\097\109\101",{Size=UDim2.new(1,0,1,0),LayoutOrder=2;BackgroundTransparency=1},{Name=a.createElement("\084\101\120\116\076\097\098\101\108",{Text=m.Author.Player.Name;Font=Enum.Font.GothamBold;TextSize=18;TextColor3=Color3.new(1,1,1);TextTransparency=n,TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,0,0,18),LayoutOrder=1,BackgroundTransparency=1}),Role=a.createElement("\084\101\120\116\076\097\098\101\108",{Text=m.Author.Role,Font=Enum.Font.Gotham;TextSize=14;TextColor3=Color3.new(1,1,1),TextTransparency=n;TextXAlignment=Enum.TextXAlignment.Left,Size=UDim2.new(1,0,0,14),LayoutOrder=2;BackgroundTransparency=1}),Layout=a.createElement("\085\073\076\105\115\116\076\097\121\111\117\116",{VerticalAlignment=Enum.VerticalAlignment.Center,FillDirection=Enum.FillDirection.Vertical;SortOrder=Enum.SortOrder.LayoutOrder,Padding=UDim.new(0,4)})});Layout=a.createElement("\085\073\076\105\115\116\076\097\121\111\117\116",{VerticalAlignment=Enum.VerticalAlignment.Center,FillDirection=Enum.FillDirection.Horizontal,SortOrder=Enum.SortOrder.LayoutOrder,Padding=UDim.new(0,15)})}),Timer=a.createElement("\070\114\097\109\101",{Size=UDim2.new(0,18,0,18);Position=UDim2.new(1,0,.5,0);AnchorPoint=Vector2.new(1,.5);BackgroundTransparency=1},{Text=a.createElement("\084\101\120\116\076\097\098\101\108",{Text=A.TimeRemaining:map(math.ceil);Font=Enum.Font.GothamBold,TextSize=14;TextColor3=Color3.new(1,1,1),TextTransparency=n,TextXAlignment=Enum.TextXAlignment.Right,Size=UDim2.new(1,0,1,0);Position=UDim2.new(0,-8,0,0),AnchorPoint=Vector2.new(1,0),BackgroundTransparency=1}),Progress=a.createElement(h,{Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\053\052\048\057\057\057\048\052\056\052";ImageTransparency=value,ImageSize=Vector2.new(36,36);Size=UDim2.new(1,0,1,0);Value=A.TimeRemaining:map(function(z)return z/A.ActiveTime end)}),Background=a.createElement("\073\109\097\103\101\076\097\098\101\108",{Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\053\052\048\057\057\057\048\052\056\052",ImageTransparency=n:map(function(z)return F.Math.lerp(.7,1,z)end);Size=UDim2.new(1,0,1,0),ZIndex=0,BackgroundTransparency=1})})});LightingEffects=a.createElement(a.Portal,{target=Y},{Blur=a.createElement("\066\108\117\114\069\102\102\101\099\116",{Size=(X.getBinding(A.Motor)):map(function(z)return F.Math.lerp(0,24,z)end)})}),Layout=a.createElement("\085\073\076\105\115\116\076\097\121\111\117\116",{HorizontalAlignment=Enum.HorizontalAlignment.Center;VerticalAlignment=Enum.VerticalAlignment.Center;FillDirection=Enum.FillDirection.Vertical,SortOrder=Enum.SortOrder.LayoutOrder;Padding=UDim.new(0,20)})})end return c
local TextService = game:GetService("TextService")
local RunService = game:GetService("RunService")
local Lighting = game:GetService("Lighting")

local Packages = script:FindFirstAncestor("CmdrAdditions").Packages
local Components = script:FindFirstAncestor("UI").Components

local Roact = require(Packages.Roact)
local Flipper = require(Packages.Flipper)
local RoactFlipper = require(Packages.RoactFlipper)
local Utility =  require(Packages.Util)

local RadialProgress = require(Components.RadialProgress)
local RoundedRectangle = require(Components.RoundedRectangle)

local TEXT_MAX_WIDTH = 480
local CONTENT_PADDING = Vector2.new(22, 19)

local function GetActiveTime(text)
	return 8 -- todo: calculate based on text length
end

local MessageEvent = Roact.PureComponent:extend("MessageEvent")

MessageEvent.listenTo = "ShowGlobalMessage"
MessageEvent.maxQuantity = 1

function MessageEvent:init()
	self.Motor = Flipper.SingleMotor.new(0)
	self.TimeRemaining, self.SetTimeRemaining = Roact.createBinding(0)

	local data = self.props.Data
	self.ActiveTime = data.Duration or GetActiveTime(data.Text)
end

function MessageEvent:didMount()
	self.Motor:setGoal(
		Flipper.Spring.new(1, {
			frequency = 6,
			dampingRatio = 1.2
		})
	)

	local initTime = tick()
	self.RenderListener = RunService.RenderStepped:Connect(function()
		local timeRemaining = self.ActiveTime - math.clamp(tick() - initTime, 0, self.ActiveTime)

		if timeRemaining == 0 and self.props.Active then
			self:close()
			self.RenderListener:Disconnect()
		end

		self.SetTimeRemaining(timeRemaining)
	end)
end

function MessageEvent:close()
	if not self.IsClosing then
		self.IsClosing = true

		self.Motor:setGoal(
			Flipper.Spring.new(0, {
				frequency = 4,
				dampingRatio = 0.75
			})
		)

		self.Motor:onComplete(self.props.Destroy)
	end
end

function MessageEvent:didUpdate(lastProps)
	if self.props.Active ~= lastProps.Active and not self.props.Active then
		self:close()
	end
end

function MessageEvent:willUnmount()
	if self.RenderListener then
		self.RenderListener:Disconnect()
	end
end

function MessageEvent:render()
	local data = self.props.Data

	local textBounds = TextService:GetTextSize(
		data.Content, 26, Enum.Font.Gotham,
		Vector2.new(TEXT_MAX_WIDTH, math.huge)
	)
	local lineCount = textBounds.Y / 26
	textBounds = textBounds + Vector2.new(0, (26 * 0.2) * (lineCount - 1))

	local transparency = RoactFlipper.getBinding(self.Motor):map(function(value)
		return 1 - value
	end)

	return Roact.createElement("Frame", {
		BackgroundColor3 = Color3.new(0, 0, 0),
		BackgroundTransparency = transparency:map(function(value)
			return Utility.Math.lerp(0.5, 1, value)
		end),

		Size = UDim2.new(1, 0, 1, 0),

		LayoutOrder = 1,
		BorderSizePixel = 0
	}, {
		Content = Roact.createElement(RoundedRectangle, {
			Radius = 12,
			Color = Color3.new(0, 0, 0),
			Transparency = transparency:map(function(value)
				return Utility.Math.lerp(0.5, 1, value)
			end),

			Size = UDim2.new(0, TEXT_MAX_WIDTH + CONTENT_PADDING.X * 2, 0, textBounds.Y + CONTENT_PADDING.Y * 2)
		}, {
			Text = Roact.createElement("TextLabel", {
				Text = data.Content,
				Font = Enum.Font.Gotham,
				TextSize = 26,
				LineHeight = 1.2,
				TextColor3 = Color3.new(1, 1, 1),
				TextTransparency = transparency,
				TextXAlignment = Enum.TextXAlignment.Left,
				TextWrapped = true,
				
				Size = UDim2.new(1, 0, 1, 0),

				BackgroundTransparency = 1
			}),

			Padding = Roact.createElement("UIPadding", {
				PaddingLeft = UDim.new(0, CONTENT_PADDING.X),
				PaddingRight = UDim.new(0, CONTENT_PADDING.X),
				PaddingTop = UDim.new(0, CONTENT_PADDING.Y),
				PaddingBottom = UDim.new(0, CONTENT_PADDING.Y)
			})
		}),

		Footer = Roact.createElement("Frame", {
			Size = UDim2.new(0, TEXT_MAX_WIDTH + CONTENT_PADDING.X * 2, 0, 44),
			BackgroundTransparency = 1
		}, {
			Author = data.Author and Roact.createElement("Frame", {
				Size = UDim2.new(1, 0, 1, 0),
				BackgroundTransparency = 1
			}, {
				Avatar = Roact.createElement("Frame", {
					Size = UDim2.new(0, 44, 0, 44),
					LayoutOrder = 1,
					BackgroundTransparency = 1
				}, {
					Image = Roact.createElement("ImageLabel", {
						Image = ("rbxthumb://type=AvatarHeadShot&id=%d&w=60&h=60"):format(data.Author.Player.UserId),
						ImageTransparency = transparency,

						Size = UDim2.new(1, 0, 1, 0),

						BackgroundTransparency = 1
					}, {
						Corner = Roact.createElement("UICorner", {
							CornerRadius = UDim.new(0.5, 0)
						})
					}),
					
					Background = Roact.createElement("ImageLabel", {
						Image = "rbxassetid://2600845734",
						ImageColor3 = Color3.new(0, 0, 0),
						ImageTransparency = transparency:map(function(value)
							return Utility.Math.lerp(0.7, 1, value)
						end),

						Size = UDim2.new(1, 0, 1, 0),

						ZIndex = 0,
						BackgroundTransparency = 1
					})
				}),

				Details = Roact.createElement("Frame", {
					Size = UDim2.new(1, 0, 1, 0),
					LayoutOrder = 2,
					BackgroundTransparency = 1
				}, {
					Name = Roact.createElement("TextLabel", {
						Text = data.Author.Player.Name,
						Font = Enum.Font.GothamBold,
						TextSize = 18,
						TextColor3 = Color3.new(1, 1, 1),
						TextTransparency = transparency,
						TextXAlignment = Enum.TextXAlignment.Left,

						Size = UDim2.new(1, 0, 0, 18),
						
						LayoutOrder = 1,
						BackgroundTransparency = 1
					}),

					Role = Roact.createElement("TextLabel", {
						Text = data.Author.Role,
						Font = Enum.Font.Gotham,
						TextSize = 14,
						TextColor3 = Color3.new(1, 1, 1),
						TextTransparency = transparency,
						TextXAlignment = Enum.TextXAlignment.Left,

						Size = UDim2.new(1, 0, 0, 14),
						
						LayoutOrder = 2,
						BackgroundTransparency = 1
					}),

					Layout = Roact.createElement("UIListLayout", {
						VerticalAlignment = Enum.VerticalAlignment.Center,
						FillDirection = Enum.FillDirection.Vertical,
						SortOrder = Enum.SortOrder.LayoutOrder,
						Padding = UDim.new(0, 4)
					})
				}),

				Layout = Roact.createElement("UIListLayout", {
					VerticalAlignment = Enum.VerticalAlignment.Center,
					FillDirection = Enum.FillDirection.Horizontal,
					SortOrder = Enum.SortOrder.LayoutOrder,
					Padding = UDim.new(0, 15)
				})
			}),

			Timer = Roact.createElement("Frame", {
				Size = UDim2.new(0, 18, 0, 18),
				Position = UDim2.new(1, 0, 0.5, 0),
				AnchorPoint = Vector2.new(1, 0.5),

				BackgroundTransparency = 1
			}, {
				Text = Roact.createElement("TextLabel", {
					Text = self.TimeRemaining:map(math.ceil),
					Font = Enum.Font.GothamBold,
					TextSize = 14,
					TextColor3 = Color3.new(1, 1, 1),
					TextTransparency = transparency,
					TextXAlignment = Enum.TextXAlignment.Right,

					Size = UDim2.new(1, 0, 1, 0),
					Position = UDim2.new(0, -8, 0, 0),
					AnchorPoint = Vector2.new(1, 0),

					BackgroundTransparency = 1
				}),

				Progress = Roact.createElement(RadialProgress, {
					Image = "rbxassetid://5409990484",
					ImageTransparency = value,
					ImageSize = Vector2.new(36, 36),

					Size = UDim2.new(1, 0, 1, 0),

					Value = self.TimeRemaining:map(function(value)
						return value / self.ActiveTime
					end)
				}),

				Background = Roact.createElement("ImageLabel", {
					Image = "rbxassetid://5409990484",
					ImageTransparency = transparency:map(function(value)
						return Utility.Math.lerp(0.7, 1, value)
					end),

					Size = UDim2.new(1, 0, 1, 0),

					ZIndex = 0,
					BackgroundTransparency = 1
				})
			})
		}),

		LightingEffects = Roact.createElement(Roact.Portal, {
			target = Lighting
		}, {
			Blur = Roact.createElement("BlurEffect", {
				Size = RoactFlipper.getBinding(self.Motor):map(function(value)
					return Utility.Math.lerp(0, 24, value)
				end)
			})
		}),

		Layout = Roact.createElement("UIListLayout", {
			HorizontalAlignment = Enum.HorizontalAlignment.Center,
			VerticalAlignment = Enum.VerticalAlignment.Center,
			FillDirection = Enum.FillDirection.Vertical,
			SortOrder = Enum.SortOrder.LayoutOrder,
			Padding = UDim.new(0, 20)
		})
	})
end

return MessageEvent