mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-25 15:16:07 +00:00
Fix Rojo breaking when users undo/redo in Studio (#708)
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
* Skip confirming patches that contain only a datamodel name change. ([#688])
|
* Skip confirming patches that contain only a datamodel name change. ([#688])
|
||||||
* Added sync reminder notification. ([#689])
|
* Added sync reminder notification. ([#689])
|
||||||
* Added protection against syncing a model to a place. ([#691])
|
* Added protection against syncing a model to a place. ([#691])
|
||||||
|
* Fix Rojo breaking when users undo/redo in Studio ([#708])
|
||||||
|
|
||||||
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
||||||
[#674]: https://github.com/rojo-rbx/rojo/pull/674
|
[#674]: https://github.com/rojo-rbx/rojo/pull/674
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
[#688]: https://github.com/rojo-rbx/rojo/pull/688
|
[#688]: https://github.com/rojo-rbx/rojo/pull/688
|
||||||
[#689]: https://github.com/rojo-rbx/rojo/pull/689
|
[#689]: https://github.com/rojo-rbx/rojo/pull/689
|
||||||
[#691]: https://github.com/rojo-rbx/rojo/pull/691
|
[#691]: https://github.com/rojo-rbx/rojo/pull/691
|
||||||
|
[#708]: https://github.com/rojo-rbx/rojo/pull/708
|
||||||
|
|
||||||
## [7.3.0] - April 22, 2023
|
## [7.3.0] - April 22, 2023
|
||||||
* Added `$attributes` to project format. ([#574])
|
* Added `$attributes` to project format. ([#574])
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
local ChangeHistoryService = game:GetService("ChangeHistoryService")
|
||||||
local Players = game:GetService("Players")
|
local Players = game:GetService("Players")
|
||||||
local ServerStorage = game:GetService("ServerStorage")
|
local ServerStorage = game:GetService("ServerStorage")
|
||||||
local RunService = game:GetService("RunService")
|
local RunService = game:GetService("RunService")
|
||||||
@@ -57,6 +58,64 @@ function App:init()
|
|||||||
self.confirmationEvent = self.confirmationBindable.Event
|
self.confirmationEvent = self.confirmationBindable.Event
|
||||||
self.notifId = 0
|
self.notifId = 0
|
||||||
|
|
||||||
|
self.waypointConnection = ChangeHistoryService.OnUndo:Connect(function(action: string)
|
||||||
|
if not string.find(action, "^Rojo: Patch") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local undoConnection, redoConnection = nil, nil
|
||||||
|
local function cleanup()
|
||||||
|
undoConnection:Disconnect()
|
||||||
|
redoConnection:Disconnect()
|
||||||
|
end
|
||||||
|
|
||||||
|
Log.warn(
|
||||||
|
string.format(
|
||||||
|
"You've undone '%s'.\nIf this was not intended, please Redo in the topbar or with Ctrl/⌘+Y.",
|
||||||
|
action
|
||||||
|
)
|
||||||
|
)
|
||||||
|
local dismissNotif = self:addNotification(
|
||||||
|
string.format("You've undone '%s'.\nIf this was not intended, please restore.", action),
|
||||||
|
10,
|
||||||
|
{
|
||||||
|
Restore = {
|
||||||
|
text = "Restore",
|
||||||
|
style = "Solid",
|
||||||
|
layoutOrder = 1,
|
||||||
|
onClick = function(notification)
|
||||||
|
cleanup()
|
||||||
|
notification:dismiss()
|
||||||
|
ChangeHistoryService:Redo()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
Dismiss = {
|
||||||
|
text = "Dismiss",
|
||||||
|
style = "Bordered",
|
||||||
|
layoutOrder = 2,
|
||||||
|
onClick = function(notification)
|
||||||
|
cleanup()
|
||||||
|
notification:dismiss()
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
undoConnection = ChangeHistoryService.OnUndo:Once(function()
|
||||||
|
-- Our notif is now out of date- redoing will not restore the patch
|
||||||
|
-- since we've undone even further. Dismiss the notif.
|
||||||
|
cleanup()
|
||||||
|
dismissNotif()
|
||||||
|
end)
|
||||||
|
redoConnection = ChangeHistoryService.OnRedo:Once(function(redoneAction: string)
|
||||||
|
if redoneAction == action then
|
||||||
|
-- The user has restored the patch, so we can dismiss the notif
|
||||||
|
cleanup()
|
||||||
|
dismissNotif()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
self:setState({
|
self:setState({
|
||||||
appStatus = AppStatus.NotConnected,
|
appStatus = AppStatus.NotConnected,
|
||||||
guiEnabled = false,
|
guiEnabled = false,
|
||||||
@@ -83,7 +142,7 @@ function App:init()
|
|||||||
onClick = function(notification)
|
onClick = function(notification)
|
||||||
notification:dismiss()
|
notification:dismiss()
|
||||||
self:startSession()
|
self:startSession()
|
||||||
end
|
end,
|
||||||
},
|
},
|
||||||
Dismiss = {
|
Dismiss = {
|
||||||
text = "Dismiss",
|
text = "Dismiss",
|
||||||
@@ -97,7 +156,16 @@ function App:init()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function App:addNotification(text: string, timeout: number?, actions: { [string]: {text: string, style: string, layoutOrder: number, onClick: (any) -> ()} }?)
|
function App:willUnmount()
|
||||||
|
self.waypointConnection:Disconnect()
|
||||||
|
self.confirmationBindable:Destroy()
|
||||||
|
end
|
||||||
|
|
||||||
|
function App:addNotification(
|
||||||
|
text: string,
|
||||||
|
timeout: number?,
|
||||||
|
actions: { [string]: { text: string, style: string, layoutOrder: number, onClick: (any) -> () } }?
|
||||||
|
)
|
||||||
if not Settings:get("showNotifications") then
|
if not Settings:get("showNotifications") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -123,6 +191,10 @@ function App:addNotification(text: string, timeout: number?, actions: { [string]
|
|||||||
end
|
end
|
||||||
|
|
||||||
function App:closeNotification(id: number)
|
function App:closeNotification(id: number)
|
||||||
|
if not self.state.notifications[id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local notifications = table.clone(self.state.notifications)
|
local notifications = table.clone(self.state.notifications)
|
||||||
notifications[id] = nil
|
notifications[id] = nil
|
||||||
|
|
||||||
@@ -133,26 +205,38 @@ end
|
|||||||
|
|
||||||
function App:getPriorEndpoint()
|
function App:getPriorEndpoint()
|
||||||
local priorEndpoints = Settings:get("priorEndpoints")
|
local priorEndpoints = Settings:get("priorEndpoints")
|
||||||
if not priorEndpoints then return end
|
if not priorEndpoints then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local id = tostring(game.PlaceId)
|
local id = tostring(game.PlaceId)
|
||||||
if ignorePlaceIds[id] then return end
|
if ignorePlaceIds[id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local place = priorEndpoints[id]
|
local place = priorEndpoints[id]
|
||||||
if not place then return end
|
if not place then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
return place.host, place.port
|
return place.host, place.port
|
||||||
end
|
end
|
||||||
|
|
||||||
function App:getLastSyncTimestamp()
|
function App:getLastSyncTimestamp()
|
||||||
local priorEndpoints = Settings:get("priorEndpoints")
|
local priorEndpoints = Settings:get("priorEndpoints")
|
||||||
if not priorEndpoints then return end
|
if not priorEndpoints then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local id = tostring(game.PlaceId)
|
local id = tostring(game.PlaceId)
|
||||||
if ignorePlaceIds[id] then return end
|
if ignorePlaceIds[id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local place = priorEndpoints[id]
|
local place = priorEndpoints[id]
|
||||||
if not place then return end
|
if not place then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
return place.timestamp
|
return place.timestamp
|
||||||
end
|
end
|
||||||
@@ -172,7 +256,9 @@ function App:setPriorEndpoint(host: string, port: string)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local id = tostring(game.PlaceId)
|
local id = tostring(game.PlaceId)
|
||||||
if ignorePlaceIds[id] then return end
|
if ignorePlaceIds[id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
priorEndpoints[id] = {
|
priorEndpoints[id] = {
|
||||||
host = if host ~= Config.defaultHost then host else nil,
|
host = if host ~= Config.defaultHost then host else nil,
|
||||||
@@ -181,7 +267,6 @@ function App:setPriorEndpoint(host: string, port: string)
|
|||||||
}
|
}
|
||||||
Log.trace("Saved last used endpoint for {}", game.PlaceId)
|
Log.trace("Saved last used endpoint for {}", game.PlaceId)
|
||||||
|
|
||||||
|
|
||||||
Settings:set("priorEndpoints", priorEndpoints)
|
Settings:set("priorEndpoints", priorEndpoints)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
Patches can come from the server or be generated by the client.
|
Patches can come from the server or be generated by the client.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
local ChangeHistoryService = game:GetService("ChangeHistoryService")
|
||||||
|
|
||||||
local Packages = script.Parent.Parent.Parent.Packages
|
local Packages = script.Parent.Parent.Parent.Packages
|
||||||
local Log = require(Packages.Log)
|
local Log = require(Packages.Log)
|
||||||
|
|
||||||
@@ -17,6 +19,8 @@ local reify = require(script.Parent.reify)
|
|||||||
local setProperty = require(script.Parent.setProperty)
|
local setProperty = require(script.Parent.setProperty)
|
||||||
|
|
||||||
local function applyPatch(instanceMap, patch)
|
local function applyPatch(instanceMap, patch)
|
||||||
|
local patchTimestamp = DateTime.now():FormatLocalTime("LTS", "en-us")
|
||||||
|
|
||||||
-- Tracks any portions of the patch that could not be applied to the DOM.
|
-- Tracks any portions of the patch that could not be applied to the DOM.
|
||||||
local unappliedPatch = PatchSet.newEmpty()
|
local unappliedPatch = PatchSet.newEmpty()
|
||||||
|
|
||||||
@@ -199,6 +203,8 @@ local function applyPatch(instanceMap, patch)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ChangeHistoryService:SetWaypoint("Rojo: Patch " .. patchTimestamp)
|
||||||
|
|
||||||
return unappliedPatch
|
return unappliedPatch
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user