mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-21 20:21:38 +00:00
Clicking on the "X changes X ago" message opens up a handy diff visualizer to see what those changes were. However, it had quite a few issues that needed fixing. - Disconnecting a session with it expanded caused an error as it tried to read the serveSession that no longer exists during the page fade transition. (#671) - Resolved by converting to stateful component and holding the serveSession during the lifetime to ensure it can render the last known changes during the fade transition - Leaving it open while new changes are synced did not update the visualizer - The patch data was piggybacking on an existing binding, which meant that new patches did not trigger rerender. - Resolved by converting to state - Also made some improvements to that old binding - Moved from app to connected page for better organization and separation of duties - No more useless updates causing rerenders with no real change - Scroll window child component wouldn't actually display the updated visuals - Resolved by making major improvements to VirtualScroller - Made more robust against edge case states - Made smarter about knowing when it needs to refresh As you can see in this slow motion GIF, it works now. 
176 lines
4.8 KiB
Lua
176 lines
4.8 KiB
Lua
local StudioService = game:GetService("StudioService")
|
|
|
|
local Rojo = script:FindFirstAncestor("Rojo")
|
|
local Plugin = Rojo.Plugin
|
|
local Packages = Rojo.Packages
|
|
|
|
local Roact = require(Packages.Roact)
|
|
local Flipper = require(Packages.Flipper)
|
|
|
|
local Assets = require(Plugin.Assets)
|
|
local Theme = require(Plugin.App.Theme)
|
|
local bindingUtil = require(Plugin.App.bindingUtil)
|
|
|
|
local e = Roact.createElement
|
|
|
|
local ChangeList = require(script.Parent.ChangeList)
|
|
|
|
local Expansion = Roact.Component:extend("Expansion")
|
|
|
|
function Expansion:render()
|
|
local props = self.props
|
|
|
|
if not props.rendered then
|
|
return nil
|
|
end
|
|
|
|
return e("Frame", {
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(1, -props.indent, 1, -30),
|
|
Position = UDim2.new(0, props.indent, 0, 30),
|
|
}, {
|
|
ChangeList = e(ChangeList, {
|
|
changes = props.changeList,
|
|
transparency = props.transparency,
|
|
columnVisibility = props.columnVisibility,
|
|
}),
|
|
})
|
|
end
|
|
|
|
local DomLabel = Roact.Component:extend("DomLabel")
|
|
|
|
function DomLabel:init()
|
|
local initHeight = self.props.elementHeight:getValue()
|
|
self.expanded = initHeight > 30
|
|
|
|
self.motor = Flipper.SingleMotor.new(initHeight)
|
|
self.binding = bindingUtil.fromMotor(self.motor)
|
|
|
|
self:setState({
|
|
renderExpansion = self.expanded,
|
|
})
|
|
self.motor:onStep(function(value)
|
|
local renderExpansion = value > 30
|
|
|
|
self.props.setElementHeight(value)
|
|
if self.props.updateEvent then
|
|
self.props.updateEvent:Fire()
|
|
end
|
|
|
|
self:setState(function(state)
|
|
if state.renderExpansion == renderExpansion then
|
|
return nil
|
|
end
|
|
|
|
return {
|
|
renderExpansion = renderExpansion,
|
|
}
|
|
end)
|
|
end)
|
|
end
|
|
|
|
function DomLabel:render()
|
|
local props = self.props
|
|
|
|
return Theme.with(function(theme)
|
|
local iconProps = StudioService:GetClassIcon(props.className)
|
|
local indent = (props.depth or 0) * 20 + 25
|
|
|
|
-- Line guides help indent depth remain readable
|
|
local lineGuides = {}
|
|
for i = 1, props.depth or 0 do
|
|
table.insert(
|
|
lineGuides,
|
|
e("Frame", {
|
|
Name = "Line_" .. i,
|
|
Size = UDim2.new(0, 2, 1, 2),
|
|
Position = UDim2.new(0, (20 * i) + 15, 0, -1),
|
|
BorderSizePixel = 0,
|
|
BackgroundTransparency = props.transparency,
|
|
BackgroundColor3 = theme.BorderedContainer.BorderColor,
|
|
})
|
|
)
|
|
end
|
|
|
|
return e("Frame", {
|
|
Name = "Change",
|
|
ClipsDescendants = true,
|
|
BackgroundColor3 = if props.patchType then theme.Diff[props.patchType] else nil,
|
|
BorderSizePixel = 0,
|
|
BackgroundTransparency = props.patchType and props.transparency or 1,
|
|
Size = self.binding:map(function(expand)
|
|
return UDim2.new(1, 0, 0, expand)
|
|
end),
|
|
}, {
|
|
Padding = e("UIPadding", {
|
|
PaddingLeft = UDim.new(0, 10),
|
|
PaddingRight = UDim.new(0, 10),
|
|
}),
|
|
ExpandButton = if props.changeList
|
|
then e("TextButton", {
|
|
BackgroundTransparency = 1,
|
|
Text = "",
|
|
Size = UDim2.new(1, 0, 1, 0),
|
|
[Roact.Event.Activated] = function()
|
|
self.expanded = not self.expanded
|
|
local goalHeight = 30 + (if self.expanded then math.clamp(#self.props.changeList * 30, 30, 30 * 6) else 0)
|
|
self.motor:setGoal(Flipper.Spring.new(goalHeight, {
|
|
frequency = 5,
|
|
dampingRatio = 1,
|
|
}))
|
|
end,
|
|
})
|
|
else nil,
|
|
Expansion = if props.changeList
|
|
then e(Expansion, {
|
|
rendered = self.state.renderExpansion,
|
|
indent = indent,
|
|
transparency = props.transparency,
|
|
changeList = props.changeList,
|
|
columnVisibility = props.columnVisibility,
|
|
})
|
|
else nil,
|
|
DiffIcon = if props.patchType
|
|
then e("ImageLabel", {
|
|
Image = Assets.Images.Diff[props.patchType],
|
|
ImageColor3 = theme.AddressEntry.PlaceholderColor,
|
|
ImageTransparency = props.transparency,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0, 20, 0, 20),
|
|
Position = UDim2.new(0, 0, 0, 15),
|
|
AnchorPoint = Vector2.new(0, 0.5),
|
|
})
|
|
else nil,
|
|
ClassIcon = e("ImageLabel", {
|
|
Image = iconProps.Image,
|
|
ImageTransparency = props.transparency,
|
|
ImageRectOffset = iconProps.ImageRectOffset,
|
|
ImageRectSize = iconProps.ImageRectSize,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0, 20, 0, 20),
|
|
Position = UDim2.new(0, indent, 0, 15),
|
|
AnchorPoint = Vector2.new(0, 0.5),
|
|
}),
|
|
InstanceName = e("TextLabel", {
|
|
Text = props.name .. (props.hint and string.format(
|
|
' <font color="#%s">%s</font>',
|
|
theme.AddressEntry.PlaceholderColor:ToHex(),
|
|
props.hint
|
|
) or ""),
|
|
RichText = true,
|
|
BackgroundTransparency = 1,
|
|
Font = Enum.Font.GothamMedium,
|
|
TextSize = 14,
|
|
TextColor3 = theme.Settings.Setting.DescriptionColor,
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
TextTransparency = props.transparency,
|
|
TextTruncate = Enum.TextTruncate.AtEnd,
|
|
Size = UDim2.new(1, -indent - 50, 0, 30),
|
|
Position = UDim2.new(0, indent + 30, 0, 0),
|
|
}),
|
|
LineGuides = e("Folder", nil, lineGuides),
|
|
})
|
|
end)
|
|
end
|
|
|
|
return DomLabel
|