diff --git a/src/ui/elements/button.lua b/src/ui/elements/button.lua index 7f391c4..bb48c7a 100644 --- a/src/ui/elements/button.lua +++ b/src/ui/elements/button.lua @@ -54,12 +54,12 @@ local buttonCore = { love.graphics.rectangle('fill', self.cornerX, self.cornerY, self.width, self.height, sType.rx, sType.ry, sType.segments) love.graphics.setColor(self.inactive and colours.midgrey or colours.white) if self.text and self.icon then - love.graphics.draw(self.icon, self.cornerX+self.height/2, self.midY, 0, w.scale, w.scale, self.icon:getWidth()/2, self.icon:getHeight()/2) + love.graphics.draw(self.icon, self.cornerX+self.height/2, self.midY, self.iconAngle or 0, w.scale, w.scale, self.icon:getWidth()/2, self.icon:getHeight()/2) love.graphics.printf(self.text, self.cornerX+self.height, self.midY-8*w.scale, self.widthBase-self.heightBase, 'left', 0, w.scale) elseif self.text then love.graphics.printf(self.text, self.cornerX, self.midY-8*w.scale, self.widthBase, 'center', 0, w.scale) elseif self.icon then - love.graphics.draw(self.icon, self.midX, self.midY, 0, w.scale, w.scale, self.icon:getWidth()/2, self.icon:getHeight()/2) + love.graphics.draw(self.icon, self.midX, self.midY, self.iconAngle or 0, w.scale, w.scale, self.icon:getWidth()/2, self.icon:getHeight()/2) end love.graphics.setColor(1,1,1) end, diff --git a/src/ui/mapView.lua b/src/ui/mapView.lua index 7b320fc..93dffe3 100644 --- a/src/ui/mapView.lua +++ b/src/ui/mapView.lua @@ -1,6 +1,10 @@ local selected local textHeadings, textValues, textDesc local white, grey = {1,1,1}, {0.5, 0.5, 0.5} +local throbber = love.graphics.newImage'graphics/throbber.png' +local writePath = love.filesystem.isFused() and 'SCFA/LOUD/' or '' +local downloading = {} +local outOfDate, localPath, scenarioInfoPath return { set = function(self, data) @@ -48,6 +52,13 @@ return { :gsub('\\t', '\t') or '', }, 480, 'left' ) + localPath = ('%susermaps/%s'):format(writePath, selected.identifier) + scenarioInfoPath = ('%susermaps/%s/%s_scenario.lua'):format(writePath, selected.identifier, selected.identifier) + if love.filesystem.getInfo(scenarioInfoPath) then + scenarioInfo = love.filesystem.read(scenarioInfoPath) + local localVersion = (scenarioInfo:match('map_version%s*%=%s*([^,%s]*)%s*,') or '') + outOfDate = tostring(selected.version):gsub('["\']', '')~=localVersion:gsub('["\']', '') + end return true end @@ -101,6 +112,68 @@ return { UI:goBack() end, }, + require'ui.elements.button'{ + text = 'Download', + posXN = 0, + posYN = 1, + offsetXN = 0.5, + offsetXP = 10, + offsetYN = -1.5, + offsetYP = -20, + type = 'bigicon', + onPress = function(self, UI) + if self.inactive then return end + love.filesystem.remove(scenarioInfoPath) + love.thread.getChannel'getMap':push(selected) + love.thread.newThread'utils/threads/getMap.lua':start() + downloading[selected.identifier] = true + selected.downloads = selected.downloads+1 + self.inactive = true + outOfDate = nil + end, + update = function(self, UI, delta) + if outOfDate then + self.inactive = nil + self.icon = nil + self.text = 'Update' + elseif love.filesystem.getInfo(scenarioInfoPath) then + self.inactive = true + self.icon = nil + self.text = 'Installed' + else + self.inactive = downloading[selected.identifier] + self.icon = downloading[selected.identifier] and throbber or nil + self.text = (not self.icon) and 'Download' or nil + end + self.iconAngle = love.timer.getTime() + end, + }, + require'ui.elements.button'{ + text = 'Uninstall', + posXN = 0, + posYN = 1, + offsetXN = 0.5, + offsetXP = 10, + offsetYN = -2.5, + offsetYP = -30, + type = 'bigicon', + onPress = function(self, UI) + if self.inactive then return end + downloading[selected.identifier] = nil + outOfDate = nil + require'utils.filesystem' + forEachFile(localPath, function(path, name) + love.filesystem.remove(path..'/'..(name or '')) + end) + love.filesystem.remove(localPath) + end, + update = function(self, UI, delta) + self.inactive = not love.filesystem.getInfo(scenarioInfoPath) + end, + showIf = function(self, UI) + return love.filesystem.getInfo(scenarioInfoPath) + end, + }, }, goBack = function(self) setUIMode(require'ui.mapLib') diff --git a/src/ui/menu.lua b/src/ui/menu.lua index cd0ca1e..7ef54c0 100644 --- a/src/ui/menu.lua +++ b/src/ui/menu.lua @@ -71,7 +71,7 @@ return { end, update = function(self, UI, delta) if exeFound then - self.inactive = updating + self.inactive = updating or ( (#files+todo+done)>0 and todo~=done ) end end, }, @@ -469,7 +469,7 @@ return { love.graphics.printf(text, 576*scale, (337+(i-1)*20)*scale, 556, 'right', 0, scale, scale) end ]] - if updating~=nil then + if updating~=nil or (#files+todo+done)>0 then love.graphics.printf(('Files downloading: %d Queued: %d Finished: %d'):format(#files, todo, done), 20*scale, 337*scale, 556, 'right', 0, scale, scale) end for i, text in ipairs(files) do diff --git a/src/utils/network.lua b/src/utils/network.lua index 337ae59..791110c 100644 --- a/src/utils/network.lua +++ b/src/utils/network.lua @@ -63,4 +63,39 @@ function network.getMapLibFile(file) return file, body end +local writePath = love.filesystem.isFused() and 'SCFA/LOUD/' or '' + +function network.getMap(data) + feedback:push(1) + feedback:push{data.name, 'downloading'} + local code, body, headers = require'https'.request('https://theloudproject.org:8081/'..data.file) + if code~=200 then + feedback:push{data.name, 'done'} + feedback:push(('%s map download failed: code %s: %s'):format(data.name, tostring(code), body)) + return + end + feedback:push{data.name, 'writing'} + local path, filename = data.file:match'(.*)(/[^/]*)' + love.filesystem.createDirectory('temp/'..path) + local SCDWritePath = 'temp/'..data.file + love.filesystem.write(SCDWritePath, body) + local mountPath = data.file:gsub('/', '-') + love.filesystem.mount(SCDWritePath, mountPath) + + require'utils.filesystem' + forEachFile(mountPath, function(path, name) + local inputPath = path..'/'..(name or '') + local outputPath = writePath..'usermaps'..path:sub(#mountPath+1)..'/'..(name or '') + if not name then + love.filesystem.createDirectory(outputPath) + return + end + love.filesystem.write(outputPath, (love.filesystem.read(inputPath))) + end) + love.filesystem.unmount(SCDWritePath) + love.filesystem.remove(SCDWritePath) + feedback:push{data.name, 'done'} + feedback:push(('Map "%s" downloaded.'):format(data.name)) +end + return network diff --git a/src/utils/threads/getMap.lua b/src/utils/threads/getMap.lua new file mode 100644 index 0000000..ae6f815 --- /dev/null +++ b/src/utils/threads/getMap.lua @@ -0,0 +1,4 @@ +local channel = love.thread.getChannel'getMap' +local network = require'utils.network' + +network.getMap(channel:demand())