| Comment: | add avatar panel |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
8398fcda5a90bf34c663de5c55cd783d |
| User & Date: | lexi on 2021-01-10 16:44:33 |
| Other Links: | manifest | tags |
|
2021-01-11
| ||
| 01:53 | add auth docs and rsa auth check-in: 0d10a378e9 user: lexi tags: trunk | |
|
2021-01-10
| ||
| 16:44 | add avatar panel check-in: 8398fcda5a user: lexi tags: trunk | |
| 14:26 | get some user admin shit working, general cleanups check-in: e1ff4f301e user: lexi tags: trunk | |
Modified math.t from [60110bc615] to [12858be43d].
1 1 -- vim: ft=terra 2 2 local m = { 3 - shorthand = {maxlen = 14} 3 + shorthand = {maxlen = 14}; 4 + ll = { 5 + ctpop_u8 = terralib.intrinsic('llvm.ctpop.i8', uint8 -> uint8); 6 + }; 4 7 } 5 8 6 9 local pstring = lib.mem.ptr(int8) 7 10 8 11 -- swap in place -- faster on little endian 9 12 m.netswap_ip = macro(function(ty, src, dest) 10 13 if ty:astype().type ~= 'integer' then error('bad type') end ................................................................................ 52 55 elseif ch == 0x3a then ch = 37 53 56 elseif ch >= 0x61 and ch <= 0x7a then 54 57 ch = 38 + (ch - 0x61) 55 58 else return 0, false end 56 59 57 60 return ch, true 58 61 end 62 + 63 +terra m.pow(n: intptr, fac: intptr): intptr 64 + var o = n 65 + for i=0,fac do n = n * o end 66 + return n 67 +end 59 68 60 69 terra m.shorthand.gen(val: uint64, dest: rawstring): ptrdiff 61 70 var lst = "0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz" 62 71 var buf: int8[m.shorthand.maxlen] 63 72 var ptr = [&int8](buf) 64 73 while val ~= 0 do 65 74 var v = val % 64
Modified mgtool.t from [b40be7a821] to [600c3c1067].
115 115 elseif tmppw[i] >= 10 then 116 116 tmppw[i] = tmppw[i] + (0x41 - 10) 117 117 else tmppw[i] = tmppw[i] + 0x30 end 118 118 end 119 119 lib.dbg('assigning temporary password') 120 120 dlg:auth_attach_pw(uid, reset, 121 121 pstr { ptr = [rawstring](tmppw), ct = 32 }, 122 - lib.str.plit 'temporary password'); 122 + 'temporary password'); 123 123 end 124 124 125 125 local terra ipc_report(acks: lib.mem.ptr(lib.ipc.ack), rep: rawstring) 126 126 var decbuf: int8[21] 127 127 for i=0,acks.ct do 128 128 var num = lib.math.decstr(acks(i).clid, &decbuf[20]) 129 129 if acks(i).success then ................................................................................ 379 379 if cfmode.help then 380 380 [ lib.emit(false, 1, 'usage: ', `argv[0], ' mkroot ', cfmode.type.helptxt.flags, ' <handle>', cfmode.type.helptxt.opts) ] 381 381 return 1 382 382 end 383 383 if cfmode.arglist.ct == 1 then 384 384 var am = dlg:conf_get('credential-store') 385 385 var mg: bool 386 - if (not am) or am:cmp(lib.str.plit 'managed') then 386 + if (not am) or am:cmp('managed') then 387 387 mg = true 388 - elseif am:cmp(lib.str.plit 'unmanaged') then 388 + elseif am:cmp('unmanaged') then 389 389 lib.warn('credential store is unmanaged; you will need to create credentials for the new root user manually!') 390 390 mg = false 391 391 else lib.bail('unknown credential store mode "',{am.ptr,am.ct},'"; should be either "managed" or "unmanaged"') end 392 392 var kbuf: uint8[lib.crypt.const.maxdersz] 393 393 var root = lib.store.actor.mk(&kbuf[0]) 394 394 root.handle = cfmode.arglist(0) 395 395 var epithets = array(
Modified parsav.t from [2fffe11917] to [04e1a3fbb9].
272 272 set.name = string.format('set<%s>', table.concat(tbl, '|')) 273 273 set.metamethods.__entrymissing = macro(function(val, obj) 274 274 if o[val] == nil then error('value ' .. val .. ' not in set') end 275 275 return `bit { _v=[o[val] - 1], _set = &(obj) } 276 276 end) 277 277 terra set:sz() 278 278 var ct: intptr = 0 279 + --for i = 0, [math.floor(#tbl/8)] do 280 + -- ct = ct + lib.math.ll.ctpop_u8(self._store[i]) 281 + --end 282 + --[(function() 283 + -- if #tbl % 8 ~= 0 then 284 + -- local last = #tbl-1 285 + -- local msk = (2 ^ (#tbl % 8)) - 1 286 + -- return quote ct = ct + lib.math.ll.ctpop_u8(self._store[last] and [uint8](msk)) end 287 + -- else return {} end 288 + --end)()] 279 289 for i = 0, [#tbl] do 280 290 if (self._store[i/8] and (1 << i % 8)) ~= 0 then ct = ct + 1 end 281 291 end 282 292 return ct 283 293 end 284 294 set.methods.dump = macro(function(self) 285 295 local q = quote lib.io.say('dumping set:\n') end ................................................................................ 451 461 'render:media-gallery'; 452 462 453 463 'render:docpage'; 454 464 455 465 'render:conf:profile'; 456 466 'render:conf:sec'; 457 467 'render:conf:users'; 468 + 'render:conf:avi'; 458 469 'render:conf'; 459 470 'route'; 460 471 } 461 472 462 473 do 463 474 local p = string.format('parsav: %s\nbuilt on %s\n', config.build.str, config.build.when) 464 475 terra version() lib.io.send(1, p, [#p]) end
Modified render/compose.t from [95dc7dcbc1] to [4959831ced].
15 15 form.acl = edit.acl 16 16 end 17 17 if acc ~= nil then form:append(acc) return end 18 18 19 19 var cotxt = form:poolstr(&co.srv.pool) -- defer cotxt:free() 20 20 21 21 var doc = [lib.srv.convo.page] { 22 - title = lib.str.plit 'compose'; 22 + title = 'compose'; 23 23 body = cotxt; 24 - class = lib.str.plit 'compose'; 24 + class = 'compose'; 25 25 cache = true; 26 26 } 27 27 28 28 co:stdpage(doc) 29 29 end 30 30 31 31 return render_compose
Modified render/conf.t from [cd79efba6f] to [a292c2030a].
1 1 -- vim: ft=terra 2 2 local pstr = lib.mem.ptr(int8) 3 3 local pref = lib.mem.ref(int8) 4 4 5 5 local mappings = { 6 6 {url = 'profile', title = 'account profile', render = 'profile'}; 7 - {url = 'avi', title = 'avatar', render = 'avatar'}; 7 + {url = 'avi', title = 'avatar', render = 'avi'}; 8 8 {url = 'ui', title = 'user interface', render = 'ui'}; 9 9 {url = 'sec', title = 'security', render = 'sec_overlay'}; 10 10 {url = 'rel', title = 'relationships', render = 'rel'}; 11 11 {url = 'qnt', title = 'quarantine', render = 'quarantine'}; 12 12 {url = 'acl', title = 'access control shortcuts', render = 'acl'}; 13 13 {url = 'rooms', title = 'chatrooms', render = 'rooms'}; 14 14 {url = 'circles', title = 'circles', render = 'circles'}; ................................................................................ 83 83 pg:append(&fnpg) 84 84 pgt = fnpg:finalize() 85 85 else pgt = pg:poolstr(&co.srv.pool) end 86 86 --defer pgt:free() 87 87 88 88 co:stdpage([lib.srv.convo.page] { 89 89 title = 'configure'; body = pgt; 90 - class = lib.str.plit 'conf'; 90 + class = 'conf'; 91 91 cache = false; 92 92 }) 93 93 94 94 --if panel.ct ~= 0 then panel:free() end 95 95 end 96 96 97 97 return render_conf
Added render/conf/avi.t version [154a292a80].
1 +-- vim: ft=terra 2 +local pstr = lib.mem.ptr(int8) 3 +local pref = lib.mem.ref(int8) 4 + 5 +local terra 6 +render_conf_avi(co: &lib.srv.convo, path: lib.mem.ptr(pref)): pstr 7 + var a = co:stra(128) 8 + a:lpush '<form method="post"><p>this is your current avatar. if you want to change it, you can reset it to the default, or pick a new image in your <a href="/media">media library</a> to represent yourself with.</p><img class="avatar big" src="/avi/':push(co.who.handle,0):lpush '">' 9 + if co.who.avatarid ~= 0 then 10 + a:lpush '<menu class="vertical choice"><button name="act" value="clear">use default avatar</button><a class="button" href="/media/a/':shpush(co.who.avatarid):lpush '">open image</a></menu>' 11 + end 12 + return a:finalize() 13 +end 14 + 15 +return render_conf_avi
Modified render/conf/sec.t from [d16c1b9a13] to [157639932a].
35 35 end 36 36 end 37 37 credmgr.credlist = cl:finalize() 38 38 end 39 39 credmgr:append(&a) 40 40 --if credmgr.credlist.ct > 0 then credmgr.credlist:free() end 41 41 else 42 - if new:cmp(lib.str.plit'pw') then 42 + if new:cmp('pw') then 43 43 var d: data.view.conf_sec_pwnew 44 44 var time = lib.osclock.time(nil) 45 45 var timestr: int8[26] lib.osclock.ctime_r(&time, ×tr[0]) 46 46 var cmt = co:stra(48) 47 47 cmt:lpush('enrolled over http on '):push(×tr[0],0) 48 48 d.comment = cmt:finalize() 49 49 50 50 var st = d:poolstr(&co.srv.pool) 51 51 --d.comment:free() 52 52 return st 53 - elseif new:cmp(lib.str.plit'challenge') then 53 + elseif new:cmp('challenge') then 54 54 -- we're going to break the rules a bit and do database munging from 55 55 -- the rendering code, because doing otherwise in this case would be 56 56 -- genuinely nightmarish 57 - elseif new:cmp(lib.str.plit'otp') then 58 - elseif new:cmp(lib.str.plit'api') then 57 + elseif new:cmp('otp') then 58 + elseif new:cmp('api') then 59 59 else return pstr.null() end 60 60 end 61 61 else body:append(&a) end 62 62 63 63 return a:finalize() 64 64 end 65 65
Modified render/conf/users.t from [7c5c858095] to [88e528c638].
1 1 -- vim: ft=terra 2 2 local pstr = lib.mem.ptr(int8) 3 3 local pref = lib.mem.ref(int8) 4 -local P = lib.str.plit 5 4 6 5 local terra cs(s: rawstring) 7 6 return pstr { ptr = s, ct = lib.str.sz(s) } 8 7 end 9 8 10 9 local terra 11 10 regalia(acc: &lib.str.acc, rank: uint16) ................................................................................ 14 13 case [uint16](2) then acc:lpush('🔱') end 15 14 case [uint16](3) then acc:lpush('⚜️') end 16 15 case [uint16](4) then acc:lpush('🗡') end 17 16 case [uint16](5) then acc:lpush('🗝') end 18 17 else acc:lpush('🕴') 19 18 end 20 19 end 20 + 21 +local splitwords = macro(function(str) 22 + local words = {} 23 + for w in str:asvalue():gmatch('(%g+)') do words[#words + 1] = w end 24 + return `arrayof(pstr, [words]) 25 +end) 21 26 22 27 local rnd = lib.crypt.random 23 28 local terra 24 29 suggest_handle(a: &lib.str.acc) 25 30 var start = a.sz 26 31 var puncts = array('.','_','-') 27 32 var xXx = rnd(uint8, 0, 9) == 0 28 33 var leet = rnd(uint8, 0, 8) == 0 29 - var caps = rnd(uint8, 0, 5) 34 + var caps = rnd(uint8, 0, 10) 30 35 var punct: rawstring = nil 31 36 var useadj = rnd(uint8, 0, 4) == 0 32 37 if rnd(uint8, 0, 4) == 0 then 33 38 punct = puncts[rnd(intptr,0,[puncts.type.N])] 34 39 end 35 40 36 - var nouns = array( 37 - 'thunder','bride','blaze','doom','squad','gun','lord','blaster', 38 - 'fuck','hell','hound','piss','shit','killa','terror', 'horror', 39 - 'fear', 'slaughter','murder','general','commander', 'commissar', 40 - 'terrorist','infinity','slut','cunt','whore','bitch', 'bastard', 41 - 'cock','prince','princess','pimp','gay','cop','slayer', 'vampire', 42 - 'vampyre','blood','pain','brute','wolf','sword','star','sun','moon', 43 - 'killer','murderer','thief','arson','fire','ice','frost','hack', 44 - 'hacker','god','master','mistress','slave','rage','freeze','flayer', 45 - 'pirate','ninja','shadow','fog','mist','misery','glory','bear', 46 - 'king','queen','empress','emperor','majesty','space','martian', 47 - 'winter','fall','monk','katana','420','warrior','banana','demon', 48 - 'devil','ghost','wraith','cuck','legend','hero','heroine','goblin', 49 - 'gremlin','troll','dragon','evil','overlord','radiance' 50 - ) 51 - var adjs = array( 52 - 'dark','super','supreme','ultra','ultimate','total','infinite', 53 - 'omnipotent','crazy','final','deathless','immortal', 'elite', 54 - 'leet','1337','bloody','fearless','headless','screaming','insane', 55 - 'brutal','legendary','space','frozen','flaming','burning', 56 - 'mighty','flayed','hidden','secret','lost','mystery','glorious', 57 - 'nude','naked','bare','first','radiant','martian','fallen', 58 - 'wandering','dank','demonic','satanic','invisible','based','woke', 59 - 'deadly','lethal','heroic','evil','majestic','luminous' 60 - ) 41 + var nouns = splitwords [[ 42 + thunder bride blaze doom squad gun lord blaster 43 + fuck hell hound piss shit killa terror horror 44 + fear slaughter murder general commander commissar 45 + terrorist infinity slut cunt whore bitch bastard 46 + cock prince princess pimp gay cop slayer vampire 47 + vampyre blood pain brute wolf sword star sun moon 48 + killer murderer thief arson fire ice frost hack 49 + hacker god master mistress slave rage freeze flayer 50 + pirate ninja shadow fog mist misery glory bear 51 + king queen empress emperor majesty space martian 52 + winter fall monk katana 420 warrior banana demon 53 + devil ghost wraith cuck legend hero heroine goblin 54 + gremlin troll dragon evil overlord radiance slop 55 + operator rage hog bog roach wizard 56 + ]] 57 + var adjs = splitwords [[ 58 + dark super supreme ultra ultimate total infinite 59 + omnipotent crazy final deathless immortal elite 60 + leet 1337 bloody fearless headless screaming insane 61 + brutal legendary space frozen flaming burning 62 + mighty flayed hidden secret lost mystery glorious 63 + nude naked bare first radiant martian fallen bog 64 + wandering dank demonic satanic invisible based woke 65 + deadly lethal heroic evil majestic luminous ethereal 66 + ]] 61 67 62 68 if xXx then a:lpush('xXx_') end 63 69 64 70 if useadj then 65 71 var len = rnd(uint8,1,3) 66 72 for i = 0, len do 67 73 var sz = a.sz 68 - a:push(adjs[rnd(intptr,0,[adjs.type.N])], 0) 74 + a:ppush(adjs[rnd(intptr,0,[adjs.type.N])]) 69 75 if punct ~= nil then a:push(punct, 1) end 70 76 if caps == 1 then 71 77 a.buf[sz] = lib.str.cupcase(a.buf[sz]) 72 78 end 73 79 end 74 80 end 75 81 var nounct = rnd(uint8,1,3) 76 82 for i = 0, nounct do 77 83 var sz = a.sz 78 - a:push(nouns[rnd(intptr,0,[nouns.type.N])], 0) 84 + a:ppush(nouns[rnd(intptr,0,[nouns.type.N])]) 79 85 if punct ~= nil and i+1 ~= nounct then a:push(punct, 1) end 80 86 if caps == 1 then 81 87 a.buf[sz] = lib.str.cupcase(a.buf[sz]) 82 88 end 83 89 end 84 90 85 - if leet or caps == 2 then for i=start, a.sz do 86 - if caps == 2 and rnd(uint8,0,5)==0 then 91 + if leet or caps == 9 then for i=start, a.sz do 92 + if caps == 9 and rnd(uint8,0,5)==0 then 87 93 a.buf[i] = lib.str.cupcase(a.buf[i]) 88 94 end 89 95 if leet then 90 96 switch lib.str.cdowncase(a.buf[i]) do 91 97 case [uint8]([string.byte('e')]) then a.buf[i] = @'3' end 92 98 case [uint8]([string.byte('i')]) then a.buf[i] = @'1' end 93 99 case [uint8]([string.byte('l')]) then a.buf[i] = @'1' end ................................................................................ 97 103 case [uint8]([string.byte('b')]) then a.buf[i] = @'6' end 98 104 end 99 105 end 100 106 end end 101 107 102 108 if (nounct == 1 and not useadj) or rnd(uint8, 0, 5) == 0 then 103 109 if punct ~= nil then a:push(punct, 1) end 104 - a:ipush(rnd(uint16,0,65535)) 110 + a:ipush(rnd(uint32,0,lib.math.pow(10,rnd(uint8,1,4)))) 105 111 end 106 112 107 113 if xXx then a:lpush('_xXx') end 108 114 109 115 end 110 116 111 117 local terra 112 118 suggest_domain(a: &lib.str.acc) 113 - var tlds = array('tld','club','town','space','xxx') 119 + var words = splitwords [[ 120 + flop slop hop wiggle wriggle bug snoot boop jorts horse rad 121 + witch witches cum code spank grump grumps slap spoop spoopy 122 + spook wobble flip jock nerd dope dork slab drug funk gay 123 + hex node snack weed pot slug worm fur fuzz fuzzy game gamer 124 + rock smack drank wack wild sexy hot sin cock fuck piss man 125 + wank fae weird woke slurp spine skull fail elf elves mom 126 + dad dog cat kitten snake troll top bottom chungus dong wang 127 + 420 hog lover lovers best worst love hate big bigger tiny 128 + little teeny spunky jazz wrack rump kink kinky crack meth 129 + whore cam live over under turbo pizza rat rats crotch crank 130 + chunky funky butt grab grabber grabbers thief steal slave 131 + slaves hug hugs hag hags hogs wimp thieves wizard wizards 132 + pussy pansy dark doom stank spunk dumb rage 133 + ]] 134 + var tlds = splitwords [[ 135 + tld club town space xxx house land ranch horse com io online 136 + shop site vip ltd win men lgbt cat adult army analytics art 137 + associates bar bible biz black blog broker cam camp careers 138 + catering church city coop dad date dating direct diy dog 139 + duck dot enterprises esq estate expert express fail farm foo 140 + forsale fun fund forum foundation gay global golf gop guru 141 + group hangout hot industries international info investments 142 + jobs land law life limited live lol mom network now party 143 + porn productions pub rehab rocks school sex sexy singles 144 + social software solutions space spot store sucks supplies 145 + systems university vacations ventures wang website work 146 + wow wtf world xyz soy live gym park 147 + ]] 148 + var sub = rnd(uint8,0,10) == 0 149 + if sub then a:ppush(words[rnd(intptr,0,[words.type.N])]):lpush('.') end 150 + a:ppush(words[rnd(intptr,0,[words.type.N])]) 151 + if rnd(uint8,0,3) == 0 or not sub then 152 + a:ppush(words[rnd(intptr,0,[words.type.N])]) 153 + end 154 + a:lpush('.'):ppush(tlds[rnd(intptr,0,[tlds.type.N])]) 114 155 end 115 156 116 157 local push_num_field = macro(function(acc,name,lbl,min,max,value,disable) 117 158 name = name:asvalue() 118 159 lbl = lbl:asvalue() 119 160 local start = '<div class="elem small">' 120 161 local enabled = start .. string.format('<label for="%s">%s</label><input type="number" id="%s" name="%s" min="', name, lbl, name, name) ................................................................................ 290 331 ctlbox:append(&pg) 291 332 --ctlbox.name:free() 292 333 --if ctlbox.btns.ct > 0 then ctlbox.btns:free() end 293 334 294 335 return pg:finalize() 295 336 end 296 337 else 297 - var modes = array(P'local', P'remote', P'staff', P'titled', P'peons', P'all') 338 + var modes = arrayof(pstr,'local', 'remote', 'staff', 'titled', 'peons', 'all') 298 339 var idbuf: int8[lib.math.shorthand.maxlen] 299 340 var ulst = co:stra(256) 300 341 var mode: uint8 = mode_local 301 342 var modestr = co:pgetv('show') 302 343 ulst:lpush('<div style="text-align: right"><em>showing ') 303 344 for i=0,[modes.type.N] do 304 345 if modestr:ref() and modes[i]:cmp(modestr) then mode = i end ................................................................................ 345 386 ulst:lpush('</ul>') 346 387 347 388 if co.who.rights.powers.invite() or co.who.rights.invites > 0 then 348 389 ulst:lpush('<details><summary>create new user</summary><form method="post"><div class="elem"><label for="handle">handle</label><input type="text" name="handle" id="handle" placeholder="') 349 390 suggest_handle(&ulst) 350 391 ulst:lpush('"></div><button name="act" value="create">create</button></form></details>') 351 392 end 352 - ulst:lpush('<details><summary>instantiate remote actor</summary><form method="post"><div class="elem"><label for="xid">xid</label><input type="text" name="xid" id="xid" placeholder="tweetlord@website.tld"></div><button name="act" value="inst">instantiate</button></form></details>') 393 + ulst:lpush('<details><summary>instantiate remote actor</summary><form method="post"><div class="elem"><label for="xid">xid</label><input type="text" name="xid" id="xid" placeholder="') 394 + suggest_handle(&ulst) ulst:lpush('@') suggest_domain(&ulst) 395 + ulst:lpush('"></div><button name="act" value="inst">instantiate</button></form></details>') 353 396 354 397 return ulst:finalize() 355 398 end 356 399 do return pstr.null() end 357 400 ::e404:: co:complain(404, 'not found', 'there is no user or resource by that identifier on this server') goto quit 358 401 ::e403:: co:complain(403, 'forbidden', 'you do not have sufficient authority to control that resource') 359 402 360 403 ::quit:: return pstr.null() 361 404 end 362 405 363 406 return render_conf_users
Modified render/docpage.t from [9f2f406de7] to [704653b9d0].
1 1 -- vim: ft=terra 2 2 local page = lib.srv.convo.page 3 3 local pstr = lib.mem.ptr(int8) 4 4 local pref = lib.mem.ref(int8) 5 -local P = lib.str.plit 6 -local R = lib.str.lit 7 5 8 6 local topics = lib.util.keys(data.doc) 9 7 local topicidxt = {} 10 8 table.sort(topics) -- because deterministic builds are good 11 9 local branches = {} 12 10 for i,k in pairs(topics) do 13 11 topicidxt[k] = i ................................................................................ 36 34 if t.meta.priv then 37 35 if type(t.meta.priv) ~= 'table' then t.meta.priv = {t.meta.priv} end 38 36 for _,v in pairs(t.meta.priv) do 39 37 setbits = quote [setbits]; (restrict.[v] << true) end 40 38 end 41 39 end 42 40 allpages[i] = quote var [restrict]; [setbits] in pgpair { 43 - name = R(v); 41 + name = [v]; 44 42 parent = par; 45 43 priv = restrict; 46 - title = R(t.meta.title); 44 + title = [t.meta.title]; 47 45 content = page { 48 46 title = ['documentation :: ' .. t.meta.title]; 49 47 body = [ t.text ]; 50 - class = P'doc article'; 48 + class = 'doc article'; 51 49 cache = true; 52 50 }; 53 51 } end 54 52 end 55 53 56 54 local terra 57 55 showpage(co: &lib.srv.convo, id: pref) ................................................................................ 107 105 end 108 106 end 109 107 list:lpush('</ul>') 110 108 111 109 co:stdpage(page { 112 110 title = 'documentation'; 113 111 body = list:finalize(); 114 - class = P'doc listing'; 112 + class = 'doc listing'; 115 113 cache = false; 116 114 }) 117 115 else showpage(co, pg) end 118 116 end 119 117 120 118 return render_docpage
Modified render/login.t from [7ea4ccf2b4] to [434636bebc].
1 1 -- vim: ft=terra 2 2 local pstr = lib.mem.ptr(int8) 3 -local P = lib.str.plit 4 3 local terra 5 4 login_form(co: &lib.srv.convo, user: &lib.store.actor, creds: &lib.store.credset, msg: pstr) 6 5 var doc = [lib.srv.convo.page] { 7 - title = lib.str.plit 'instance logon'; 8 - class = lib.str.plit 'login'; 6 + title = 'instance logon'; 7 + class = 'login'; 9 8 cache = false; 10 9 } 11 10 12 11 if user == nil then 13 12 var form = data.view.login_username { 14 13 loginmsg = msg; 15 14 } 16 15 if form.loginmsg.ptr == nil then 17 - form.loginmsg = lib.str.plit 'identify yourself for access to this instance.' 16 + form.loginmsg = 'identify yourself for access to this instance.' 18 17 end 19 18 doc.body = form:tostr() 20 19 elseif creds:sz() == 0 then 21 20 co:complain(403,'access denied','your host is not eligible to authenticate as this user') 22 21 return 23 22 elseif creds:sz() == 1 then 24 23 if creds.trust() then ................................................................................ 27 26 end 28 27 29 28 var ch = data.view.login_challenge { 30 29 handle = user.handle; 31 30 name = lib.coalesce(user.nym, user.handle); 32 31 } 33 32 if creds.pw() then 34 - ch.challenge = P'enter the password associated with your account' 35 - ch.label = P'password' 36 - ch.method = P'pw' 37 - ch.auto = P'current-password'; 33 + ch.challenge = 'enter the password associated with your account' 34 + ch.label = 'password' 35 + ch.method = 'pw' 36 + ch.auto = 'current-password'; 38 37 elseif creds.otp() then 39 - ch.challenge = P'enter a valid one-time password for your account' 40 - ch.label = P'OTP code' 41 - ch.method = P'otp' 42 - ch.auto = P'one-time-code'; 38 + ch.challenge = 'enter a valid one-time password for your account' 39 + ch.label = 'OTP code' 40 + ch.method = 'otp' 41 + ch.auto = 'one-time-code'; 43 42 elseif creds.challenge() then 44 - ch.challenge = P'sign the challenge token: <code>...</code>' 45 - ch.label = P'digest' 46 - ch.method = P'challenge' 47 - ch.auto = P'one-time-code'; 43 + ch.challenge = 'sign the challenge token: <code>...</code>' 44 + ch.label = 'digest' 45 + ch.method = 'challenge' 46 + ch.auto = 'one-time-code'; 48 47 else 49 48 co:complain(500,'login failure','unknown login method') 50 49 return 51 50 end 52 51 53 52 doc.body = ch:tostr() 54 53 else
Modified render/media-gallery.t from [18e4a71c1d] to [1f18c83945].
1 1 -- vim: ft=terra 2 2 local pstr = lib.str.t 3 -local P = lib.str.plit 4 3 local terra cs(s: rawstring) 5 4 return pstr { ptr = s, ct = lib.str.sz(s) } 6 5 end 7 6 8 7 local show_all,show_new,show_unfiled,show_files,show_vid,show_img=1,2,3,4,5,6 9 8 10 9 local terra ................................................................................ 21 20 var pa = co:stra(32) 22 21 pa:lpush('/') 23 22 if ou(0).origin ~= 0 then pa:lpush('@') end 24 23 pa:push(ou(0).xid,0) 25 24 pfx = pa:finalize() 26 25 end 27 26 28 - if path.ct >= 3 and path(1):cmp(lib.str.lit'a') then 27 + if path.ct >= 3 and path(1):cmp('a') then 29 28 var id, idok = lib.math.shorthand.parse(path(2).ptr, path(2).ct) 30 29 if not idok then goto e404 end 31 30 var art = co.srv:artifact_fetch(uid, id) 32 31 if not art then goto e404 end 33 32 if path.ct == 3 then 34 33 -- sniff out the artifact type and display the appropriate viewer 35 34 var artid = cs(art(0).url) ................................................................................ 45 44 pfx = pfx, desc = desc; 46 45 id = artid; btns = btntxt; 47 46 } 48 47 if lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then 49 48 var view = data.view.media_image(viewerprops) 50 49 var pg = view:poolstr(&co.srv.pool) 51 50 co:stdpage([lib.srv.convo.page] { 52 - title = lib.str.plit'media :: image'; 53 - class = lib.str.plit'media viewer img'; 51 + title = 'media :: image'; 52 + class = 'media viewer img'; 54 53 cache = false, body = pg; 55 54 }) 56 55 --pg:free() 57 56 elseif lib.str.cmp(art(0).mime, 'text/markdown') == 0 then 58 57 var view = data.view.media_text(viewerprops) 59 58 var text, mime = co.srv:artifact_load(id) mime:free() 60 59 view.text = lib.smackdown.html(&co.srv.pool, pstr{[rawstring](text.ptr),text.ct}, false) 61 60 text:free() 62 61 var pg = view:poolstr(&co.srv.pool) 63 62 --view.text:free() 64 63 co:stdpage([lib.srv.convo.page] { 65 - title = lib.str.plit'media :: text'; 66 - class = lib.str.plit'media viewer text'; 64 + title = 'media :: text'; 65 + class = 'media viewer text'; 67 66 cache = false, body = pg; 68 67 }) 69 68 --pg:free() 70 69 elseif 71 70 lib.str.ncmp(art(0).mime, 'text/', 5) == 0 or 72 71 lib.str.cmp(art(0).mime, 'application/x-perl') == 0 or 73 72 lib.str.cmp(art(0).mime, 'application/sql') == 0 ................................................................................ 78 77 var san = lib.html.sanitize(&co.srv.pool,pstr{[rawstring](text.ptr),text.ct}, false) 79 78 text:free() 80 79 view.text = co:qstr('<pre>',san,'</pre>') 81 80 --san:free() 82 81 var pg = view:poolstr(&co.srv.pool) 83 82 --view.text:free() 84 83 co:stdpage([lib.srv.convo.page] { 85 - title = lib.str.plit'media :: text'; 86 - class = lib.str.plit'media viewer text'; 84 + title = 'media :: text'; 85 + class = 'media viewer text'; 87 86 cache = false, body = pg; 88 87 }) 89 88 --pg:free() 90 89 else co:complain(500,'bad file type','this file type is not supported') end 91 90 elseif path.ct == 4 then 92 91 var act = path(3) 93 92 var curl = co:qstr('/media/a/', path(2)) 94 93 -- defer curl:free() 95 - if act:cmp(lib.str.lit'avi') and lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then 94 + if act:cmp('avi') and lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then 96 95 co:confirm('set avatar', 'are you sure you want this image to be your new avatar?',curl) 97 - elseif act:cmp(lib.str.lit'del') then 96 + elseif act:cmp('del') then 98 97 co:confirm('delete', 'are you sure you want to permanently delete this artifact?',curl) 99 98 else goto e404 end 100 99 end 101 100 else 102 101 var mode: uint8 = show_new 103 102 var folder: pstr 104 103 if path.ct == 2 then 105 - if path(1):cmp(lib.str.lit'unfiled') then 104 + if path(1):cmp('unfiled') then 106 105 mode=show_unfiled 107 - elseif path(1):cmp(lib.str.lit'all') then 106 + elseif path(1):cmp('all') then 108 107 mode=show_all 109 108 else goto e404 end 110 - elseif path.ct == 3 and path(1):cmp(lib.str.lit'kind') then 109 + elseif path.ct == 3 and path(1):cmp('kind') then 111 110 end 112 111 113 112 var folders = co.srv:artifact_folder_enum(uid) 114 113 115 114 if mode == show_new then 116 - folder = lib.str.plit'' 115 + folder = '' 117 116 elseif mode == show_all or mode == show_unfiled then 118 117 folder = pstr.null() 119 118 end 120 119 121 120 var view = data.view.media_gallery { 122 121 menu = pstr{'',0}; 123 122 folders = pstr{'',0}; ................................................................................ 142 141 end 143 142 fa:lpush('<hr>') 144 143 view.folders = fa:finalize() 145 144 folders:free() 146 145 end 147 146 148 147 if owner then 149 - view.menu = P'<a class="pos" href="/media/upload">upload</a><hr>' 148 + view.menu = '<a class="pos" href="/media/upload">upload</a><hr>' 150 149 end 151 150 152 151 var md = co.srv:artifact_enum_uid(uid, folder) 153 152 var gallery: lib.str.acc gallery:pool(&co.srv.pool,256) 154 153 var files: lib.str.acc files:pool(&co.srv.pool,256) 155 154 for i=0,md.ct do 156 155 var desc = lib.smackdown.html(&co.srv.pool,pstr{md(i)(0).desc,0}, true) --defer desc:free() ................................................................................ 173 172 view.directory = files:finalize() 174 173 175 174 if acc ~= nil then 176 175 view:append(acc) 177 176 else 178 177 var pg = view:poolstr(&co.srv.pool) -- defer pg:free() 179 178 co:stdpage([lib.srv.convo.page] { 180 - title = P'media'; 181 - class = P'media manager'; 179 + title = 'media'; 180 + class = 'media manager'; 182 181 cache = false; 183 182 body = pg; 184 183 }) 185 184 end 186 185 187 186 --view.images:free() 188 187 --view.directory:free()
Modified render/notices.t from [1e81acf0af] to [75a5e28d82].
1 1 -- vim: ft=terra 2 2 local pstr = lib.mem.ptr(int8) 3 -local P = lib.str.plit 4 3 local terra cs(s: rawstring) 5 4 return pstr { ptr = s, ct = lib.str.sz(s) } 6 5 end 7 6 8 7 local terra 9 8 render_notices( 10 9 co: &lib.srv.convo ................................................................................ 33 32 avatar = cs(who(0).avatar); 34 33 nym = lib.render.nym(who.ptr,0,nil,true); 35 34 pflink = pstr{ptr = pflink.buf; ct = pflink.sz}; 36 35 } 37 36 var notweet, nopost = true, false 38 37 switch notes(i).kind do 39 38 case lib.store.noticetype.rt then 40 - n.kind = P'rt' 41 - n.act = P'retweeted your post' 39 + n.kind = 'rt' 40 + n.act = 'retweeted your post' 42 41 end 43 42 case lib.store.noticetype.like then 44 - n.kind = P'like' 45 - n.act = P'likes your post' 43 + n.kind = 'like' 44 + n.act = 'likes your post' 46 45 end 47 46 case lib.store.noticetype.reply then 48 - n.kind = P'reply' 49 - n.act = P'replied to your post' 47 + n.kind = 'reply' 48 + n.act = 'replied to your post' 50 49 notweet = false 51 50 end 52 51 case lib.store.noticetype.follow then 53 - n.kind = P'follow' 54 - n.act = P'followed you!' 52 + n.kind = 'follow' 53 + n.act = 'followed you!' 55 54 nopost = true 56 55 end 57 56 else goto skip end 58 57 if not nopost then 59 58 var what = co.srv:post_fetch(notes(i).what) defer what:free() 60 59 var b = lib.smackdown.html(&co.srv.pool, pstr {ptr=what(0).body,ct=0},true) --defer b:free() 61 60 body:lpush(' <a class="quote" href="/post/'):shpush(notes(i).what):lpush('">'):ppush(b):lpush('</a>') ................................................................................ 71 70 ::skip:: n.nym:free() 72 71 pflink:reset() 73 72 body:reset() 74 73 end 75 74 --pflink:free() 76 75 pg:lpush('<form method="post"><button name="act" value="clear">clear all notices</button></form>') 77 76 co:livepage([lib.srv.convo.page] { 78 - title = P'notices', class = P'notices'; 77 + title = 'notices', class = 'notices'; 79 78 body = pstr {ptr = pg.buf, ct = pg.sz}; 80 79 cache = false; 81 80 }, latest) 82 81 end 83 82 84 83 return render_notices
Modified render/profile.t from [849244d87f] to [f79f7a1ea9].
32 32 33 33 var strfbuf: int8[28*4] 34 34 var stats = co.srv:actor_stats(actor.id) 35 35 var sn_posts = cs(lib.math.decstr_friendly(stats.posts, &strfbuf[ [strfbuf.type.N - 1] ])) 36 36 var sn_follows = cs(lib.math.decstr_friendly(stats.follows, sn_posts.ptr - 1)) 37 37 var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1)) 38 38 var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1)) 39 - var bio = lib.str.plit '<em style="opacity:0.6">tall, dark, and mysterious</em>' 39 + var bio = pstr '<em style="opacity:0.6">tall, dark, and mysterious</em>' 40 40 if actor.bio ~= nil then 41 41 bio = lib.smackdown.html(&co.srv.pool,cs(actor.bio),false) 42 42 end 43 43 var fullname = lib.render.nym(actor,0,nil,false) defer fullname:free() 44 44 var comments = co:stra(64) 45 45 46 46 if co.srv.cfg.master == actor.id then 47 - var foundertxt = lib.str.plit 'founder' 47 + var foundertxt = pstr 'founder' 48 48 if co.srv.cfg.ui_cue_founder:ref() then 49 49 if co.srv.cfg.ui_cue_founder.ct == 0 -- empty string, suppress field 50 50 then foundertxt = pstr.null() 51 51 else foundertxt = co.srv.cfg.ui_cue_founder 52 52 end 53 53 end 54 54 55 55 if foundertxt:ref() then 56 56 comments:lpush('<li style="--co:-70">'):ppush(foundertxt):lpush('</li>') 57 57 end 58 58 end 59 59 if co.aid ~= 0 and actor.rights.rank ~= 0 then 60 - var stafftxt = lib.str.plit 'site staff' 60 + var stafftxt = pstr 'site staff' 61 61 if co.srv.cfg.ui_cue_staff:ref() then 62 62 if co.srv.cfg.ui_cue_staff.ct == 0 -- empty string, suppress field 63 63 then stafftxt = pstr.null() 64 64 else stafftxt = co.srv.cfg.ui_cue_staff 65 65 end 66 66 end 67 67 ................................................................................ 88 88 bio = bio; 89 89 xid = cs(actor.xid); 90 90 avatar = cs(actor.avatar); 91 91 92 92 nposts = sn_posts, nfollows = sn_follows; 93 93 nfollowers = sn_followers, nmutuals = sn_mutuals; 94 94 tweetday = cs(timestr); 95 - timephrase = lib.trn(actor.origin == 0, lib.str.plit'joined', lib.str.plit'known since'); 95 + timephrase = lib.trn(actor.origin == 0, pstr 'joined', pstr 'known since'); 96 96 97 97 remarks = ''; 98 98 99 99 auxbtn = auxp; 100 100 } 101 101 if comments.sz > 0 then profile.remarks = comments:finalize() end 102 102
Modified render/timeline.t from [7375f87c90] to [9997258dca].
22 22 from_time = stoptime; 23 23 to_idx = 64; 24 24 }) 25 25 elseif mode == modes.fediglobal then 26 26 elseif mode == modes.circle then 27 27 end 28 28 29 - var acc: lib.str.acc acc:pool(&co.srv.pool,1024) 29 + var acc = co:stra(1024) 30 30 acc:lpush('<div id="tl" data-live="10">') 31 31 var newest: lib.store.timepoint = 0 32 32 for i = 0, posts.sz do 33 33 lib.render.tweet(co, posts(i).ptr, &acc) 34 34 var t = lib.math.biggest(lib.math.biggest(posts(i).ptr.posted, posts(i).ptr.discovered),posts(i).ptr.edited) 35 35 if t > newest then newest = t end 36 36 posts(i):free() 37 37 end 38 38 posts:free() 39 39 acc:lpush('</div>') 40 40 41 41 var doc = [lib.srv.convo.page] { 42 - title = lib.str.plit'timeline'; 42 + title = 'timeline'; 43 43 body = acc:finalize(); 44 - class = lib.str.plit'timeline'; 44 + class = 'timeline'; 45 45 cache = false; 46 46 } 47 47 co:livepage(doc,newest) 48 48 --doc.body:free() 49 49 end 50 50 return render_timeline
Modified render/tweet-page.t from [304c6c3aff] to [6d8fb63eed].
60 60 61 61 if co.aid ~= 0 and co.who.rights.powers.post() then 62 62 lib.render.compose(co, nil, &pg) 63 63 end 64 64 65 65 var ppg = pg:finalize() --defer ppg:free() 66 66 co:livepage([lib.srv.convo.page] { 67 - title = lib.str.plit 'post'; cache = false; 68 - class = lib.str.plit 'post'; body = ppg; 67 + title = 'post'; cache = false; 68 + class = 'post'; body = ppg; 69 69 }, livetime) 70 70 71 71 -- TODO display conversation 72 72 -- perhaps display descendant nodes here, and have a link to the top of the whole tree? 73 73 end 74 74 75 75 return render_tweet_page
Modified render/user-page.t from [be37fdb666] to [d4b538d774].
34 34 end 35 35 posts:free() 36 36 acc:lpush('</div>') 37 37 38 38 var bdf = acc:finalize() 39 39 co:livepage([lib.srv.convo.page] { 40 40 title = tiptr; body = bdf; 41 - class = lib.str.plit 'profile'; 41 + class = 'profile'; 42 42 cache = false; 43 43 }, newest) 44 44 45 45 tiptr:free() 46 46 --bdf:free() 47 47 end 48 48 49 49 return render_userpage
Modified route.t from [efbc5e4a8e] to [6caa1366ba].
451 451 end 452 452 453 453 msg = 'profile changes saved' 454 454 --user_refresh = true -- not really necessary here, actually 455 455 456 456 elseif path(1):cmp('sec') then 457 457 credsec_for_uid(co, co.who.id) 458 + elseif path(1):cmp('avi') then 459 + var act = co:ppostv('act') 460 + if act:ref() and act:cmp('clear') then 461 + co.who.avatarid = 0 462 + co.who.source:actor_save(co.who) 463 + msg = 'avatar reset to default' 464 + else goto badop end 458 465 elseif path(1):cmp('users') then 459 466 if path.ct >= 3 then 460 467 var userid, ok = lib.math.shorthand.parse(path(2).ptr, path(2).ct) 461 468 if ok then 462 469 var usr = co.srv:actor_fetch_uid(userid) 463 470 if usr:ref() then --defer usr:free() 464 471 if not co.who:overpowers(usr.ptr) then
Modified srv.t from [baac561cfe] to [2ff93305a1].
237 237 terra convo:stdpage(pg: convo.page) self:statpage(200, pg) end 238 238 239 239 terra convo:bytestream(mime: pstring, data: lib.mem.ptr(uint8)) 240 240 -- TODO this is not a satisfactory solution; it's a bandaid on a gaping 241 241 -- chest wound. ultimately we need to compile a whitelist of safe mime 242 242 -- types as part of mimelib, but that is no small task. for now, this 243 243 -- will keep the patient from immediately bleeding out 244 - if mime:cmp(lib.str.plit'text/html') or 245 - mime:cmp(lib.str.plit'text/xml') or 246 - mime:cmp(lib.str.plit'application/xhtml+xml') or 247 - mime:cmp(lib.str.plit'application/vnd.wap.xhtml+xml') 244 + if mime:cmp('text/html') or 245 + mime:cmp('text/xml') or 246 + mime:cmp('application/xhtml+xml') or 247 + mime:cmp('application/vnd.wap.xhtml+xml') 248 248 then -- danger will robinson 249 - mime = lib.str.plit'text/plain' 250 - elseif mime:cmp(lib.str.plit'application/x-shockwave-flash') then 251 - mime = lib.str.plit'application/octet-stream' 249 + mime = 'text/plain' 250 + elseif mime:cmp('application/x-shockwave-flash') then 251 + mime = 'application/octet-stream' 252 252 end 253 253 lib.net.mg_printf(self.con, "HTTP/1.1 200 OK\r\nContent-Type: %.*s\r\nContent-Length: %llu\r\nContent-Security-Policy: sandbox; default-src 'none'; form-action 'none'; navigate-to 'none';\r\nX-Content-Options: nosniff\r\n\r\n", mime.ct, mime.ptr, data.ct + 2) 254 254 lib.net.mg_send(self.con, data.ptr, data.ct) 255 255 lib.net.mg_send(self.con, '\r\n', 2) 256 256 end 257 257 258 258 terra convo:reroute_cookie(dest: rawstring, cookie: rawstring) ................................................................................ 293 293 if msg == nil then msg = "i'm sorry, dave. i can't let you do that" end 294 294 295 295 var ti: lib.str.acc ti:compose('error :: ', title) 296 296 var bo: lib.str.acc bo:compose('<div class="message"><img class="icon" src="/s/warn.svg"><h1>',title,'</h1><p>',msg,'</p></div>') 297 297 var body = [convo.page] { 298 298 title = ti:finalize(); 299 299 body = bo:finalize(); 300 - class = lib.str.plit 'error'; 300 + class = 'error'; 301 301 cache = false; 302 302 } 303 303 304 304 self:statpage(code, body) 305 305 306 306 body.title:free() 307 307 body.body:free() ................................................................................ 313 313 query = msg; 314 314 cancel = cancel; 315 315 } 316 316 var ti: lib.str.acc ti:pcompose(&self.srv.pool,'confirm :: ', title) 317 317 var body = conf:poolstr(&self.srv.pool) -- defer body:free() 318 318 var cf = [convo.page] { 319 319 title = ti:finalize(); 320 - class = lib.str.plit 'query'; 320 + class = 'query'; 321 321 body = body; cache = false; 322 322 } 323 323 self:stdpage(cf) 324 324 --cf.title:free() 325 325 end 326 326 327 327 terra convo:stra(sz: intptr) -- convenience function ................................................................................ 629 629 var halt = lib.str.find(@lsent, lsr) 630 630 if halt:ref() then 631 631 lsent.ct = halt.ptr - lsent.ptr 632 632 end 633 633 lsr:free() end 634 634 635 635 for i=0,upmap.ct do 636 - var hdrbrk = lib.str.find(upmap(i), lib.str.plit'\r\n\r\n') 636 + var hdrbrk = lib.str.find(upmap(i), '\r\n\r\n') 637 637 if hdrbrk:ref() then 638 638 var hdrtxt = pstring {upmap(i).ptr,upmap(i).ct - hdrbrk.ct} 639 639 var hdrs = lib.str.splitmap(hdrtxt, '\r\n',6) 640 640 var ctt = pstring.null() 641 641 var ctd = pstring.null() 642 642 for j=0, hdrs.ct do 643 - var brk = lib.str.find(hdrs(j),lib.str.plit':') 643 + var brk = lib.str.find(hdrs(j),':') 644 644 if brk:ref() then 645 645 var hdr = pstring{hdrs(j).ptr,hdrs(j).ct - brk.ct} 646 646 var val = pstring{brk.ptr+1, brk.ct-1}:ffw() 647 - if hdr:cmp(lib.str.plit'Content-Type') then 647 + if hdr:cmp('Content-Type') then 648 648 ctt = val 649 - elseif hdr:cmp(lib.str.plit'Content-Disposition') then 649 + elseif hdr:cmp('Content-Disposition') then 650 650 ctd = val 651 651 end 652 652 end 653 653 end 654 654 if ctd:ref() then 655 655 var ctdvals = lib.str.splitmap(ctd, ';', 4) defer ctdvals:free() 656 - if ctdvals(0):cmp(lib.str.plit'form-data') and ctdvals.ct > 1 then 656 + if ctdvals(0):cmp('form-data') and ctdvals.ct > 1 then 657 657 var fld = pstring.null() 658 658 var file = pstring.null() 659 659 for j=1, ctdvals.ct do var v = ctdvals(j):ffw() 660 - var x = lib.str.find(v,lib.str.plit'=') 660 + var x = lib.str.find(v,'=') 661 661 if x:ref() then 662 662 var key = pstring{v.ptr, v.ct - x.ct} 663 663 var val = pstring{x.ptr + 1, x.ct - 1} 664 664 var decval, ofs, sp = lib.str.toknext(val,@';',true) 665 - if key:cmp(lib.str.plit'name') then 665 + if key:cmp('name') then 666 666 fld = decval 667 - elseif key:cmp(lib.str.plit'filename') then 667 + elseif key:cmp('filename') then 668 668 file = decval 669 669 else decval:free() end 670 670 end 671 671 end 672 672 if fld:ref() then 673 673 var nextup = co.uploads:new() 674 674 if ctt:ref() then ................................................................................ 937 937 end 938 938 return default 939 939 end 940 940 941 941 terra cfgcache:cfbool(name: rawstring, default: bool) 942 942 var str = self.overlord:conf_get(name) 943 943 if str.ptr ~= nil then 944 - if str:cmp(lib.str.plit 'true') or str:cmp(lib.str.plit 'on') or 945 - str:cmp(lib.str.plit 'yes') or str:cmp(lib.str.plit '1') then 944 + if str:cmp('true') or str:cmp('on') or 945 + str:cmp('yes') or str:cmp('1') then 946 946 default = true 947 - elseif str:cmp(lib.str.plit 'false') or str:cmp(lib.str.plit 'off') or 948 - str:cmp(lib.str.plit 'no') or str:cmp(lib.str.plit '0') then 947 + elseif str:cmp('false') or str:cmp('off') or 948 + str:cmp('no') or str:cmp('0') then 949 949 default = false 950 950 else 951 951 lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected boolean; using default value instead') 952 952 end 953 953 str:free() 954 954 end 955 955 return default
Modified static/style.scss from [08446e37b3] to [e23a7affc6].
287 287 grid-row: 1 / 2; 288 288 display: grid; 289 289 grid-template-columns: 1.1in 1fr; 290 290 grid-template-rows: max-content 1fr; 291 291 > .avatar { 292 292 display: block; 293 293 width: 1in; height: 1in; 294 - object-fit: contain; 294 + object-fit: cover; 295 295 grid-column: 1 / 2; 296 296 grid-row: 1 / 3; 297 297 border: 1px solid black; 298 298 } 299 299 > .id { 300 300 grid-column: 2 / 3; 301 301 grid-row: 1 / 2; ................................................................................ 526 526 transition: 0.2s ease-out; 527 527 >.avatar { 528 528 grid-column: 1/2; grid-row: 1/2; 529 529 background: linear-gradient(to bottom, tone(-53%), tone(-57%)); 530 530 img { 531 531 display: block; width: 1in; height: 1in; margin:0; 532 532 border-right: 1px solid tone(-65%); 533 + object-fit: cover; 533 534 } 534 535 } 535 536 >a[href].username { 536 537 display: block; 537 538 grid-column: 1/3; 538 539 grid-row: 2/3; 539 540 text-align: left; ................................................................................ 665 666 padding-top: 0.12in; 666 667 background: linear-gradient(to right, tone(-50%), tone(-50%,-0.7)); 667 668 border: 1px solid tone(-55%); 668 669 border-left: none; 669 670 text-shadow: 1px 1px 0 black; 670 671 } 671 672 } 672 - 673 + img.avatar.big { 674 + display:block; 675 + width: 70%; 676 + height: auto; 677 + margin: 0.2in auto; 678 + border: 1px solid tone(-45%); 679 + border-top-color: tone(-40%); 680 + border-bottom: 2px solid tone(-60%); 681 + object-fit: cover; 682 + border-radius: 3px; 683 + } 673 684 } 674 685 675 686 hr { 676 687 border: none; 677 688 border-top: 1px solid tone(-30%); 678 689 border-bottom: 1px solid tone(-55%); 679 690 }
Modified store.t from [8b07464dc2] to [9b6251fcb3].
59 59 local function setmap(set) 60 60 local map = {} 61 61 local struct pt { name:lib.mem.ptr(int8), val:set } 62 62 for k,v in pairs(set.members) do 63 63 map[#map + 1] = quote 64 64 var ps: set ps:clear() 65 65 (ps.[v] << true) 66 - in pt {name = lib.str.plit(v), val = ps} end 66 + in pt {name = [v], val = ps} end 67 67 end 68 68 return map 69 69 end 70 70 m.powmap = setmap(m.powerset) 71 71 m.privmap = setmap(m.privset) 72 72 73 73 terra m.powerset:affect_users()
Modified str.t from [c8b5d8bfdc] to [c25d641c64].
36 36 do local strptr = (lib.mem.ptr(int8)) 37 37 local strref = (lib.mem.ref(int8)) 38 38 local byteptr = (lib.mem.ptr(uint8)) 39 39 local function install_funcs(ty) 40 40 ty.metamethods.__cast = function(from,to,e) 41 41 local v = e:asvalue() 42 42 if type(v) == 'string' then 43 - print('hard-coding pstr',v,#v) 44 43 return `ty {ptr = v, ct = [#v]} 45 44 elseif from == &int8 then 46 45 return `ty {ptr = e, ct = m.sz(e)} 47 46 elseif to == &int8 then 48 47 return e.ptr 49 48 end 50 49 end