|
| 1 | +local React = require(script.Parent.Packages.React) |
| 2 | +local ReactRoblox = require(script.Parent.Packages.ReactRoblox) |
| 3 | +local StudioComponents = require(script.Parent.Packages.StudioComponents) |
| 4 | +local storageHandler = require(script.Parent.storageHandler) |
| 5 | +local util = require(script.Parent.util) |
| 6 | +local e = React.createElement |
| 7 | +local module = {} |
| 8 | + |
| 9 | +local function getIcon() |
| 10 | + return if settings().Studio.Theme:GetColor(Enum.StudioStyleGuideColor.MainBackground).R < 0.5 |
| 11 | + then "rbxassetid://121239006179116" |
| 12 | + else "rbxassetid://70875562655977", |
| 13 | + "Settings" |
| 14 | +end |
| 15 | + |
| 16 | +local function HeaderText(props: { |
| 17 | + Text: string, |
| 18 | +}) |
| 19 | + return e(StudioComponents.Label, { |
| 20 | + Text = `<b>{props.Text}</b>`, |
| 21 | + RichText = true, |
| 22 | + TextXAlignment = Enum.TextXAlignment.Left, |
| 23 | + Size = UDim2.new(1, 0, 0, 20), |
| 24 | + TextColorStyle = Enum.StudioStyleGuideColor.BrightText, |
| 25 | + }) |
| 26 | +end |
| 27 | + |
| 28 | +local function Checkbox(props: { |
| 29 | + Label: string, |
| 30 | + InitialValue: boolean, |
| 31 | + SetValue: (value: boolean) -> (), |
| 32 | +}) |
| 33 | + local state, setState = React.useState(props.InitialValue) |
| 34 | + |
| 35 | + return e(StudioComponents.Checkbox, { |
| 36 | + Label = props.Label, |
| 37 | + Value = state, |
| 38 | + OnChanged = function() |
| 39 | + local newValue = not state |
| 40 | + setState(newValue) |
| 41 | + props.SetValue(newValue) |
| 42 | + end, |
| 43 | + }) |
| 44 | +end |
| 45 | + |
| 46 | +local function VerticalSpace(props: { Height: number }) |
| 47 | + return e("Frame", { |
| 48 | + Size = UDim2.new(1, 0, 0, props.Height), |
| 49 | + BackgroundTransparency = 1, |
| 50 | + BorderSizePixel = 0, |
| 51 | + }) |
| 52 | +end |
| 53 | + |
| 54 | +local function MainUI(props: { |
| 55 | + initialProject: string, |
| 56 | + setProject: (value: string) -> (), |
| 57 | + |
| 58 | + initialApiKey: string, |
| 59 | + setApiKey: (value: string) -> (), |
| 60 | + |
| 61 | + initialShouldLogPlayTime: boolean, |
| 62 | + setShouldLogPlayTime: (value: boolean) -> (), |
| 63 | + |
| 64 | + initialShouldLogEditTime: boolean, |
| 65 | + setShouldLogEditTime: (value: boolean) -> (), |
| 66 | + |
| 67 | + initialShouldLogCodingTime: boolean, |
| 68 | + setShouldLogCodingTime: (value: boolean) -> (), |
| 69 | +}) |
| 70 | + local projectText, setProjectText = React.useState(props.initialProject) |
| 71 | + local keyText, setKeyText = React.useState(props.initialApiKey) |
| 72 | + |
| 73 | + return e(StudioComponents.ScrollFrame, { |
| 74 | + PaddingLeft = UDim.new(0, 10), |
| 75 | + PaddingRight = UDim.new(0, 10), |
| 76 | + PaddingTop = UDim.new(0, 10), |
| 77 | + PaddingBottom = UDim.new(0, 10), |
| 78 | + }, { |
| 79 | + e(HeaderText, { |
| 80 | + Text = "Experience settings", |
| 81 | + }), |
| 82 | + |
| 83 | + e(StudioComponents.Label, { |
| 84 | + Text = "Project name", |
| 85 | + TextXAlignment = Enum.TextXAlignment.Left, |
| 86 | + Size = UDim2.new(1, 0, 0, 30), |
| 87 | + }), |
| 88 | + e(StudioComponents.TextInput, { |
| 89 | + Text = projectText, |
| 90 | + OnChanged = function(newText) |
| 91 | + setProjectText(newText) |
| 92 | + props.setProject(newText) |
| 93 | + end, |
| 94 | + ClearTextOnFocus = false, |
| 95 | + PlaceholderText = "Get it at wakatime.com/api-key", |
| 96 | + }), |
| 97 | + |
| 98 | + VerticalSpace({ |
| 99 | + Height = 15, |
| 100 | + }), |
| 101 | + e(HeaderText, { |
| 102 | + Text = "Global settings", |
| 103 | + }), |
| 104 | + |
| 105 | + e(StudioComponents.Label, { |
| 106 | + Text = `WakaTime API key{if util.isValidWakaTimeApiKey(keyText) |
| 107 | + then "" |
| 108 | + else " <b>(Please paste your API key that starts with waka_)</b>"}`, |
| 109 | + TextXAlignment = Enum.TextXAlignment.Left, |
| 110 | + Size = UDim2.new(1, 0, 0, 30), |
| 111 | + RichText = true, |
| 112 | + }), |
| 113 | + e(StudioComponents.TextInput, { |
| 114 | + Text = keyText, |
| 115 | + OnChanged = function(newText) |
| 116 | + setKeyText(newText) |
| 117 | + props.setApiKey(newText) |
| 118 | + end, |
| 119 | + ClearTextOnFocus = false, |
| 120 | + PlaceholderText = "Get it at wakatime.com/api-key", |
| 121 | + }), |
| 122 | + |
| 123 | + VerticalSpace({ Height = 10 }), |
| 124 | + |
| 125 | + e(Checkbox, { |
| 126 | + Label = "Log time in the editor", |
| 127 | + InitialValue = props.initialShouldLogEditTime, |
| 128 | + SetValue = props.setShouldLogEditTime, |
| 129 | + }), |
| 130 | + |
| 131 | + e(Checkbox, { |
| 132 | + Label = "Log time in playtesting", |
| 133 | + InitialValue = props.initialShouldLogPlayTime, |
| 134 | + SetValue = props.setShouldLogPlayTime, |
| 135 | + }), |
| 136 | + |
| 137 | + e(Checkbox, { |
| 138 | + Label = "Log time in the script editor", |
| 139 | + InitialValue = props.initialShouldLogCodingTime, |
| 140 | + SetValue = props.setShouldLogCodingTime, |
| 141 | + }), |
| 142 | + }) |
| 143 | +end |
| 144 | + |
| 145 | +function module.init(plugin: Plugin) |
| 146 | + local settingsWidget = plugin:CreateDockWidgetPluginGui( |
| 147 | + "wakatime_widget", |
| 148 | + DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Right, false, false, 200, 300, 50, 50) |
| 149 | + ) |
| 150 | + settingsWidget.Title = "WakaTime" |
| 151 | + |
| 152 | + local toolbar = plugin:CreateToolbar("WakaTime") |
| 153 | + local settingsButton = |
| 154 | + toolbar:CreateButton("wakatime_main", "Open the Roblox Studio WakaTime configuration.", getIcon()) |
| 155 | + settings().Studio.ThemeChanged:Connect(function() |
| 156 | + settingsButton.Icon = getIcon() |
| 157 | + end) |
| 158 | + settingsButton.Click:Connect(function() |
| 159 | + settingsWidget.Enabled = not settingsWidget.Enabled |
| 160 | + end) |
| 161 | + settingsButton:SetActive(settingsWidget.Enabled) |
| 162 | + settingsWidget:GetPropertyChangedSignal("Enabled"):Connect(function() |
| 163 | + settingsButton:SetActive(settingsWidget.Enabled) |
| 164 | + end) |
| 165 | + |
| 166 | + local root = ReactRoblox.createRoot(settingsWidget) |
| 167 | + root:render(e(MainUI, { |
| 168 | + initialProject = storageHandler.getProjectName(plugin), |
| 169 | + setProject = function(value) |
| 170 | + storageHandler.setProjectName(plugin, value) |
| 171 | + end, |
| 172 | + |
| 173 | + initialApiKey = storageHandler.getWakaTimeKey(plugin) or "", |
| 174 | + setApiKey = function(value) |
| 175 | + storageHandler.setWakaTimeKey(plugin, value) |
| 176 | + end, |
| 177 | + |
| 178 | + initialShouldLogPlayTime = storageHandler.getShouldLogPlayTime(plugin), |
| 179 | + setShouldLogPlayTime = function(value) |
| 180 | + storageHandler.setShouldLogPlayTime(plugin, value) |
| 181 | + end, |
| 182 | + |
| 183 | + initialShouldLogEditTime = storageHandler.getShouldLogEditTime(plugin), |
| 184 | + setShouldLogEditTime = function(value) |
| 185 | + storageHandler.setShouldLogEditTime(plugin, value) |
| 186 | + end, |
| 187 | + |
| 188 | + initialShouldLogCodingTime = storageHandler.getShouldLogCodingTime(plugin), |
| 189 | + setShouldLogCodingTime = function(value) |
| 190 | + storageHandler.setShouldLogCodingTime(plugin, value) |
| 191 | + end, |
| 192 | + })) |
| 193 | +end |
| 194 | + |
| 195 | +return module |
0 commit comments