Overview
| Comment: | begin work on circles |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
a4b4af5ca4157d4716100e593c53b642 |
| User & Date: | lexi on 2021-01-13 15:01:13 |
| Other Links: | manifest | tags |
Context
|
2021-01-14
| ||
| 01:11 | more work on UI and circles check-in: 03ea3dffe7 user: lexi tags: trunk | |
|
2021-01-13
| ||
| 15:01 | begin work on circles check-in: a4b4af5ca4 user: lexi tags: trunk | |
| 13:57 | implement some sanctions check-in: 60040f3ca3 user: lexi tags: trunk | |
Changes
Modified backend/pgsql.t from [bd352a7166] to [96ec125a09].
282 282 283 283 actor_notice_enum = { 284 284 params = {uint64}, sql = [[ 285 285 select (notice).* from pg_temp.parsavpg_notices 286 286 where rcpt = $1::bigint 287 287 ]]; 288 288 }; 289 + 290 + circle_search = { 291 + params = {uint64,uint64}, sql = [[ 292 + select name, id, owner, array_length(members,1) from parsav_circles where 293 + ($1::bigint = 0 or $1::bigint = owner) and 294 + ($2::bigint = 0 or $2::bigint = id) 295 + ]]; 296 + }; 297 + 298 + circle_members_fetch_cid = { 299 + params = {uint64, uint64}, sql = [[ 300 + select unnest(members) from parsav_circles where 301 + ($1::bigint = 0 or owner = $1::bigint) and 302 + id = $2::bigint 303 + ]]; 304 + }; 305 + 306 + circle_members_fetch_name = { 307 + params = {uint64, pstring}, sql = [[ 308 + select unnest(members) from parsav_circles where 309 + ($1::bigint = 0 or owner = $1::bigint) and 310 + name = $2::text 311 + ]]; 312 + }; 289 313 290 314 auth_sigtime_user_fetch = { 291 315 params = {uint64}, sql = [[ 292 316 select authtime::bigint 293 317 from parsav_actors where id = $1::bigint 294 318 ]]; 295 319 }; ................................................................................ 2035 2059 end 2036 2060 return 0, false 2037 2061 end]; 2038 2062 actor_conf_int_set = [terra(src: &lib.store.source, uid: uint64, key: rawstring, value: uint64): {} 2039 2063 queries.actor_conf_int_set.exec(src,uid,key,value) end]; 2040 2064 actor_conf_int_reset = [terra(src: &lib.store.source, uid: uint64, key: rawstring): {} 2041 2065 queries.actor_conf_int_reset.exec(src,uid,key) end]; 2066 + 2067 + circle_search = [terra( 2068 + src: &lib.store.source, 2069 + pool:&lib.mem.pool, 2070 + uid: uint64, 2071 + cid: uint64 2072 + ): lib.mem.ptr(lib.store.circle) 2073 + var res = queries.circle_search.exec(src, uid, cid) 2074 + if res.sz == 0 then return [lib.mem.ptr(lib.store.circle)].null() end 2075 + defer res:free() 2076 + 2077 + var rt = pool:alloc(lib.store.circle, res.sz) 2078 + for i = 0, res.sz do 2079 + var name = res:_string(i,0) 2080 + rt(i) = lib.store.circle { 2081 + name = name:pdup(pool); 2082 + cid = res:int(uint64,i,1); 2083 + owner = res:int(uint64,i,2); 2084 + memcount = res:int(uint64,i,3); 2085 + } 2086 + end 2087 + 2088 + return rt 2089 + end]; 2090 + 2091 + circle_members_fetch_cid = [terra( 2092 + src: &lib.store.source, 2093 + pool:&lib.mem.pool, 2094 + uid: uint64, 2095 + cid: uint64 2096 + ): lib.mem.ptr(uint64) 2097 + var res = queries.circle_members_fetch_cid.exec(src,uid,cid) 2098 + if res.sz == 0 then return [lib.mem.ptr(uint64)].null() end 2099 + defer res:free() 2100 + 2101 + var rt = pool:alloc(uint64, res.sz) 2102 + for i = 0, res.sz do rt(i) = res:int(uint64,i,0) end 2103 + 2104 + return rt 2105 + end]; 2042 2106 2043 2107 actor_auth_register_uid = nil; -- TODO better support non-view based auth 2044 2108 } 2045 2109 2046 2110 return b
Modified mem.t from [05a21ff4d9] to [a251bec86e].
105 105 self.ptr = self.ptr + n 106 106 self.ct = self.ct - n 107 107 return self.ptr 108 108 end 109 109 terra t.methods.null(): t return t { ptr = nil, ct = 0 } end -- maybe should be a macro? 110 110 terra t:ref() return self.ptr ~= nil end 111 111 t.metamethods.__not = macro(function(self) return `not self:ref() end) 112 - t.metamethods.__apply = macro(function(self,idx) return `self.ptr[idx] end) 112 + t.metamethods.__apply = macro(function(self,idx) return `self.ptr[ [idx or 0] ] end) 113 + t.metamethods.__update = macro(function(self,idx,rhs) 114 + return quote self.ptr[idx] = rhs end end) 115 + 113 116 if not ty:isstruct() then 114 117 terra t:cmp_raw(other: &ty) 115 118 for i=0, self.ct do 116 119 if self.ptr[i] ~= other[i] then return false end 117 120 end 118 121 return true 119 122 end
Modified render/timeline.t from [dac341c838] to [900216dd8b].
5 5 requires_login(m: modes.t): bool 6 6 return m == modes.follow 7 7 or m == modes.mutual 8 8 or m == modes.circle 9 9 end 10 10 11 11 local terra 12 -render_timeline(co: &lib.srv.convo, modestr: lib.mem.ref(int8)) 12 +render_timeline(co: &lib.srv.convo, hpath: lib.mem.ptr(lib.mem.ref(int8))) 13 + var modestr = lib.str.ref.null() 14 + var spec = lib.str.ref.null() 15 + if hpath.ct >= 2 then 16 + modestr = hpath(1) 17 + if hpath.ct >= 3 then spec = hpath(2) end 18 + end 13 19 var mode = modes.follow 14 20 var circle: uint64 = 0 15 - if modestr:cmp('local') then mode = [modes['local']] 16 - elseif modestr:cmp('mutual') then mode = modes.mutual 17 - elseif modestr:cmp('fedi') then mode = modes.fedi 18 - elseif modestr:cmp('circle') then mode = modes.circle 21 + if modestr:ref() then 22 + if modestr:cmp('local' ) then mode = [modes['local']] 23 + elseif modestr:cmp('mutual') then mode = modes.mutual 24 + elseif modestr:cmp('fedi' ) then mode = modes.fedi 25 + elseif modestr:cmp('circle') then mode = modes.circle 26 + end 19 27 end 20 28 if requires_login(mode) and co.aid == 0 then mode = [modes['local']] end 21 29 22 30 23 31 var stoptime = lib.osclock.time(nil) 24 32 25 33 var posts = [lib.mem.vec(lib.mem.ptr(lib.store.post))] { ................................................................................ 41 49 var acc = co:stra(1024) 42 50 var modelabels = arrayof(pstr, 'followed', 'mutuals', 'local instance', 'fediverse', 'circle') 43 51 var modelinks = arrayof(pstr, [modes.members]) 44 52 acc:lpush('<div style="text-align: right"><em>showing ') 45 53 for i=0, [modelabels.type.N] do 46 54 if co.aid ~= 0 or not requires_login(i) then 47 55 if i > 0 then acc:lpush(' ยท ') end 48 - if i == mode then 56 + if i == mode and not (mode == modes.circle and spec:ref()) then 49 57 acc:lpush('<strong>'):ppush(modelabels[i]):lpush('</strong>') 50 58 else 51 59 acc:lpush('<a href="/tl/'):ppush(modelinks[i]):lpush('">'):ppush(modelabels[i]):lpush('</a>') 52 60 end 53 61 end 54 62 end 55 63 acc:lpush('</em></div>') 56 - acc:lpush('<div id="tl" data-live="10">') 57 64 var newest: lib.store.timepoint = 0 58 - for i = 0, posts.sz do 59 - var author = co:uid2actor(posts(i).ptr.author) 60 - if mode == modes.mutual and posts(i).ptr.author ~= co.who.id then 61 - if not author.relationship.recip.follow() then goto skip end 65 + if mode == modes.circle and not spec then 66 + var circles = co.srv:circle_search(&co.srv.pool, co.who.id, 0) 67 + acc:lpush '<menu class="circles">' 68 + for i:intptr = 0, circles.ct do 69 + acc:lpush '<li><a href="/tl/circle/' 70 + :shpush(circles(i).cid) 71 + :lpush '">' 72 + :ppush(circles(i).name) 73 + :lpush '</a></li>' 74 + end 75 + -- TODO list circles 76 + acc:lpush '</menu>' 77 + else 78 + acc:lpush('<div id="tl" data-live="10">') 79 + for i = 0, posts.sz do 80 + var author = co:uid2actor(posts(i).ptr.author) 81 + if mode == modes.mutual and posts(i).ptr.author ~= co.who.id then 82 + if not author.relationship.recip.follow() then goto skip end 83 + end 84 + if author.relationship.rel.mute() or 85 + author.relationship.rel.avoid() or 86 + author.relationship.recip.exclude() then goto skip end 87 + lib.render.tweet(co, posts(i).ptr, &acc) 88 + var t = lib.math.biggest(lib.math.biggest(posts(i).ptr.posted, posts(i).ptr.discovered),posts(i).ptr.edited) 89 + if t > newest then newest = t end 90 + ::skip:: posts(i):free() 62 91 end 63 - if author.relationship.rel.mute() or 64 - author.relationship.rel.avoid() or 65 - author.relationship.recip.exclude() then goto skip end 66 - lib.render.tweet(co, posts(i).ptr, &acc) 67 - var t = lib.math.biggest(lib.math.biggest(posts(i).ptr.posted, posts(i).ptr.discovered),posts(i).ptr.edited) 68 - if t > newest then newest = t end 69 - ::skip:: posts(i):free() 92 + if posts.run > 0 then posts:free() end 93 + acc:lpush('</div>') 70 94 end 71 - if posts.run > 0 then posts:free() end 72 - acc:lpush('</div>') 73 95 74 96 var doc = [lib.srv.convo.page] { 75 97 title = 'timeline'; 76 98 body = acc:finalize(); 77 99 class = 'timeline'; 78 100 cache = false; 79 101 } 80 - co:livepage(doc,newest) 102 + if newest ~= 0 103 + then co:livepage(doc,newest) 104 + else co:stdpage(doc) 105 + end 81 106 --doc.body:free() 82 107 end 83 108 return render_timeline
Modified route.t from [cc19a11396] to [bb5bfba2ee].
218 218 var idlen = lib.math.shorthand.gen(newid, idbuf) 219 219 var redirto: lib.str.acc redirto:compose('/post/',{idbuf,idlen}) defer redirto:free() 220 220 co:reroute(redirto.buf) 221 221 end 222 222 end 223 223 224 224 terra http.timeline(co: &lib.srv.convo, mode: hpath) 225 - lib.render.timeline(co,lib.trn(mode.ptr == nil, rstring{ptr=nil}, mode.ptr[1])) 225 + lib.render.timeline(co,mode) 226 226 end 227 227 228 228 terra http.documentation(co: &lib.srv.convo, path: hpath) 229 229 if path.ct == 2 then 230 230 lib.render.docpage(co,path(1)) 231 231 elseif path.ct == 1 then 232 232 lib.render.docpage(co, rstring.null())
Modified store.t from [303dfd42c8] to [8e00371af1].
236 236 rtdby: uint64 -- 0 if not rt 237 237 rtact: uint64 -- 0 if not rt, id of rt action otherwise 238 238 isreply: bool 239 239 source: &m.source 240 240 241 241 -- save :: bool -> {} (defined in acl.t due to dep. hell) 242 242 } 243 + 244 +struct m.circle { 245 + cid: uint64 246 + owner: uint64 247 + name: lib.str.t 248 +-- ephemera 249 + memcount: intptr 250 +} 243 251 244 252 struct m.artifact { 245 253 rid: uint64 246 254 owner: uint64 247 255 desc: str 248 256 folder: str 249 257 mime: str ................................................................................ 461 469 -- undo: bool 462 470 post_react: {&m.source, uint64, uint64, pstring} -> {} 463 471 -- emoji: pstring (null to delete previous reaction, otherwise adds/changes) 464 472 post_act_cancel: {&m.source, uint64} -> {} 465 473 post_liked_uid: {&m.source, uint64, uint64} -> bool 466 474 post_reacted_uid: {&m.source, uint64, uint64} -> bool 467 475 post_act_fetch_notice: {&m.source, uint64} -> m.notice 476 + 477 + circle_search: {&m.source, &lib.mem.pool, uint64, uint64} -> lib.mem.ptr(m.circle) 478 + circle_create: {&m.source, uint64, pstring} -> {} 479 + circle_destroy: {&m.source, uint64, uint64} -> {} 480 + circle_members_fetch_cid: {&m.source, &lib.mem.pool, uint64, uint64} -> lib.mem.ptr(uint64) 481 + circle_members_fetch_name: {&m.source, &lib.mem.pool, uint64, pstring} -> lib.mem.ptr(uint64) 482 + circle_members_add_uid: {&m.source, uint64, uint64} -> {} 483 + circle_members_del_uid: {&m.source, uint64, uint64} -> {} 468 484 469 485 thread_latest_arrival_calc: {&m.source, uint64} -> m.timepoint 470 486 471 487 artifact_instantiate: {&m.source, lib.mem.ptr(uint8), lib.mem.ptr(int8)} -> uint64 472 488 -- instantiate an artifact in the database, either installing a new 473 489 -- artifact or returning the id of an existing artifact with the same hash 474 490 -- artifact: bytea
Modified str.t from [ee5af81e76] to [0c9ba1d780].
28 28 (@str == @' ' or @str == @'\t' or @str == @'\n') do 29 29 str = str + 1 30 30 maxlen = maxlen - 1 31 31 end 32 32 return str 33 33 end 34 34 35 - 36 35 do local strptr = (lib.mem.ptr(int8)) 37 36 local strref = (lib.mem.ref(int8)) 38 37 local byteptr = (lib.mem.ptr(uint8)) 39 38 local function install_funcs(ty) 40 39 ty.metamethods.__cast = function(from,to,e) 41 40 local v = e:asvalue() 42 41 if type(v) == 'string' then 43 42 return `ty {ptr = v, ct = [#v]} 44 43 elseif from == &int8 then 45 44 return `ty {ptr = e, ct = m.sz(e)} 46 45 elseif to == &int8 then 47 46 return e.ptr 48 47 end 48 + end 49 + terra ty:pdup(p: &lib.mem.pool): strptr 50 + if not @self then return strptr.null() end 51 + if self.ct == 0 then self.ct = m.sz(self.ptr) end 52 + var newstr = p:alloc(int8, self.ct) 53 + lib.mem.cpy(newstr.ptr, self.ptr, self.ct) 54 + return newstr 49 55 end 50 56 terra ty:cmp(other: ty) 51 57 if self.ptr == nil and other.ptr == nil then return true end 52 58 if self.ptr == nil or other.ptr == nil then return false end 53 59 54 60 var sz = lib.math.biggest(self.ct, other.ct) 55 61 for i = 0, sz do