Index: backend/pgsql.t ================================================================== --- backend/pgsql.t +++ backend/pgsql.t @@ -760,17 +760,23 @@ body = {`r:string(row,5), `r:len(row,5)+1}; convoheaduri = { `cvhu, `cvhlen }; --FIXME }) ] p.ptr.id = r:int(uint64,row,1) p.ptr.author = r:int(uint64,row,2) - p.ptr.posted = r:int(uint64,row,6) - p.ptr.discovered = r:int(uint64,row,7) - p.ptr.edited = r:int(uint64,row,8) - if r:null(row,9) - then p.ptr.parent = 0 - else p.ptr.parent = r:int(uint64,row,9) - end + if r:null(row,6) + then p.ptr.posted = 0 + else p.ptr.posted = r:int(uint64,row,6) + end + if r:null(row,7) + then p.ptr.discovered = 0 + else p.ptr.discovered = r:int(uint64,row,7) + end + if r:null(row,8) + then p.ptr.edited = 0 + else p.ptr.edited = r:int(uint64,row,8) + end + p.ptr.parent = r:int(uint64,row,9) if r:null(row,11) then p.ptr.chgcount = 0 else p.ptr.chgcount = r:int(uint32,row,11) end p.ptr.accent = r:int(int16,row,12) Index: config.lua ================================================================== --- config.lua +++ config.lua @@ -47,20 +47,18 @@ debug = u.tobool(default('parsav_enable_debug',true)); backends = defaultlist('parsav_backends', 'pgsql'); braingeniousmode = false; embeds = { -- TODO with gzip compression, svg is dramatically superior to webp - -- we should have a build-time option to serve svg so instances - -- proxied behind nginx can serve svgz, or possibly just straight-up - -- add support for content-encoding headers and pre-compress the - -- damn things before compiling + -- we should add support for content-encoding headers and pre-compress + -- the damn things before compiling (also making the binary smaller) {'style.css', 'text/css'}; {'live.js', 'text/javascript'}; -- rrrrrrrr - {'default-avatar.webp', 'image/webp'}; - {'padlock.webp', 'image/webp'}; - {'warn.webp', 'image/webp'}; - {'query.webp', 'image/webp'}; + {'default-avatar.webp', 'image/webp'}; -- needs inkscape-exclusive svg features + {'padlock.svg', 'image/svg+xml'}; + {'warn.svg', 'image/svg+xml'}; + {'query.svg', 'image/svg+xml'}; }; default_ui_accent = tonumber(default('parsav_ui_default_accent',323)); } if os.getenv('parsav_let_me_be_an_idiot') == "i know what i'm doing" then conf.braingeniousmode = true -- SOUND GENERAL QUARTERS Index: makefile ================================================================== --- makefile +++ makefile @@ -1,9 +1,10 @@ dl = git dbg-flags = $(if $(dbg),-g) -images = $(addsuffix .webp, $(basename $(wildcard static/*.svg))) +images = static/default-avatar.webp +#$(addsuffix .webp, $(basename $(wildcard static/*.svg))) styles = $(addsuffix .css, $(basename $(wildcard static/*.scss))) parsav parsavd: parsav.t config.lua pkgdata.lua $(images) $(styles) terra $(dbg-flags) $< parsav.o parsavd.o: parsav.t config.lua pkgdata.lua $(images) $(styles) @@ -19,11 +20,11 @@ inkscape -f $< -C -d 180 -e $@ static/%.css: static/%.scss sassc -t compressed $< $@ clean: - rm parsav parsav.o + rm parsav parsav.o $(images) $(styles) install: parsav mkdir $(prefix)/bin cp $< $(prefix)/bin/ Index: parsav.md ================================================================== --- parsav.md +++ parsav.md @@ -19,11 +19,11 @@ * cmark (commonmark implementation), for transformation of the help files, whose source is in commonmark. online documentation transforms these into html and embeds them in the binary; cmark is also used to to produce the troff source which is used to build the offline documentation. disable with `parsav_online_documentation=no parsav_offline_documentation=no` * troff implementation (tested with groff but as far as i know we don't need any groff-specific extensions) to produce PDFs and manpages from the cmark-generated intermediate forms. disable with `parsav_offline_documentation=no` additional preconfigure dependencies are necessary if you are building directly from trunk, rather than from a release tarball that includes certain build artifacts which need to be embedded in the binary: -* inkscape, for rendering out UI graphics +* inkscape, for rendering out some of the UI graphics that can't be represented with standard svg * cwebp (libwebp package), for transforming inkscape PNGs to webp * sassc, for compiling the SCSS stylesheet into its final CSS all builds require terra, which, unfortunately, requires installing an older version of llvm, v9 at the latest (which i develop parsav under). with any luck, your distro will be clever enough to package terra and its dependencies properly (it's trivial on nix, tho you'll need to tweak the terra expression to select a more recent llvm package); Arch Linux is one of those distros which is not so clever, and whose (AUR) terra package is totally broken. due to these unfortunate circumstances, terra is distributed not just in source form, but also in the the form of LLVM IR. distributions will also be made in the form of tarballed object code and assembly listings for various common platforms, currently including x86-32/64, arm7hf, aarch64, riscv, mips32/64, and ppc64/64le. Index: render/profile.t ================================================================== --- render/profile.t +++ render/profile.t @@ -43,11 +43,11 @@ var profile = data.view.profile { nym = fullname; bio = bio; xid = cs(actor.xid); avatar = lib.trn(actor.origin == 0, pstr{ptr=avistr.buf,ct=avistr.sz}, - cs(lib.coalesce(actor.avatar, '/s/default-avatar.webp'))); + cs(lib.coalesce(actor.avatar, '/s/default-avatar.svg'))); nposts = sn_posts, nfollows = sn_follows; nfollowers = sn_followers, nmutuals = sn_mutuals; tweetday = cs(timestr); timephrase = lib.trn(actor.origin == 0, lib.str.plit'joined', lib.str.plit'known since'); Index: render/tweet.t ================================================================== --- render/tweet.t +++ render/tweet.t @@ -31,11 +31,11 @@ text = bhtml; subject = cs(lib.coalesce(p.subject,'')); nym = fullname; when = cs(×tr[0]); avatar = cs(lib.trn(author.origin == 0, avistr.buf, - lib.coalesce(author.avatar, '/s/default-avatar.webp'))); + lib.coalesce(author.avatar, '/s/default-avatar.svg'))); acctlink = cs(author.xid); permalink = permalink:finalize(); attr = '' } Index: srv.t ================================================================== --- srv.t +++ srv.t @@ -207,11 +207,11 @@ key = 'X-Live-Newest-Artifact'; value = lib.math.decstr(lastup, &nbuf[20]); }, lib.http.header { key = 'Content-Length', value = '0' } ) - if self.live_last ~= 0 and self.live_last <= lastup then + if self.live_last ~= 0 and self.live_last >= lastup then lib.net.mg_printf(self.con, 'HTTP/1.1 %s', lib.http.codestr(200)) for i = 0, [hdrs.type.N] do lib.net.mg_printf(self.con, '%s: %s\r\n', hdrs[i].key, hdrs[i].value) end lib.net.mg_printf(self.con, '\r\n') @@ -260,11 +260,11 @@ terra convo:complain(code: uint16, title: rawstring, msg: rawstring) if msg == nil then msg = "i'm sorry, dave. i can't let you do that" end var ti: lib.str.acc ti:compose('error :: ', title) - var bo: lib.str.acc bo:compose('
') + var bo: lib.str.acc bo:compose('') var body = [convo.page] { title = ti:finalize(); body = bo:finalize(); class = lib.str.plit 'error'; cache = false; Index: static/live.js ================================================================== --- static/live.js +++ static/live.js @@ -18,11 +18,11 @@ * retrieve this url from the server as a get request, create a * tree from its html, find the element in question, ferret out * any deltas, and apply them. */ document.querySelectorAll('*[data-live]').forEach(function(container) { let interv = parseFloat(container.attributes.getNamedItem('data-live').nodeValue) * 1000; - container._liveLastArrival = '0'; /* TODO include header for this */ + container._liveLastArrival = 0; /* TODO include initial value in document */ window.setInterval(function() { var req = new Request(window.location, { method: 'GET', headers: { @@ -30,22 +30,21 @@ } }) fetch(req).then(function(resp) { if (!resp.ok) return; - let newest = resp.headers.get('X-Live-Newest-Artifact'); + let newest = parseInt(resp.headers.get('X-Live-Newest-Artifact')); if (newest <= container._liveLastArrival) { resp.body.cancel(); return; } container._liveLastArrival = newest resp.text().then(function(htmlbody) { var parser = new DOMParser(); var newdoc = parser.parseFromString(htmlbody,'text/html') - // console.log(newdoc.getElementById(container.id).innerHTML) container.innerHTML = newdoc.getElementById(container.id).innerHTML }) }) }, interv) }); }); Index: static/style.scss ================================================================== --- static/style.scss +++ static/style.scss @@ -416,15 +416,15 @@ cursor: help; } input.acl { @extend %teletype; - background: url(/s/padlock.webp) no-repeat; + background: url(/s/padlock.svg) no-repeat; background-size: 20pt; background-position: 0.05in 50%; &:focus { - background: url(/s/padlock.webp) no-repeat, $grad-ui-focus; + background: url(/s/padlock.svg) no-repeat, $grad-ui-focus; background-size: 20pt; background-position: 0.05in 50%; }; padding-left: 0.40in; } Index: view/confirm.tpl ================================================================== --- view/confirm.tpl +++ view/confirm.tpl @@ -1,9 +1,9 @@