slabOS/slabos.lua
2025-06-06 04:24:16 +00:00

327 lines
9.2 KiB
Lua

local basalt = require("/lib/basalt")
config = {}
if fs.exists("config.json") then
local config_file = fs.open("/config.json","r")
local config_text = config_file.readAll()
config = textutils.unserialiseJSON(config_text)
config_file.close()
end
if config.password then
while true do
if config.password == "" then
break
end
term.setCursorPos(1, 1)
term.clear()
print("This device requires a password to start.")
write("Password: ")
local msg = read()
if msg == config.password then
break
else
print("Incorrect!")
sleep(1)
end
end
end
local main = basalt.getMainFrame()
local FRAME_WIDTH = 26
local FRAME_HEIGHT = 19
local CONTROL_BUTTON_Y = 20
local homescreen = main:addFrame()
:setPosition(1, 1)
:setSize(FRAME_WIDTH, FRAME_HEIGHT)
:setBackground(colours.blue)
:setVisible(true)
if config.wallpaperColour then
homescreen:setBackground(colours[config.wallpaperColour])
end
local active_app_frames = {}
local current_active_frame = homescreen
local app_switcher_frame = main:addFrame()
:setPosition(1, 1)
:setSize(FRAME_WIDTH, FRAME_HEIGHT)
:setBackground(colours.brown)
:setVisible(false)
function show_payment_confirmation(amount, purpose, callback)
local payment_confirmation_frame = main:addFrame()
:setPosition(1, 1)
:setSize(FRAME_WIDTH, FRAME_HEIGHT / 3)
:setBackground(colours.black)
payment_confirmation_frame.z = 99
payment_confirmation_frame.focused = true
payment_confirmation_frame:addLabel()
:setText("Confirm Payment")
:setForeground(colours.white)
payment_confirmation_frame:addLabel()
:setPosition(1, 3)
:setText(amount .. "G -> " .. purpose)
:setForeground(colours.white)
payment_confirmation_frame:addButton()
:setText("Confirm")
:setPosition(1, 6)
:setSize(13, 1)
:setBackground(colours.green)
:onClick(function()
if callback then
callback(true)
end
payment_confirmation_frame:destroy()
end)
payment_confirmation_frame:addButton()
:setText("Deny")
:setPosition(14, 6)
:setSize(13, 1)
:setBackground(colours.red)
:onClick(function()
if callback then
callback(false)
end
payment_confirmation_frame:destroy()
end)
sleep(0.01)
end
local function payment_listener()
local modem = peripheral.find("modem")
local lchannel = tonumber(os.getComputerID() .. 43)
modem.open(lchannel)
while true do
local event, side, channel, replyChannel, message, distance
repeat
event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
until channel == lchannel
local payload = textutils.unserialiseJSON(message)
if payload.type == "confirmTransaction" then
show_payment_confirmation(payload.amount, payload.vendor,function(bruh)
if bruh then
local confirmation_payload = {
type = "transactionConfirmation",
transaction_id = payload.transaction_id,
confirmed = true
}
modem.transmit(replyChannel,channel,textutils.serialiseJSON(confirmation_payload))
else
local confirmation_payload = {
type = "transactionConfirmation",
transaction_id = payload.transaction_id,
confirmed = false
}
modem.transmit(replyChannel,channel,textutils.serialiseJSON(confirmation_payload))
end
end)
end
end
end
local function populate_homescreen_buttons()
homescreen:clear()
local button_width = 11
local button_height = 3
local button_spacing_x = 2
local button_spacing_y = 2
local current_x = button_spacing_x
local current_y = button_spacing_y
local app_files = fs.list("/apps/")
for i = 1, #app_files do
local filename = app_files[i]
local display_name = filename:gsub(".lua$", "")
if current_x + button_width > homescreen:getWidth() then
current_x = button_spacing_x
current_y = current_y + button_height + button_spacing_y
end
if current_y + button_height > homescreen:getHeight() then
break
end
local app_button = homescreen:addButton()
:setText(display_name)
:setPosition(current_x, current_y)
:setSize(button_width, button_height)
:setBackground(colours.grey)
:setForeground(colours.white)
:onClick(function()
if current_active_frame then
current_active_frame:setVisible(false)
end
local app_frame = active_app_frames[filename]
if not app_frame then
app_frame = main:addFrame()
:setPosition(1, 1)
:setSize(FRAME_WIDTH, FRAME_HEIGHT)
:setBackground(colours.green)
:setVisible(false)
app_frame:addProgram()
:setSize(FRAME_WIDTH, FRAME_HEIGHT)
:execute("/apps/" .. filename)
active_app_frames[filename] = app_frame
end
app_frame:setVisible(true)
current_active_frame = app_frame
end)
current_x = current_x + button_width + button_spacing_x
end
end
local function switch_to_frame(target_frame, frame_name)
if current_active_frame then
current_active_frame:setVisible(false)
end
target_frame:setVisible(true)
current_active_frame = target_frame
end
local function populate_app_switcher_ui()
app_switcher_frame:clear()
app_switcher_frame:addLabel()
:setText("Active Applications")
:setPosition(5, 1)
:setSize(FRAME_WIDTH - 2, 1)
:setForeground(colours.white)
:setBackground(colours.blue)
local current_y = 3
app_switcher_frame:addButton()
:setText("Home Screen")
:setPosition(2, current_y)
:setSize(FRAME_WIDTH - 3, 1)
:setBackground(homescreen == current_active_frame and colours.lightGrey or colours.grey)
:setForeground(colours.white)
:onClick(function()
switch_to_frame(homescreen, "Home Screen")
app_switcher_frame:setVisible(false)
end)
current_y = current_y + 2
for filename, app_frame in pairs(active_app_frames) do
local display_name = filename:gsub(".lua$", "")
if current_y + 1 > app_switcher_frame:getHeight() - 2 then
app_switcher_frame:addLabel()
:setText("...more apps below...")
:setPosition(1, current_y)
:setSize(FRAME_WIDTH - 2, 1)
:setForeground(colours.orange)
:setBackground(colours.black)
break
end
app_switcher_frame:addButton()
:setText(display_name)
:setPosition(2, current_y)
:setSize(FRAME_WIDTH - 8, 1)
:setBackground(app_frame == current_active_frame and colours.lightGrey or colours.grey)
:setForeground(colours.white)
:onClick(function()
switch_to_frame(app_frame, filename)
app_switcher_frame:setVisible(false)
end)
app_switcher_frame:addButton()
:setText("X")
:setPosition(FRAME_WIDTH - 6, current_y)
:setSize(5, 1)
:setBackground(colours.red)
:setForeground(colours.white)
:onClick(function()
if app_frame then
app_frame:destroy()
end
active_app_frames[filename] = nil
if current_active_frame == app_frame then
switch_to_frame(homescreen, "Home Screen (after close)")
end
populate_app_switcher_ui()
end)
current_y = current_y + 2
end
end
populate_homescreen_buttons()
main:addButton()
:setText("Home")
:setPosition(0, CONTROL_BUTTON_Y)
:setSize(14, 1)
:setBackground(colours.black)
:setForeground(colours.white)
:onClick(function()
populate_homescreen_buttons()
if current_active_frame ~= homescreen or app_switcher_frame.visible == true then
app_switcher_frame:setVisible(false)
switch_to_frame(homescreen, "Home Screen")
end
end)
main:addButton()
:setText("Switch")
:setPosition(14, CONTROL_BUTTON_Y)
:setSize(13, 1)
:setBackground(colours.red)
:setForeground(colours.white)
:onClick(function()
if current_active_frame then
current_active_frame:setVisible(false)
end
populate_app_switcher_ui()
app_switcher_frame:setVisible(true)
end)
parallel.waitForAny(basalt.run,payment_listener)