local Y=require("yaru.core") local gfx=require("yaru.gfx") local ui=require("yaru.ui") local fs=require("filesystem") local computer=require("computer") local unicode=require("unicode") local B=require("yaru.backuplib") local M={} local function targets() local r={} local boot=computer.getBootAddress() for proxy,path in fs.mounts()do if proxy.address~=boot and proxy.address~=computer.tmpAddress()and not proxy.isReadOnly()and path~="/"and not path:match("^/dev")then r[#r+1]={path=path,label=proxy.getLabel()or proxy.address:sub(1,8),free=proxy.spaceTotal()-proxy.spaceUsed()} end end table.sort(r,function(a,b)return a.path0 and st.job.done/st.job.total or 0) else ui.button(w,x+10,3,"Back Up Now",function() if not st.cfg.dst then return Y.notify("Backups","Choose a destination drive first")end local s=stamp() job("Backup",function(p)return B.run(st.cfg,p,s)end) end,"suggested") end local y=6 gfx.text(x,y,"Folder to back up",t.fg) ui.button(w,x+pw-16,y,st.cfg.src,function() Y.dialog{title="Folder to Back Up",entry=st.cfg.src,buttons={{"Cancel"},{"Set",function(p) if p and fs.isDirectory(p)then st.cfg.src=fs.canonical(p);B.save(st.cfg)end end,"suggested"}}} end,nil,16) y=y+2 gfx.text(x,y,"Destination drive",t.fg) local tg=targets() if#tg==0 then gfx.text(x+20,y,"insert a floppy or a second hard drive",t.dim)end for i,d in ipairs(tg)do local on=st.cfg.dst==d.path ui.radio(w,x+20,y+i-1,on,ui.trunc(d.label.." "..d.path.." ("..ui.size(d.free).." free)",pw-24),function() st.cfg.dst=d.path;B.save(st.cfg) end) end y=y+math.max(1,#tg)+1 gfx.text(x,y,"Keep snapshots",t.fg) for i,n in ipairs({1,3,5,10})do ui.radio(w,x+20+(i-1)*7,y,st.cfg.keep==n,tostring(n),function()st.cfg.keep=n;B.save(st.cfg)end) end y=y+2 gfx.text(x,y,"Snapshots",t.fg) y=y+1 for i,s in ipairs(snaps)do if y>=ch then break end local info=B.info(st.cfg.dst,s) ui.round(x,y,pw,1,t.card) gfx.text(x+1,y,(s:gsub("_"," ")),t.fg,t.card) gfx.text(x+24,y,(info.files or"?").." files, "..ui.size(info.bytes or 0),t.dim,t.card) ui.button(w,x+pw-22,y,"Restore…",function() Y.dialog{title="Restore "..s.."?",text="Restore into the original folder (files are overwritten)\nor into a new folder next to it.", buttons={{"Cancel"},{"New Folder",function() local into=st.cfg.src.."/Restored "..s job("Restore",function(p)return B.restore(st.cfg.dst,s,into,p)end) end},{"Overwrite",function() job("Restore",function(p)return B.restore(st.cfg.dst,s,info.src or st.cfg.src,p)end) end,"destructive"}}} end,"flat",10) ui.button(w,x+pw-11,y,"Delete",function() Y.dialog{title="Delete snapshot "..s.."?",buttons={{"Cancel"},{"Delete",function() fs.remove(fs.concat(st.cfg.dst,"Backups",s))end,"destructive"}}} end,"flat",9) y=y+2 end gfx.text(x,ch,"Tip: schedule `backup` in Scheduled Tasks for automatic backups.",t.dim) end function win.cleanup()if not st.job then package.loaded["yaru.backuplib"]=nil end end function win.onSignal(name)if name=="component_added"or name=="component_removed"then Y.redraw(win)end end return win end return M