Overview
| Comment: | enable profile editing |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
ac4a630ad562c1ae6efc8ee1a5a3e593 |
| User & Date: | lexi on 2020-12-30 02:44:15 |
| Other Links: | manifest | tags |
Context
|
2020-12-31
| ||
| 00:15 | add lots more shit check-in: d4ecea913f user: lexi tags: trunk | |
|
2020-12-30
| ||
| 02:44 | enable profile editing check-in: ac4a630ad5 user: lexi tags: trunk | |
| 00:43 | continued iteration check-in: 0324d62546 user: lexi tags: trunk | |
Changes
Modified backend/pgsql.t from [30de1dd276] to [d54604496b].
58 58 where $1::text = (a.handle || '@' || domain) or 59 59 $1::text = ('@' || a.handle || '@' || domain) or 60 60 (a.origin is null and 61 61 $1::text = a.handle or 62 62 $1::text = ('@' || a.handle)) 63 63 ]]; 64 64 }; 65 + 66 + actor_save = { 67 + params = { 68 + uint64, --id 69 + rawstring, --nym 70 + rawstring, --handle 71 + rawstring, --bio 72 + rawstring, --epithet 73 + rawstring, --avataruri 74 + uint64, --avatarid 75 + uint16, --rank 76 + uint32 --quota 77 + }, cmd = true, sql = [[ 78 + update parsav_actors set 79 + nym = $2::text, 80 + handle = $3::text, 81 + bio = $4::text, 82 + epithet = $5::text, 83 + avataruri = $6::text, 84 + avatarid = $7::bigint, 85 + rank = $8::smallint, 86 + quota = $9::integer 87 + --invites are controlled by their own specialized routines 88 + where id = $1::bigint 89 + ]]; 90 + }; 65 91 66 92 actor_create = { 67 93 params = { 68 94 rawstring, rawstring, uint64, lib.store.timepoint, 69 95 rawstring, rawstring, lib.mem.ptr(uint8), 70 96 rawstring, uint16, uint32 71 97 }; ................................................................................ 823 849 824 850 actor_enum = [terra(src: &lib.store.source) 825 851 var r = queries.actor_enum.exec(src) 826 852 if r.sz == 0 then 827 853 return [lib.mem.ptr(&lib.store.actor)] { ct = 0, ptr = nil } 828 854 else defer r:free() 829 855 var mem = lib.mem.heapa([&lib.store.actor], r.sz) 830 - for i=0,r.sz do mem.ptr[i] = row_to_actor(&r, i).ptr end 856 + for i=0,r.sz do 857 + mem.ptr[i] = row_to_actor(&r, i).ptr 858 + mem.ptr[i].source = src 859 + end 831 860 return [lib.mem.ptr(&lib.store.actor)] { ct = r.sz, ptr = mem.ptr } 832 861 end 833 862 end]; 834 863 835 864 actor_enum_local = [terra(src: &lib.store.source) 836 865 var r = queries.actor_enum_local.exec(src) 837 866 if r.sz == 0 then 838 867 return [lib.mem.ptr(&lib.store.actor)] { ct = 0, ptr = nil } 839 868 else defer r:free() 840 869 var mem = lib.mem.heapa([&lib.store.actor], r.sz) 841 - for i=0,r.sz do mem.ptr[i] = row_to_actor(&r, i).ptr end 870 + for i=0,r.sz do 871 + mem.ptr[i] = row_to_actor(&r, i).ptr 872 + mem.ptr[i].source = src 873 + end 842 874 return [lib.mem.ptr(&lib.store.actor)] { ct = r.sz, ptr = mem.ptr } 843 875 end 844 876 end]; 845 877 846 878 actor_auth_how = [terra( 847 879 src: &lib.store.source, 848 880 ip: lib.store.inet, ................................................................................ 934 966 935 967 timeline_instance_fetch = [terra(src: &lib.store.source, rg: lib.store.range) 936 968 var r = pqr { sz = 0 } 937 969 var A,B,C,D = rg:matrix() -- :/ 938 970 r = queries.timeline_instance_fetch.exec(src,A,B,C,D) 939 971 940 972 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 941 - for i=0,r.sz do ret.ptr[i] = row_to_post(&r, i) end -- MUST FREE ALL 973 + for i=0,r.sz do 974 + ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 975 + ret.ptr[i].ptr.source = src 976 + end 942 977 943 978 return ret 944 979 end]; 945 980 946 981 post_enum_author_uid = [terra( 947 982 src: &lib.store.source, 948 983 uid: uint64, ................................................................................ 949 984 rg: lib.store.range 950 985 ): lib.mem.ptr(lib.mem.ptr(lib.store.post)) 951 986 var r = pqr { sz = 0 } 952 987 var A,B,C,D = rg:matrix() -- :/ 953 988 r = queries.post_enum_author_uid.exec(src,A,B,C,D,uid) 954 989 955 990 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 956 - for i=0,r.sz do ret.ptr[i] = row_to_post(&r, i) end -- MUST FREE ALL 991 + for i=0,r.sz do 992 + ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 993 + ret.ptr[i].ptr.source = src 994 + end 957 995 958 996 return ret 959 997 end]; 960 998 961 999 actor_powers_fetch = getpow; 1000 + actor_save = [terra( 1001 + src: &lib.store.source, 1002 + ac: &lib.store.actor 1003 + ): {} 1004 + queries.actor_save.exec(src, 1005 + ac.id, ac.nym, ac.handle, 1006 + ac.bio, ac.epithet, ac.avatar, 1007 + ac.avatarid, ac.rights.rank, ac.rights.quota) 1008 + end]; 1009 + 962 1010 actor_save_privs = privupdate; 963 1011 964 1012 actor_create = [terra( 965 1013 src: &lib.store.source, 966 1014 ac: &lib.store.actor 967 1015 ): uint64 968 1016 var r = queries.actor_create.exec(src,ac.nym, ac.handle, ac.origin, ac.knownsince, ac.bio, ac.avatar, ac.key, ac.epithet, ac.rights.rank, ac.rights.quota)
Modified parsav.t from [b85f6f7647] to [dc97a3f269].
558 558 print(util.dump(config)) 559 559 os.exit(0) 560 560 end 561 561 562 562 local holler = print 563 563 local suffix = config.exe and '' or ('.'..config.outform) 564 564 local out = 'parsavd' .. suffix 565 -local linkargs = {} 565 +local linkargs = {'-O4'} 566 566 local target = config.tgttrip and terralib.newtarget { 567 567 Triple = config.tgttrip; 568 568 CPU = config.tgtcpu; 569 569 FloatABIHard = config.tgthf; 570 570 } or nil 571 571 572 572 if bflag('quiet','q') then holler = function() end end
Modified render/conf.t from [79b6da76d7] to [1b75d5dd6d].
35 35 body:free() 36 36 else [invoker] end 37 37 end 38 38 end 39 39 end 40 40 41 41 local terra 42 -render_conf([co], [path]) 42 +render_conf([co], [path], notify: pstr) 43 43 var menu: lib.str.acc menu:init(64):lpush('<hr>') defer menu:free() 44 44 45 45 -- build menu 46 46 do var p = co.who.rights.powers 47 47 if p.config() then menu:lpush '<a href="/conf/srv">server settings</a>' end 48 48 if p.rebrand() then menu:lpush '<a href="/conf/brand">instance branding</a>' end 49 49 if p.censor() then menu:lpush '<a href="/conf/censor">badthink alerts</a>' end ................................................................................ 58 58 var mptr = pstr { ptr = menu.buf, ct = menu.sz } 59 59 if menu.sz <= 4 then mptr.ct = 0 end -- 🙄 60 60 var pg = data.view.conf { 61 61 menu = mptr; 62 62 panel = panel; 63 63 } 64 64 65 - var pgt = pg:tostr() defer pgt:free() 65 + var pgt: pstr 66 + if notify:ref() then 67 + var fnpg: lib.str.acc 68 + fnpg:compose('<div class="flashmsg">', notify, '</div>') 69 + pg:append(&fnpg) 70 + pgt = fnpg:finalize() 71 + else pgt = pg:tostr() end 72 + defer pgt:free() 73 + 66 74 co:stdpage([lib.srv.convo.page] { 67 75 title = 'configure'; body = pgt; 68 76 class = lib.str.plit 'conf'; 69 77 cache = false; 70 78 }) 71 79 72 80 if panel.ct ~= 0 then panel:free() end 73 81 end 74 82 75 83 return render_conf
Modified render/profile.t from [03b39adc21] to [19457b4b7c].
3 3 local terra cs(s: rawstring) 4 4 return pstr { ptr = s, ct = lib.str.sz(s) } 5 5 end 6 6 7 7 local terra 8 8 render_profile(co: &lib.srv.convo, actor: &lib.store.actor) 9 9 var aux: lib.str.acc 10 - var auxp: pstr 11 10 if co.aid ~= 0 and co.who.id == actor.id then 12 - auxp = lib.str.plit '<a href="/conf/profile">alter</a>' 11 + aux:compose('<a href="/conf/profile?go=/',actor.xid,'">alter</a>') 13 12 elseif co.aid ~= 0 then 14 13 aux:compose('<a href="/', actor.xid, '/follow">follow</a><a href="/', 15 14 actor.xid, '/chat">chat</a>') 16 15 if co.who.rights.powers:affect_users() then 17 16 aux:lpush('<a href="/'):push(actor.xid,0):lpush('/ctl">control</a>') 18 17 end 19 - auxp = aux:finalize() 20 18 else 21 19 aux:compose('<a href="/', actor.xid, '/follow">remote follow</a>') 22 - auxp = aux:finalize() 23 20 end 21 + var auxp = aux:finalize() 24 22 var avistr: lib.str.acc if actor.origin == 0 then 25 23 avistr:compose('/avi/',actor.handle) 26 24 end 27 25 var timestr: int8[26] lib.osclock.ctime_r(&actor.knownsince, ×tr[0]) 28 26 29 27 var strfbuf: int8[28*4] 30 28 var stats = co.srv:actor_stats(actor.id) 31 29 var sn_posts = cs(lib.math.decstr_friendly(stats.posts, &strfbuf[ [strfbuf.type.N - 1] ])) 32 30 var sn_follows = cs(lib.math.decstr_friendly(stats.follows, sn_posts.ptr - 1)) 33 31 var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1)) 34 32 var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1)) 35 33 var bio = lib.str.plit "<em>tall, dark, and mysterious</em>" 36 34 if actor.bio ~= nil then 37 - bio = lib.html.sanitize(cs(actor.bio), false) 35 + bio = lib.smackdown.html(cs(actor.bio)) 38 36 end 39 37 var fullname = lib.render.nym(actor,0) defer fullname:free() 40 38 var profile = data.view.profile { 41 39 nym = fullname; 42 40 bio = bio; 43 41 xid = cs(actor.xid); 44 42 avatar = lib.trn(actor.origin == 0, pstr{ptr=avistr.buf,ct=avistr.sz}, ................................................................................ 50 48 timephrase = lib.trn(actor.origin == 0, lib.str.plit'joined', lib.str.plit'known since'); 51 49 52 50 auxbtn = auxp; 53 51 } 54 52 55 53 var ret = profile:tostr() 56 54 if actor.origin == 0 then avistr:free() end 57 - if not (co.aid ~= 0 and co.who.id == actor.id) then auxp:free() end 55 + auxp:free() 58 56 if actor.bio ~= nil then bio:free() end 59 57 return ret 60 58 end 61 59 62 60 return render_profile
Modified route.t from [5e16c3f22b] to [ae96c17fe6].
172 172 elseif path.ct == 1 then 173 173 lib.render.docpage(co, rstring.null()) 174 174 else 175 175 co:complain(404, 'no such documentation', 'invalid documentation URL') 176 176 end 177 177 end 178 178 179 -terra http.configure(co: &lib.srv.convo, path: hpath) 180 - lib.render.conf(co,path) 179 +terra http.configure(co: &lib.srv.convo, path: hpath, meth: method.t) 180 + var msg = pstring.null() 181 + if meth == method.post and path.ct >= 1 then 182 + var user_refresh = false var fail = false 183 + if path(1):cmp(lib.str.lit 'profile') then 184 + co.who.bio = co:postv('bio')._0 185 + co.who.nym = co:postv('nym')._0 186 + if co.who.bio ~= nil and @co.who.bio == 0 then co.who.bio = nil end 187 + if co.who.nym ~= nil and @co.who.nym == 0 then co.who.nym = nil end 188 + co.who.source:actor_save(co.who) 189 + msg = lib.str.plit 'profile changes saved' 190 + --user_refresh = true -- not really necessary here, actually 191 + elseif path(1):cmp(lib.str.lit 'srv') then 192 + elseif path(1):cmp(lib.str.lit 'users') then 193 + 194 + end 195 + 196 + if user_refresh then -- refresh the user info for the renderer 197 + var usr = co.srv:actor_fetch_uid(co.who.id) 198 + lib.mem.heapf(co.who) 199 + co.who = usr.ptr 200 + end 201 + var go,golen = co:getv('go') 202 + if not fail and go ~= nil then 203 + co:reroute(go) 204 + return 205 + end 206 + end 207 + lib.render.conf(co,path,msg) 181 208 end 182 209 183 210 do local branches = quote end 184 211 local filename, flen = symbol(&int8), symbol(intptr) 185 212 local page = symbol(lib.http.page) 186 213 local send = label() 187 214 local storage = data.stmap ................................................................................ 270 297 elseif path.ptr[0]:cmp(lib.str.lit('tl')) then 271 298 http.timeline(co, path) 272 299 elseif path.ptr[0]:cmp(lib.str.lit('doc')) then 273 300 if meth ~= method.get and meth ~= method.head then goto wrongmeth end 274 301 http.documentation(co, path) 275 302 elseif path.ptr[0]:cmp(lib.str.lit('conf')) then 276 303 if co.aid == 0 then goto unauth end 277 - http.configure(co,path) 304 + http.configure(co,path,meth) 278 305 else goto notfound end 279 306 return 280 307 end 281 308 282 309 ::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end 283 310 ::notfound:: co:complain(404, 'not found', 'no such resource available') do return end 284 311 ::unauth:: co:complain(401, 'unauthorized', 'this content is not available at your clearance level') do return end 285 312 end
Modified static/style.scss from [a08d589c48] to [2a06f65525].
557 557 .txtbox { 558 558 @extend %serif; 559 559 box-sizing: border-box; 560 560 padding: 0.08in 0.1in; 561 561 border: 1px solid black; 562 562 background: tone(-55%); 563 563 } 564 + textarea { resize: vertical; min-height: 2in; } 564 565 input, textarea, .txtbox { 565 566 display: block; 566 567 width: 100%; 567 568 } 568 569 button { float: right; width: 50%; } 569 570 } 570 571 } 572 + 573 +@keyframes flashup { 574 + 0% { opacity: 0; transform: scale(0.8); } 575 + 10% { opacity: 1; transform: scale(1.1); } 576 + 80% { opacity: 1; transform: scale(1); } 577 + 100% { opacity: 0; transform: scale(0.9) translateY(-0.12in); display: none; } 578 +} 579 +.flashmsg { 580 + display: block; 581 + position: fixed; 582 + top: 1.3in; 583 + max-width: 3in; 584 + padding: 0.5in 0.2in; 585 + left: 0; right: 0; 586 + text-align: center; 587 + text-shadow: 0 0 15px tone(10%); 588 + margin: auto; 589 + background: linear-gradient(to bottom, tone(-49%), tone(-43%,-0.1)); 590 + border: 1px solid tone(0%); 591 + border-radius: 3px; 592 + box-shadow: 0 0 50px tone(-55%); 593 + color: white; 594 + animation: ease forwards flashup; 595 + //cubic-bezier(0.4, 0.63, 0.6, 0.31) 596 + animation-duration: 3s; 597 +}
Modified store.t from [69369cc5c2] to [f53ab94a55].
53 53 54 54 struct m.source 55 55 56 56 struct m.rights { 57 57 rank: uint16 -- lower = more powerful except 0 = regular user 58 58 -- creating staff automatically assigns rank immediately below you 59 59 quota: uint32 -- # of allowed tweets per day; 0 = no limit 60 - invites: intptr -- # of people left this user can invite 60 + invites: uint32 -- # of people left this user can invite 61 61 62 62 powers: m.powerset 63 63 } 64 64 65 65 terra m.rights_default() 66 66 var pow: m.powerset pow:clear() 67 67 (pow.login << true) ................................................................................ 79 79 id: uint64 80 80 nym: str 81 81 handle: str 82 82 origin: uint64 83 83 bio: str 84 84 epithet: str 85 85 avatar: str 86 + avatarid: uint64 86 87 knownsince: m.timepoint 87 88 rights: m.rights 88 89 key: lib.mem.ptr(uint8) 89 90 90 91 -- ephemera 91 92 xid: str 92 93 source: &m.source ................................................................................ 247 248 -- not have the desired effect 248 249 249 250 conf_get: {&m.source, rawstring} -> lib.mem.ptr(int8) 250 251 conf_set: {&m.source, rawstring, rawstring} -> {} 251 252 conf_reset: {&m.source, rawstring} -> {} 252 253 253 254 actor_create: {&m.source, &m.actor} -> uint64 255 + actor_save: {&m.source, &m.actor} -> {} 254 256 actor_save_privs: {&m.source, &m.actor} -> {} 255 257 actor_fetch_xid: {&m.source, lib.mem.ptr(int8)} -> lib.mem.ptr(m.actor) 256 258 actor_fetch_uid: {&m.source, uint64} -> lib.mem.ptr(m.actor) 257 259 actor_notif_fetch_uid: {&m.source, uint64} -> lib.mem.ptr(m.notif) 258 260 actor_enum: {&m.source} -> lib.mem.ptr(&m.actor) 259 261 actor_enum_local: {&m.source} -> lib.mem.ptr(&m.actor) 260 262 actor_stats: {&m.source, uint64} -> m.actor_stats