@rbxts/centurion-ui 1.0.0-dev-284510d → 1.0.0-dev-a7b777e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/out/app/centurion-app.d.ts +3 -0
- package/out/app/centurion-app.lua +92 -0
- package/out/app/index.d.ts +6 -1
- package/out/app/init.lua +57 -4
- package/out/components/history/history-line.d.ts +5 -5
- package/out/components/history/history-line.lua +51 -27
- package/out/components/history/history-list.d.ts +8 -12
- package/out/components/history/history-list.lua +41 -41
- package/out/components/index.d.ts +1 -0
- package/out/components/init.lua +3 -0
- package/out/components/suggestions/badge.d.ts +11 -11
- package/out/components/suggestions/badge.lua +14 -20
- package/out/components/suggestions/main-suggestion.d.ts +6 -8
- package/out/components/suggestions/main-suggestion.lua +153 -143
- package/out/components/suggestions/suggestion-list.d.ts +5 -5
- package/out/components/suggestions/suggestion-list.lua +70 -49
- package/out/components/suggestions/suggestions.d.ts +2 -1
- package/out/components/suggestions/suggestions.lua +41 -50
- package/out/components/suggestions/util.d.ts +2 -2
- package/out/components/suggestions/util.lua +1 -0
- package/out/components/terminal/index.d.ts +1 -0
- package/out/{store/history → components/terminal}/init.lua +1 -1
- package/out/components/terminal/terminal-text-field.d.ts +11 -0
- package/out/components/terminal/terminal-text-field.lua +319 -0
- package/out/components/terminal/terminal.d.ts +2 -0
- package/out/components/terminal/terminal.lua +240 -0
- package/out/components/ui/frame.d.ts +17 -18
- package/out/components/ui/frame.lua +8 -10
- package/out/components/ui/group.d.ts +13 -15
- package/out/components/ui/group.lua +6 -9
- package/out/components/ui/layer.d.ts +5 -5
- package/out/components/ui/layer.lua +3 -3
- package/out/components/ui/outline.d.ts +13 -12
- package/out/components/ui/outline.lua +64 -54
- package/out/components/ui/padding.d.ts +7 -7
- package/out/components/ui/padding.lua +2 -2
- package/out/components/ui/scrolling-frame.d.ts +11 -12
- package/out/components/ui/scrolling-frame.lua +4 -9
- package/out/components/ui/text-field.d.ts +10 -9
- package/out/components/ui/text-field.lua +15 -13
- package/out/components/ui/text.d.ts +16 -16
- package/out/components/ui/text.lua +39 -38
- package/out/constants/springs.lua +1 -1
- package/out/hooks/use-api.d.ts +3 -0
- package/out/hooks/use-api.lua +18 -0
- package/out/hooks/use-atom.d.ts +2 -0
- package/out/hooks/use-atom.lua +17 -0
- package/out/hooks/use-debounce-source.d.ts +11 -0
- package/out/hooks/use-debounce-source.lua +27 -0
- package/out/hooks/use-event.d.ts +14 -0
- package/out/hooks/use-event.lua +58 -0
- package/out/hooks/use-history.d.ts +2 -0
- package/out/hooks/use-history.lua +56 -0
- package/out/hooks/use-motion.d.ts +4 -4
- package/out/hooks/use-motion.lua +11 -16
- package/out/hooks/use-px.d.ts +13 -1
- package/out/hooks/use-px.lua +52 -39
- package/out/store.d.ts +14 -0
- package/out/store.lua +44 -0
- package/out/types.d.ts +7 -4
- package/out/util/argument.d.ts +2 -1
- package/out/util/argument.lua +25 -0
- package/out/util/suggestion.d.ts +2 -2
- package/out/util/suggestion.lua +9 -14
- package/package.json +14 -14
- package/out/app/app.d.ts +0 -6
- package/out/app/app.lua +0 -83
- package/out/app/terminal-app.d.ts +0 -1
- package/out/app/terminal-app.lua +0 -61
- package/out/components/terminal-text-field.d.ts +0 -11
- package/out/components/terminal-text-field.lua +0 -289
- package/out/components/terminal-window.d.ts +0 -1
- package/out/components/terminal-window.lua +0 -265
- package/out/components/terminal.d.ts +0 -1
- package/out/components/terminal.lua +0 -26
- package/out/components/ui/shortcut-group.d.ts +0 -6
- package/out/components/ui/shortcut-group.lua +0 -100
- package/out/hooks/use-store.d.ts +0 -3
- package/out/hooks/use-store.lua +0 -7
- package/out/providers/api-provider.d.ts +0 -8
- package/out/providers/api-provider.lua +0 -17
- package/out/providers/options-provider.d.ts +0 -13
- package/out/providers/options-provider.lua +0 -39
- package/out/providers/root-provider.d.ts +0 -11
- package/out/providers/root-provider.lua +0 -24
- package/out/store/app/app-selectors.d.ts +0 -2
- package/out/store/app/app-selectors.lua +0 -7
- package/out/store/app/app-slice.d.ts +0 -8
- package/out/store/app/app-slice.lua +0 -17
- package/out/store/app/index.d.ts +0 -2
- package/out/store/app/init.lua +0 -10
- package/out/store/command/command-selectors.d.ts +0 -2
- package/out/store/command/command-selectors.lua +0 -7
- package/out/store/command/command-slice.d.ts +0 -15
- package/out/store/command/command-slice.lua +0 -21
- package/out/store/command/index.d.ts +0 -2
- package/out/store/command/init.lua +0 -10
- package/out/store/history/history-slice.d.ts +0 -11
- package/out/store/history/history-slice.lua +0 -52
- package/out/store/history/index.d.ts +0 -1
- package/out/store/index.d.ts +0 -46
- package/out/store/init.lua +0 -18
- package/out/store/suggestion/index.d.ts +0 -2
- package/out/store/suggestion/init.lua +0 -10
- package/out/store/suggestion/suggestion-selectors.d.ts +0 -2
- package/out/store/suggestion/suggestion-selectors.lua +0 -7
- package/out/store/suggestion/suggestion-slice.d.ts +0 -9
- package/out/store/suggestion/suggestion-slice.lua +0 -15
- package/out/store/text/index.d.ts +0 -2
- package/out/store/text/init.lua +0 -10
- package/out/store/text/text-selectors.d.ts +0 -3
- package/out/store/text/text-selectors.lua +0 -11
- package/out/store/text/text-slice.d.ts +0 -20
- package/out/store/text/text-slice.lua +0 -29
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Vide, { Derivable } from "@rbxts/vide";
|
|
2
|
+
interface TerminalTextFieldProps {
|
|
3
|
+
anchorPoint?: Derivable<Vector2>;
|
|
4
|
+
size?: Derivable<UDim2>;
|
|
5
|
+
position?: Derivable<UDim2>;
|
|
6
|
+
backgroundTransparency?: Derivable<number>;
|
|
7
|
+
onTextChange?: (text: string) => void;
|
|
8
|
+
onSubmit?: (text: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function TerminalTextField({ anchorPoint, size, position, backgroundTransparency, onTextChange, onSubmit, }: TerminalTextFieldProps): Vide.Node;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _string = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.string)
|
|
4
|
+
local endsWithSpace = _string.endsWithSpace
|
|
5
|
+
local formatPartsAsPath = _string.formatPartsAsPath
|
|
6
|
+
local subscribe = TS.import(script, TS.getModule(script, "@rbxts", "charm").src).subscribe
|
|
7
|
+
local UserInputService = TS.import(script, TS.getModule(script, "@rbxts", "services")).UserInputService
|
|
8
|
+
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
9
|
+
local Vide = _vide
|
|
10
|
+
local effect = _vide.effect
|
|
11
|
+
local source = _vide.source
|
|
12
|
+
local getAPI = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-api").getAPI
|
|
13
|
+
local useAtom = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-atom").useAtom
|
|
14
|
+
local useEvent = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-event").useEvent
|
|
15
|
+
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
16
|
+
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
17
|
+
local commandHistory = _store.commandHistory
|
|
18
|
+
local commandHistoryIndex = _store.commandHistoryIndex
|
|
19
|
+
local currentArgIndex = _store.currentArgIndex
|
|
20
|
+
local currentCommandPath = _store.currentCommandPath
|
|
21
|
+
local currentSuggestion = _store.currentSuggestion
|
|
22
|
+
local interfaceOptions = _store.interfaceOptions
|
|
23
|
+
local interfaceVisible = _store.interfaceVisible
|
|
24
|
+
local terminalText = _store.terminalText
|
|
25
|
+
local terminalTextParts = _store.terminalTextParts
|
|
26
|
+
local terminalTextValid = _store.terminalTextValid
|
|
27
|
+
local getArgumentNames = TS.import(script, script.Parent.Parent.Parent, "util", "argument").getArgumentNames
|
|
28
|
+
local Frame = TS.import(script, script.Parent.Parent, "ui", "frame").Frame
|
|
29
|
+
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
30
|
+
local Text = TS.import(script, script.Parent.Parent, "ui", "text").Text
|
|
31
|
+
local TextField = TS.import(script, script.Parent.Parent, "ui", "text-field").TextField
|
|
32
|
+
local TEXT_SIZE = 22
|
|
33
|
+
local function TerminalTextField(_param)
|
|
34
|
+
local anchorPoint = _param.anchorPoint
|
|
35
|
+
local size = _param.size
|
|
36
|
+
local position = _param.position
|
|
37
|
+
local backgroundTransparency = _param.backgroundTransparency
|
|
38
|
+
local onTextChange = _param.onTextChange
|
|
39
|
+
local onSubmit = _param.onSubmit
|
|
40
|
+
local api = getAPI()
|
|
41
|
+
local options = useAtom(interfaceOptions)
|
|
42
|
+
local visible = useAtom(interfaceVisible)
|
|
43
|
+
local valid = useAtom(terminalTextValid)
|
|
44
|
+
local ref = source(nil)
|
|
45
|
+
local text = source("")
|
|
46
|
+
local suggestionText = source("")
|
|
47
|
+
-- Focus text field when terminal becomes visible
|
|
48
|
+
effect(function()
|
|
49
|
+
if visible() then
|
|
50
|
+
local _result = ref()
|
|
51
|
+
if _result ~= nil then
|
|
52
|
+
_result:CaptureFocus()
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
local _result = ref()
|
|
56
|
+
if _result ~= nil then
|
|
57
|
+
_result:ReleaseFocus()
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end)
|
|
61
|
+
local traverseHistory = function(up)
|
|
62
|
+
local history = commandHistory()
|
|
63
|
+
if #history == 0 then
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
66
|
+
local historyIndex = commandHistoryIndex()
|
|
67
|
+
if (up and historyIndex == 0) or (not up and historyIndex == -1) then
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
local newIndex
|
|
71
|
+
if up then
|
|
72
|
+
newIndex = if historyIndex == -1 then #history - 1 else historyIndex - 1
|
|
73
|
+
else
|
|
74
|
+
newIndex = if historyIndex ~= #history - 1 then historyIndex + 1 else -1
|
|
75
|
+
end
|
|
76
|
+
local newText = if newIndex ~= -1 then history[newIndex + 1] else ""
|
|
77
|
+
text(newText)
|
|
78
|
+
suggestionText("")
|
|
79
|
+
commandHistoryIndex(newIndex)
|
|
80
|
+
local textBox = ref()
|
|
81
|
+
if textBox ~= nil then
|
|
82
|
+
textBox.CursorPosition = #newText + 1
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
subscribe(currentSuggestion, function(suggestion)
|
|
86
|
+
if suggestion == nil then
|
|
87
|
+
suggestionText("")
|
|
88
|
+
return nil
|
|
89
|
+
end
|
|
90
|
+
local atNextPart = endsWithSpace(terminalText())
|
|
91
|
+
local textParts = terminalTextParts()
|
|
92
|
+
local suggestionStartIndex = if #textParts > 0 then (if not atNextPart then #textParts[#textParts] else 0) + 1 else -1
|
|
93
|
+
if suggestion.type == "command" and suggestionStartIndex > -1 then
|
|
94
|
+
suggestionText(text() .. string.sub(suggestion.title, suggestionStartIndex))
|
|
95
|
+
return nil
|
|
96
|
+
end
|
|
97
|
+
local command = currentCommandPath()
|
|
98
|
+
local argIndex = currentArgIndex()
|
|
99
|
+
if suggestion.type ~= "argument" or command == nil or argIndex == nil then
|
|
100
|
+
return nil
|
|
101
|
+
end
|
|
102
|
+
local newText = text()
|
|
103
|
+
local argNames = getArgumentNames(api.registry, command)
|
|
104
|
+
for i = argIndex, #argNames - 1 do
|
|
105
|
+
if i == argIndex and not atNextPart then
|
|
106
|
+
if not (#suggestion.others == 0) then
|
|
107
|
+
newText ..= string.sub(suggestion.others[1], suggestionStartIndex)
|
|
108
|
+
end
|
|
109
|
+
newText ..= " "
|
|
110
|
+
continue
|
|
111
|
+
end
|
|
112
|
+
newText = `{newText}{argNames[i + 1]} `
|
|
113
|
+
end
|
|
114
|
+
suggestionText(newText)
|
|
115
|
+
end)
|
|
116
|
+
useEvent(UserInputService.InputBegan, function(input)
|
|
117
|
+
local textBox = ref()
|
|
118
|
+
local _condition = textBox == nil
|
|
119
|
+
if not _condition then
|
|
120
|
+
local _result = textBox
|
|
121
|
+
if _result ~= nil then
|
|
122
|
+
_result = _result:IsFocused()
|
|
123
|
+
end
|
|
124
|
+
_condition = not _result
|
|
125
|
+
end
|
|
126
|
+
if _condition then
|
|
127
|
+
return nil
|
|
128
|
+
end
|
|
129
|
+
if input.KeyCode == Enum.KeyCode.Up then
|
|
130
|
+
traverseHistory(true)
|
|
131
|
+
elseif input.KeyCode == Enum.KeyCode.Down then
|
|
132
|
+
traverseHistory(false)
|
|
133
|
+
end
|
|
134
|
+
if input.KeyCode ~= Enum.KeyCode.Tab then
|
|
135
|
+
return nil
|
|
136
|
+
end
|
|
137
|
+
-- Handle command suggestions
|
|
138
|
+
local commandPath = currentCommandPath()
|
|
139
|
+
local suggestion = currentSuggestion()
|
|
140
|
+
if commandPath == nil then
|
|
141
|
+
local _suggestionTitle = suggestion
|
|
142
|
+
if _suggestionTitle ~= nil then
|
|
143
|
+
_suggestionTitle = _suggestionTitle.title
|
|
144
|
+
end
|
|
145
|
+
local suggestionTitle = _suggestionTitle
|
|
146
|
+
if suggestionTitle == nil then
|
|
147
|
+
return nil
|
|
148
|
+
end
|
|
149
|
+
local currentText = text()
|
|
150
|
+
local textParts = terminalTextParts()
|
|
151
|
+
local newText = ""
|
|
152
|
+
if endsWithSpace(currentText) then
|
|
153
|
+
newText = currentText .. suggestionTitle
|
|
154
|
+
elseif not (#textParts == 0) then
|
|
155
|
+
local textPartSize = #textParts[#textParts]
|
|
156
|
+
local _arg1 = #currentText - textPartSize
|
|
157
|
+
newText = string.sub(currentText, 0, _arg1) .. suggestionTitle
|
|
158
|
+
end
|
|
159
|
+
local suggestionTextParts = string.split((string.gsub(suggestionText(), "%s+", " ")), " ")
|
|
160
|
+
local _nextCommand = api.registry:getCommandByString(formatPartsAsPath(suggestionTextParts))
|
|
161
|
+
if _nextCommand ~= nil then
|
|
162
|
+
_nextCommand = _nextCommand.options
|
|
163
|
+
end
|
|
164
|
+
local nextCommand = _nextCommand
|
|
165
|
+
local _condition_1 = nextCommand == nil
|
|
166
|
+
if not _condition_1 then
|
|
167
|
+
local _result = nextCommand.arguments
|
|
168
|
+
if _result ~= nil then
|
|
169
|
+
_result = #_result
|
|
170
|
+
end
|
|
171
|
+
local _condition_2 = _result
|
|
172
|
+
if _condition_2 == nil then
|
|
173
|
+
_condition_2 = 0
|
|
174
|
+
end
|
|
175
|
+
_condition_1 = _condition_2 > 0
|
|
176
|
+
end
|
|
177
|
+
if _condition_1 then
|
|
178
|
+
newText ..= " "
|
|
179
|
+
end
|
|
180
|
+
suggestionText("")
|
|
181
|
+
text(newText)
|
|
182
|
+
textBox.CursorPosition = #newText + 1
|
|
183
|
+
return nil
|
|
184
|
+
end
|
|
185
|
+
-- Handle argument suggestions
|
|
186
|
+
if commandPath == nil or suggestion == nil or #suggestion.others == 0 then
|
|
187
|
+
return nil
|
|
188
|
+
end
|
|
189
|
+
local argIndex = currentArgIndex()
|
|
190
|
+
local _commandArgs = api.registry:getCommand(commandPath)
|
|
191
|
+
if _commandArgs ~= nil then
|
|
192
|
+
_commandArgs = _commandArgs.options.arguments
|
|
193
|
+
end
|
|
194
|
+
local commandArgs = _commandArgs
|
|
195
|
+
if argIndex == nil or commandArgs == nil then
|
|
196
|
+
return nil
|
|
197
|
+
end
|
|
198
|
+
local newText = text()
|
|
199
|
+
local parts = terminalTextParts()
|
|
200
|
+
if not endsWithSpace(newText) and not (#parts == 0) then
|
|
201
|
+
local _newText = newText
|
|
202
|
+
local _arg1 = #newText - #parts[#parts]
|
|
203
|
+
newText = string.sub(_newText, 0, _arg1)
|
|
204
|
+
end
|
|
205
|
+
local otherSuggestion = suggestion.others[1]
|
|
206
|
+
if (string.match(otherSuggestion, "%s")) ~= nil then
|
|
207
|
+
otherSuggestion = `"{otherSuggestion}"`
|
|
208
|
+
end
|
|
209
|
+
newText ..= otherSuggestion
|
|
210
|
+
if argIndex < #commandArgs - 1 then
|
|
211
|
+
newText ..= " "
|
|
212
|
+
end
|
|
213
|
+
suggestionText("")
|
|
214
|
+
text(newText)
|
|
215
|
+
textBox.CursorPosition = #newText + 1
|
|
216
|
+
end)
|
|
217
|
+
return Vide.jsx(Frame, {
|
|
218
|
+
anchorPoint = anchorPoint,
|
|
219
|
+
size = size,
|
|
220
|
+
position = position,
|
|
221
|
+
backgroundColor = function()
|
|
222
|
+
return options().palette.surface
|
|
223
|
+
end,
|
|
224
|
+
backgroundTransparency = backgroundTransparency,
|
|
225
|
+
cornerRadius = function()
|
|
226
|
+
return UDim.new(0, px(4))
|
|
227
|
+
end,
|
|
228
|
+
}, Vide.jsx(Padding, {
|
|
229
|
+
all = function()
|
|
230
|
+
return UDim.new(0, px(8))
|
|
231
|
+
end,
|
|
232
|
+
}), Vide.jsx(TextField, {
|
|
233
|
+
action = function(instance)
|
|
234
|
+
return ref(instance)
|
|
235
|
+
end,
|
|
236
|
+
size = UDim2.fromScale(1, 1),
|
|
237
|
+
text = function()
|
|
238
|
+
local value = text()
|
|
239
|
+
-- Remove line breaks
|
|
240
|
+
if (string.match(value, "[\n\r]")) ~= nil then
|
|
241
|
+
value = (string.gsub(value, "[\n\r]", ""))
|
|
242
|
+
end
|
|
243
|
+
-- Remove all tabs from text input - we use these for autocompletion
|
|
244
|
+
if (string.match(value, "\t")) ~= nil then
|
|
245
|
+
value = (string.gsub(value, "\t", ""))
|
|
246
|
+
end
|
|
247
|
+
local _result = onTextChange
|
|
248
|
+
if _result ~= nil then
|
|
249
|
+
_result(value)
|
|
250
|
+
end
|
|
251
|
+
return value
|
|
252
|
+
end,
|
|
253
|
+
textSize = function()
|
|
254
|
+
return px(TEXT_SIZE)
|
|
255
|
+
end,
|
|
256
|
+
textColor = function()
|
|
257
|
+
return if valid() then options().palette.success else options().palette.error
|
|
258
|
+
end,
|
|
259
|
+
textXAlignment = "Left",
|
|
260
|
+
placeholderText = "Enter command...",
|
|
261
|
+
placeholderColor = function()
|
|
262
|
+
return options().palette.subtext
|
|
263
|
+
end,
|
|
264
|
+
font = function()
|
|
265
|
+
return options().font.medium
|
|
266
|
+
end,
|
|
267
|
+
clearTextOnFocus = false,
|
|
268
|
+
focusLost = function(enterPressed)
|
|
269
|
+
if not enterPressed then
|
|
270
|
+
return nil
|
|
271
|
+
end
|
|
272
|
+
local textBox = ref()
|
|
273
|
+
if textBox == nil then
|
|
274
|
+
return nil
|
|
275
|
+
end
|
|
276
|
+
local currentText = textBox.Text
|
|
277
|
+
local history = commandHistory()
|
|
278
|
+
if currentText ~= "" and (#history == 0 or history[#history] ~= currentText) then
|
|
279
|
+
commandHistory(function(prev)
|
|
280
|
+
local _array = {}
|
|
281
|
+
local _length = #_array
|
|
282
|
+
local _prevLength = #prev
|
|
283
|
+
table.move(prev, 1, _prevLength, _length + 1, _array)
|
|
284
|
+
_length += _prevLength
|
|
285
|
+
_array[_length + 1] = textBox.Text
|
|
286
|
+
return _array
|
|
287
|
+
end)
|
|
288
|
+
end
|
|
289
|
+
commandHistoryIndex(-1)
|
|
290
|
+
local _result = onSubmit
|
|
291
|
+
if _result ~= nil then
|
|
292
|
+
_result(currentText)
|
|
293
|
+
end
|
|
294
|
+
textBox:CaptureFocus()
|
|
295
|
+
text("")
|
|
296
|
+
end,
|
|
297
|
+
textChanged = function(currentText)
|
|
298
|
+
commandHistoryIndex(-1)
|
|
299
|
+
text(currentText)
|
|
300
|
+
end,
|
|
301
|
+
zIndex = 2,
|
|
302
|
+
}), Vide.jsx(Text, {
|
|
303
|
+
size = UDim2.fromScale(1, 1),
|
|
304
|
+
text = suggestionText,
|
|
305
|
+
textColor = function()
|
|
306
|
+
return options().palette.subtext
|
|
307
|
+
end,
|
|
308
|
+
textSize = function()
|
|
309
|
+
return px(TEXT_SIZE)
|
|
310
|
+
end,
|
|
311
|
+
textXAlignment = "Left",
|
|
312
|
+
font = function()
|
|
313
|
+
return options().font.medium
|
|
314
|
+
end,
|
|
315
|
+
}))
|
|
316
|
+
end
|
|
317
|
+
return {
|
|
318
|
+
TerminalTextField = TerminalTextField,
|
|
319
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _centurion = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out)
|
|
4
|
+
local ImmutableRegistryPath = _centurion.ImmutableRegistryPath
|
|
5
|
+
local RegistryPath = _centurion.RegistryPath
|
|
6
|
+
local ArrayUtil = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.data).ArrayUtil
|
|
7
|
+
local _string = TS.import(script, TS.getModule(script, "@rbxts", "centurion").out.shared.util.string)
|
|
8
|
+
local endsWithSpace = _string.endsWithSpace
|
|
9
|
+
local formatPartsAsPath = _string.formatPartsAsPath
|
|
10
|
+
local _vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
11
|
+
local Vide = _vide
|
|
12
|
+
local effect = _vide.effect
|
|
13
|
+
local source = _vide.source
|
|
14
|
+
local HISTORY_TEXT_SIZE = TS.import(script, script.Parent.Parent.Parent, "constants", "text").HISTORY_TEXT_SIZE
|
|
15
|
+
local getAPI = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-api").getAPI
|
|
16
|
+
local useAtom = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-atom").useAtom
|
|
17
|
+
local useHistory = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-history").useHistory
|
|
18
|
+
local useMotion = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-motion").useMotion
|
|
19
|
+
local px = TS.import(script, script.Parent.Parent.Parent, "hooks", "use-px").px
|
|
20
|
+
local _store = TS.import(script, script.Parent.Parent.Parent, "store")
|
|
21
|
+
local currentArgIndex = _store.currentArgIndex
|
|
22
|
+
local currentCommandPath = _store.currentCommandPath
|
|
23
|
+
local currentSuggestion = _store.currentSuggestion
|
|
24
|
+
local interfaceOptions = _store.interfaceOptions
|
|
25
|
+
local mouseOverInterface = _store.mouseOverInterface
|
|
26
|
+
local terminalText = _store.terminalText
|
|
27
|
+
local terminalTextParts = _store.terminalTextParts
|
|
28
|
+
local terminalTextValid = _store.terminalTextValid
|
|
29
|
+
local getMissingArgs = TS.import(script, script.Parent.Parent.Parent, "util", "argument").getMissingArgs
|
|
30
|
+
local _suggestion = TS.import(script, script.Parent.Parent.Parent, "util", "suggestion")
|
|
31
|
+
local getArgumentSuggestion = _suggestion.getArgumentSuggestion
|
|
32
|
+
local getCommandSuggestion = _suggestion.getCommandSuggestion
|
|
33
|
+
local HistoryList = TS.import(script, script.Parent.Parent, "history").HistoryList
|
|
34
|
+
local Frame = TS.import(script, script.Parent.Parent, "ui", "frame").Frame
|
|
35
|
+
local Padding = TS.import(script, script.Parent.Parent, "ui", "padding").Padding
|
|
36
|
+
local TerminalTextField = TS.import(script, script.Parent, "terminal-text-field").TerminalTextField
|
|
37
|
+
local MAX_HEIGHT = HISTORY_TEXT_SIZE * 10
|
|
38
|
+
local TEXT_FIELD_HEIGHT = 40
|
|
39
|
+
local function Terminal()
|
|
40
|
+
local api = getAPI()
|
|
41
|
+
local options = useAtom(interfaceOptions)
|
|
42
|
+
local missingArgs = source({})
|
|
43
|
+
local history = useHistory()
|
|
44
|
+
local historyHeight, historyHeightMotion = useMotion(0)
|
|
45
|
+
effect(function()
|
|
46
|
+
local totalHeight = history().height
|
|
47
|
+
local isClamped = totalHeight > px(MAX_HEIGHT)
|
|
48
|
+
local clampedHeight = if isClamped then px(MAX_HEIGHT) else totalHeight
|
|
49
|
+
historyHeightMotion:spring(clampedHeight, {
|
|
50
|
+
mass = 0.1,
|
|
51
|
+
tension = 300,
|
|
52
|
+
friction = 15,
|
|
53
|
+
})
|
|
54
|
+
end)
|
|
55
|
+
return Vide.jsx(Frame, {
|
|
56
|
+
size = function()
|
|
57
|
+
return UDim2.new(1, 0, 0, math.ceil(px(TEXT_FIELD_HEIGHT + 16) + historyHeight()))
|
|
58
|
+
end,
|
|
59
|
+
backgroundColor = function()
|
|
60
|
+
return options().palette.background
|
|
61
|
+
end,
|
|
62
|
+
backgroundTransparency = function()
|
|
63
|
+
local _condition = options().backgroundTransparency
|
|
64
|
+
if _condition == nil then
|
|
65
|
+
_condition = 0
|
|
66
|
+
end
|
|
67
|
+
return _condition
|
|
68
|
+
end,
|
|
69
|
+
cornerRadius = function()
|
|
70
|
+
return UDim.new(0, px(8))
|
|
71
|
+
end,
|
|
72
|
+
mouseEnter = function()
|
|
73
|
+
return mouseOverInterface(true)
|
|
74
|
+
end,
|
|
75
|
+
mouseLeave = function()
|
|
76
|
+
return mouseOverInterface(false)
|
|
77
|
+
end,
|
|
78
|
+
}, Vide.jsx(Padding, {
|
|
79
|
+
all = function()
|
|
80
|
+
return UDim.new(0, px(8))
|
|
81
|
+
end,
|
|
82
|
+
}), Vide.jsx(HistoryList, {
|
|
83
|
+
size = function()
|
|
84
|
+
return UDim2.new(1, 0, 1, -px(TEXT_FIELD_HEIGHT + 8))
|
|
85
|
+
end,
|
|
86
|
+
data = history,
|
|
87
|
+
maxHeight = function()
|
|
88
|
+
return px(MAX_HEIGHT)
|
|
89
|
+
end,
|
|
90
|
+
}), Vide.jsx(TerminalTextField, {
|
|
91
|
+
anchorPoint = Vector2.new(0, 1),
|
|
92
|
+
size = function()
|
|
93
|
+
return UDim2.new(1, 0, 0, px(TEXT_FIELD_HEIGHT))
|
|
94
|
+
end,
|
|
95
|
+
position = UDim2.fromScale(0, 1),
|
|
96
|
+
backgroundTransparency = function()
|
|
97
|
+
local _condition = options().backgroundTransparency
|
|
98
|
+
if _condition == nil then
|
|
99
|
+
_condition = 0
|
|
100
|
+
end
|
|
101
|
+
return _condition
|
|
102
|
+
end,
|
|
103
|
+
onTextChange = function(text)
|
|
104
|
+
terminalText(text)
|
|
105
|
+
terminalTextValid(false)
|
|
106
|
+
local parts = terminalTextParts()
|
|
107
|
+
if #parts == 0 then
|
|
108
|
+
currentCommandPath(nil)
|
|
109
|
+
currentSuggestion(nil)
|
|
110
|
+
currentArgIndex(nil)
|
|
111
|
+
return nil
|
|
112
|
+
end
|
|
113
|
+
-- If the text ends in a space, we want to count that as having traversed
|
|
114
|
+
-- to the next "part" of the text. This means we should include the previous
|
|
115
|
+
-- text part as part of the parent path.
|
|
116
|
+
local atNextPart = endsWithSpace(text)
|
|
117
|
+
local commandPath = currentCommandPath()
|
|
118
|
+
local atCommand = false
|
|
119
|
+
if commandPath ~= nil and formatPartsAsPath(ArrayUtil.slice(parts, 0, commandPath:size())) == commandPath:toString() then
|
|
120
|
+
-- The current path still leads to the command, so it's valid
|
|
121
|
+
atCommand = true
|
|
122
|
+
elseif api.registry:getCommandByString(formatPartsAsPath(parts)) ~= nil then
|
|
123
|
+
atCommand = true
|
|
124
|
+
commandPath = ImmutableRegistryPath.new(parts)
|
|
125
|
+
else
|
|
126
|
+
local currentPath = RegistryPath:empty()
|
|
127
|
+
for _, part in parts do
|
|
128
|
+
currentPath:append(part)
|
|
129
|
+
if api.registry:getCommand(currentPath) ~= nil then
|
|
130
|
+
atCommand = true
|
|
131
|
+
break
|
|
132
|
+
end
|
|
133
|
+
if #api.registry:getChildPaths(currentPath) == 0 then
|
|
134
|
+
atCommand = false
|
|
135
|
+
break
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
commandPath = ImmutableRegistryPath:fromPath(currentPath)
|
|
139
|
+
end
|
|
140
|
+
local currentPath = currentCommandPath()
|
|
141
|
+
if not atCommand and currentPath ~= nil then
|
|
142
|
+
currentCommandPath(nil)
|
|
143
|
+
elseif atCommand and commandPath ~= currentPath then
|
|
144
|
+
currentCommandPath(commandPath)
|
|
145
|
+
end
|
|
146
|
+
local _result
|
|
147
|
+
if commandPath ~= nil then
|
|
148
|
+
local _result_1 = api.registry:getCommand(commandPath)
|
|
149
|
+
if _result_1 ~= nil then
|
|
150
|
+
_result_1 = _result_1.options
|
|
151
|
+
end
|
|
152
|
+
_result = _result_1
|
|
153
|
+
else
|
|
154
|
+
_result = nil
|
|
155
|
+
end
|
|
156
|
+
local command = _result
|
|
157
|
+
if commandPath ~= nil and command ~= nil then
|
|
158
|
+
local missing = getMissingArgs(api.registry, commandPath, parts)
|
|
159
|
+
missingArgs(missing)
|
|
160
|
+
local _result_1 = command.arguments
|
|
161
|
+
if _result_1 ~= nil then
|
|
162
|
+
_result_1 = #_result_1 == 0
|
|
163
|
+
end
|
|
164
|
+
local _condition = _result_1
|
|
165
|
+
if _condition == nil then
|
|
166
|
+
_condition = true
|
|
167
|
+
end
|
|
168
|
+
local noArgs = _condition
|
|
169
|
+
terminalTextValid(noArgs or #missing == 0 or (atNextPart and #missing == 1))
|
|
170
|
+
else
|
|
171
|
+
terminalTextValid(false)
|
|
172
|
+
end
|
|
173
|
+
-- Update suggestions
|
|
174
|
+
local showArgs = atCommand and (atNextPart or (commandPath ~= nil and #parts > commandPath:size()))
|
|
175
|
+
local _result_1
|
|
176
|
+
if showArgs and command ~= nil then
|
|
177
|
+
local _result_2 = command.arguments
|
|
178
|
+
if _result_2 ~= nil then
|
|
179
|
+
_result_2 = #_result_2
|
|
180
|
+
end
|
|
181
|
+
local _condition = _result_2
|
|
182
|
+
if _condition == nil then
|
|
183
|
+
_condition = 0
|
|
184
|
+
end
|
|
185
|
+
_result_1 = _condition
|
|
186
|
+
else
|
|
187
|
+
_result_1 = 0
|
|
188
|
+
end
|
|
189
|
+
local argCount = _result_1
|
|
190
|
+
local currentTextPart = if not atNextPart then parts[#parts] else nil
|
|
191
|
+
local suggestion
|
|
192
|
+
if argCount == 0 then
|
|
193
|
+
local parentPath = if atNextPart then commandPath elseif commandPath:size() ~= 1 then commandPath:parent() else nil
|
|
194
|
+
suggestion = getCommandSuggestion(api.registry, parentPath, currentTextPart)
|
|
195
|
+
elseif commandPath ~= nil then
|
|
196
|
+
-- Handle argument suggestions
|
|
197
|
+
local argIndex = #parts - commandPath:size() - (if atNextPart then 0 else 1)
|
|
198
|
+
if argIndex >= argCount then
|
|
199
|
+
return nil
|
|
200
|
+
end
|
|
201
|
+
currentArgIndex(argIndex)
|
|
202
|
+
suggestion = getArgumentSuggestion(api.registry, commandPath, argIndex, currentTextPart)
|
|
203
|
+
local _result_2 = suggestion
|
|
204
|
+
if _result_2 ~= nil then
|
|
205
|
+
_result_2 = _result_2.error
|
|
206
|
+
end
|
|
207
|
+
if _result_2 ~= nil then
|
|
208
|
+
terminalTextValid(false)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
currentSuggestion(suggestion)
|
|
212
|
+
end,
|
|
213
|
+
onSubmit = function()
|
|
214
|
+
local commandPath = currentCommandPath()
|
|
215
|
+
local command = if commandPath ~= nil then api.registry:getCommand(commandPath) else nil
|
|
216
|
+
if commandPath == nil or command == nil then
|
|
217
|
+
api.dispatcher:addHistoryEntry({
|
|
218
|
+
success = false,
|
|
219
|
+
text = "Command not found.",
|
|
220
|
+
sentAt = os.time(),
|
|
221
|
+
})
|
|
222
|
+
return nil
|
|
223
|
+
end
|
|
224
|
+
local missing = missingArgs()
|
|
225
|
+
if not (#missing == 0) then
|
|
226
|
+
api.dispatcher:addHistoryEntry({
|
|
227
|
+
success = false,
|
|
228
|
+
text = `Missing arguments: {table.concat(missing, ", ")}`,
|
|
229
|
+
sentAt = os.time(),
|
|
230
|
+
})
|
|
231
|
+
return nil
|
|
232
|
+
end
|
|
233
|
+
local args = ArrayUtil.slice(terminalTextParts(), commandPath:size())
|
|
234
|
+
api.dispatcher:run(commandPath, args)
|
|
235
|
+
end,
|
|
236
|
+
}))
|
|
237
|
+
end
|
|
238
|
+
return {
|
|
239
|
+
Terminal = Terminal,
|
|
240
|
+
}
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
visible?: BindingOrValue<boolean>;
|
|
15
|
-
zIndex?: BindingOrValue<number>;
|
|
16
|
-
layoutOrder?: BindingOrValue<number>;
|
|
17
|
-
cornerRadius?: BindingOrValue<UDim>;
|
|
1
|
+
import Vide, { ActionAttributes, Derivable, InferEnumNames } from "@rbxts/vide";
|
|
2
|
+
export interface FrameProps<T extends Instance = Frame> extends ActionAttributes<T> {
|
|
3
|
+
size?: Derivable<UDim2>;
|
|
4
|
+
position?: Derivable<UDim2>;
|
|
5
|
+
anchorPoint?: Derivable<Vector2>;
|
|
6
|
+
rotation?: Derivable<number>;
|
|
7
|
+
backgroundColor?: Derivable<Color3>;
|
|
8
|
+
backgroundTransparency?: Derivable<number>;
|
|
9
|
+
clipsDescendants?: Derivable<boolean>;
|
|
10
|
+
visible?: Derivable<boolean>;
|
|
11
|
+
zIndex?: Derivable<number>;
|
|
12
|
+
layoutOrder?: Derivable<number>;
|
|
13
|
+
cornerRadius?: Derivable<UDim>;
|
|
18
14
|
automaticSize?: InferEnumNames<Enum.AutomaticSize>;
|
|
15
|
+
children?: Vide.Node;
|
|
16
|
+
mouseEnter?: () => void;
|
|
17
|
+
mouseLeave?: () => void;
|
|
19
18
|
}
|
|
20
|
-
export declare
|
|
19
|
+
export declare function Frame(props: FrameProps): Vide.Node;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
-- Compiled with roblox-ts v2.3.0-dev-26ec859
|
|
2
2
|
local TS = _G[script]
|
|
3
|
-
local
|
|
4
|
-
local
|
|
5
|
-
|
|
6
|
-
local Frame = forwardRef(function(props, ref)
|
|
7
|
-
return React.createElement("frame", {
|
|
8
|
-
ref = ref,
|
|
3
|
+
local Vide = TS.import(script, TS.getModule(script, "@rbxts", "vide").src)
|
|
4
|
+
local function Frame(props)
|
|
5
|
+
return Vide.jsx("frame", {
|
|
9
6
|
AutomaticSize = props.automaticSize,
|
|
10
7
|
Size = props.size,
|
|
11
8
|
Position = props.position,
|
|
@@ -18,12 +15,13 @@ local Frame = forwardRef(function(props, ref)
|
|
|
18
15
|
ZIndex = props.zIndex,
|
|
19
16
|
LayoutOrder = props.layoutOrder,
|
|
20
17
|
BorderSizePixel = 0,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
MouseEnter = props.mouseEnter,
|
|
19
|
+
MouseLeave = props.mouseLeave,
|
|
20
|
+
action = props.action,
|
|
21
|
+
}, props.cornerRadius and Vide.jsx("uicorner", {
|
|
24
22
|
CornerRadius = props.cornerRadius,
|
|
25
23
|
}), props.children)
|
|
26
|
-
end
|
|
24
|
+
end
|
|
27
25
|
return {
|
|
28
26
|
Frame = Frame,
|
|
29
27
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
visible?: BindingOrValue<boolean>;
|
|
14
|
-
zIndex?: BindingOrValue<number>;
|
|
1
|
+
import Vide, { Derivable } from "@rbxts/vide";
|
|
2
|
+
interface GroupProps extends Vide.PropsWithChildren {
|
|
3
|
+
size?: Derivable<UDim2>;
|
|
4
|
+
position?: Derivable<UDim2>;
|
|
5
|
+
anchorPoint?: Derivable<Vector2>;
|
|
6
|
+
rotation?: Derivable<number>;
|
|
7
|
+
clipsDescendants?: Derivable<boolean>;
|
|
8
|
+
layoutOrder?: Derivable<number>;
|
|
9
|
+
visible?: Derivable<boolean>;
|
|
10
|
+
zIndex?: Derivable<number>;
|
|
11
|
+
mouseEnter?: () => void;
|
|
12
|
+
mouseLeave?: () => void;
|
|
15
13
|
}
|
|
16
|
-
export declare
|
|
14
|
+
export declare function Group(props: GroupProps): Vide.Node;
|
|
17
15
|
export {};
|