From cf5e13f5a08eaee4a77bd17731ceaa830dfe266b Mon Sep 17 00:00:00 2001 From: boatbomber Date: Wed, 4 Jan 2023 19:37:37 -0500 Subject: [PATCH] Add api conflict popup --- plugin/src/App/ConflictAPIPopup.lua | 121 ++++++++++++++++++++++++++++ plugin/src/App/init.lua | 52 ++++++++++-- 2 files changed, 167 insertions(+), 6 deletions(-) create mode 100644 plugin/src/App/ConflictAPIPopup.lua diff --git a/plugin/src/App/ConflictAPIPopup.lua b/plugin/src/App/ConflictAPIPopup.lua new file mode 100644 index 00000000..86f93d0b --- /dev/null +++ b/plugin/src/App/ConflictAPIPopup.lua @@ -0,0 +1,121 @@ +local Rojo = script:FindFirstAncestor("Rojo") +local Plugin = Rojo.Plugin +local Packages = Rojo.Packages + +local Roact = require(Packages.Roact) + +local Config = require(Plugin.Config) +local Version = require(Plugin.Version) +local Theme = require(Plugin.App.Theme) + +local TextButton = require(Plugin.App.Components.TextButton) + +local e = Roact.createElement + +local ConflictAPIPopup = Roact.Component:extend("ConflictAPIPopup") + +function ConflictAPIPopup:render() + return Theme.with(function(theme) + theme = theme.Settings + + return e("Frame", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 1, 0), + }, { + Padding = e("UIPadding", { + PaddingLeft = UDim.new(0, 20), + PaddingRight = UDim.new(0, 20), + PaddingTop = UDim.new(0, 15), + PaddingBottom = UDim.new(0, 15), + }), + + Details = e("Frame", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 1, 0), + }, { + Layout = e("UIListLayout", { + FillDirection = Enum.FillDirection.Vertical, + SortOrder = Enum.SortOrder.LayoutOrder, + Padding = UDim.new(0, 15), + HorizontalAlignment = Enum.HorizontalAlignment.Center, + }), + + Info = e("TextLabel", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 0, 0), + AutomaticSize = Enum.AutomaticSize.Y, + Text = "There is already a Rojo API exposed by a Rojo plugin. Do you want to overwrite it with this one?", + Font = Enum.Font.GothamMedium, + TextSize = 17, + TextColor3 = theme.Setting.NameColor, + TextXAlignment = Enum.TextXAlignment.Left, + TextWrapped = true, + TextTransparency = self.props.transparency, + LayoutOrder = 1, + }), + + Existing = e("TextLabel", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 0, 0), + AutomaticSize = Enum.AutomaticSize.Y, + Text = string.format("Existing: Version %s, Protocol %d", Version.display(self.props.existingAPI.Version), self.props.existingAPI.ProtocolVersion), + Font = Enum.Font.Gotham, + TextSize = 15, + TextColor3 = theme.Setting.DescriptionColor, + TextXAlignment = Enum.TextXAlignment.Left, + TextTransparency = self.props.transparency, + LayoutOrder = 2, + }), + + Incoming = e("TextLabel", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 0, 0), + AutomaticSize = Enum.AutomaticSize.Y, + Text = string.format("Incoming: Version %s, Protocol %d", Version.display(Config.version), Config.protocolVersion), + Font = Enum.Font.Gotham, + TextSize = 15, + TextColor3 = theme.Setting.DescriptionColor, + TextXAlignment = Enum.TextXAlignment.Left, + TextTransparency = self.props.transparency, + LayoutOrder = 3, + }), + }), + + Actions = e("Frame", { + BackgroundTransparency = 1, + Size = UDim2.new(1, 0, 0, 34), + Position = UDim2.fromScale(0, 1), + AnchorPoint = Vector2.new(0, 1), + }, { + Layout = e("UIListLayout", { + FillDirection = Enum.FillDirection.Horizontal, + SortOrder = Enum.SortOrder.LayoutOrder, + Padding = UDim.new(0, 10), + HorizontalAlignment = Enum.HorizontalAlignment.Right, + }), + + Keep = e(TextButton, { + text = "Keep", + style = "Bordered", + transparency = self.props.transparency, + layoutOrder = 1, + onClick = function() + self.props.onDeny() + end, + }), + + Overwrite = e(TextButton, { + text = "Overwrite", + style = "Solid", + transparency = self.props.transparency, + layoutOrder = 2, + onClick = function() + self.props.onAccept() + end, + }), + }), + }) + end) +end + +return ConflictAPIPopup diff --git a/plugin/src/App/init.lua b/plugin/src/App/init.lua index edcf2b07..97010ac1 100644 --- a/plugin/src/App/init.lua +++ b/plugin/src/App/init.lua @@ -24,6 +24,7 @@ local Theme = require(script.Theme) local Page = require(script.Page) local Notifications = require(script.Notifications) local PermissionPopup = require(script.PermissionPopup) +local ConflictAPIPopup = require(script.ConflictAPIPopup) local Tooltip = require(script.Components.Tooltip) local StudioPluginAction = require(script.Components.Studio.StudioPluginAction) local StudioToolbar = require(script.Components.Studio.StudioToolbar) @@ -52,11 +53,6 @@ function App:init() self.host, self.setHost = Roact.createBinding(priorHost or "") self.port, self.setPort = Roact.createBinding(priorPort or "") - self.headlessAPI, self.readOnlyHeadlessAPI = HeadlessAPI.new(self) - - -- selene: allow(global_usage) - _G.Rojo = self.readOnlyHeadlessAPI -- Expose headless to other plugins and command bar - self.patchInfo, self.setPatchInfo = Roact.createBinding({ changes = 0, timestamp = os.time(), @@ -69,6 +65,50 @@ function App:init() toolbarIcon = Assets.Images.PluginButton, popups = {}, }) + + self.headlessAPI, self.readOnlyHeadlessAPI = HeadlessAPI.new(self) + + -- selene: allow(global_usage) + local existingAPI = _G.Rojo + if existingAPI then + local responseEvent = Instance.new("BindableEvent") + responseEvent.Event:Once(function(accepted) + if accepted then + -- selene: allow(global_usage) + _G.Rojo = self.readOnlyHeadlessAPI -- Expose headless to other plugins and command bar + end + + responseEvent:Destroy() + self:setState(function(state) + state.popups["apiReplacement"] = nil + return state + end) + end) + + self:setState(function(state) + state.popups["apiReplacement"] = { + name = "Headless API Conflict", + dockState = Enum.InitialDockState.Float, + onClose = function() + responseEvent:Fire(false) + end, + content = e(ConflictAPIPopup, { + existingAPI = existingAPI, + onAccept = function() + responseEvent:Fire(true) + end, + onDeny = function() + responseEvent:Fire(false) + end, + transparency = Roact.createBinding(0), + }), + } + return state + end) + else + -- selene: allow(global_usage) + _G.Rojo = self.readOnlyHeadlessAPI -- Expose headless to other plugins and command bar + end end function App:addNotification(text: string, timeout: number?) @@ -410,7 +450,7 @@ function App:render() title = popup.name, active = true, - initDockState = Enum.InitialDockState.Top, + initDockState = popup.dockState or Enum.InitialDockState.Top, initEnabled = true, overridePreviousState = true, floatingSize = Vector2.new(400, 300),