| Comment: | add follow notices |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
00a6815988cf730166006380c81ff264 |
| User & Date: | lexi on 2021-01-10 11:17:29 |
| Other Links: | manifest | tags |
|
2021-01-10
| ||
| 14:26 | get some user admin shit working, general cleanups check-in: e1ff4f301e user: lexi tags: trunk | |
| 11:17 | add follow notices check-in: 00a6815988 user: lexi tags: trunk | |
| 08:19 | begin replacing inefficient memory management with a pool-based solution; fix memory leaks check-in: 7c8769bf96 user: lexi tags: trunk | |
Modified backend/pgsql.t from [794844a9c8] to [b388ba7244].
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
....
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
|
delete from parsav_rights where
actor = $1::bigint and
key = $2::text
]]
};
actor_rel_create = {
params = {uint16,uint64, uint64}, cmd = true, sql = [[
insert into parsav_rels (kind,relator,relatee)
values($1::smallint, $2::bigint, $3::bigint)
on conflict do nothing
]];
};
actor_rel_destroy = {
params = {uint16,uint64, uint64}, cmd = true, sql = [[
delete from parsav_rels where
................................................................................
end];
actor_rel_create = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
relatee: uint64
): {} queries.actor_rel_create.exec(src,kind,relator,relatee) end];
actor_rel_destroy = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
relatee: uint64
): {} queries.actor_rel_destroy.exec(src,kind,relator,relatee) end];
|
|
|
|
|
|
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
....
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
|
delete from parsav_rights where
actor = $1::bigint and
key = $2::text
]]
};
actor_rel_create = {
params = {uint16,uint64, uint64, int64}, cmd = true, sql = [[
insert into parsav_rels (kind,relator,relatee,since)
values($1::smallint, $2::bigint, $3::bigint, $4::bigint)
on conflict do nothing
]];
};
actor_rel_destroy = {
params = {uint16,uint64, uint64}, cmd = true, sql = [[
delete from parsav_rels where
................................................................................
end];
actor_rel_create = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
relatee: uint64
): {} queries.actor_rel_create.exec(src,kind,relator,relatee,lib.osclock.time(nil)) end];
actor_rel_destroy = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
relatee: uint64
): {} queries.actor_rel_destroy.exec(src,kind,relator,relatee) end];
|
Modified backend/schema/pgsql-views.sql from [c997d2f5ad] to [0fea8fa8b6].
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
...
208
209
210
211
212
213
214
215
216
217
218
219
|
($1).time,
($1).actor,
($1).subject,
null::bigint,
($1).body
)::pg_temp.parsavpg_intern_notice as notice
from (values
('rt', <notice:rt> ),
('like', <notice:like> ),
('react', <notice:react>)
) as kmap(kstr,kind) where kmap.kstr = ($1).kind
$$ language sql;
create type pg_temp.parsavpg_intern_actor as (
id bigint,
nym text,
handle text,
................................................................................
null::text
)::pg_temp.parsavpg_intern_notice as notice,
par.author as rcpt
from parsav_posts as p
inner join parsav_posts as par on p.parent = par.id
left join ntimes as nt on nt.uid = p.author
where p.discovered >= coalesce(nt.when,0)
), allnotices as (select * from acts union select * from replies)
table allnotices order by (notice).when desc
);
|
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
($1).time,
($1).actor,
($1).subject,
null::bigint,
($1).body
)::pg_temp.parsavpg_intern_notice as notice
from (values
('rt', <notice:rt> ),
('like', <notice:like> ),
('react', <notice:react> ),
('follow',<notice:follow>)
) as kmap(kstr,kind) where kmap.kstr = ($1).kind
$$ language sql;
create type pg_temp.parsavpg_intern_actor as (
id bigint,
nym text,
handle text,
................................................................................
null::text
)::pg_temp.parsavpg_intern_notice as notice,
par.author as rcpt
from parsav_posts as p
inner join parsav_posts as par on p.parent = par.id
left join ntimes as nt on nt.uid = p.author
where p.discovered >= coalesce(nt.when,0)
), follows as (
select row(
<notice:follow>::smallint,
r.since,
r.relator,
r.relatee,
null::bigint,
null::text
)::pg_temp.parsavpg_intern_notice as notice,
r.relatee as rcpt
from parsav_rels as r
left join ntimes as nt on nt.uid = r.relatee
where
r.since >= coalesce(nt.when,0) and
r.kind = <rel:follow>
), allnotices as (table acts union table replies union table follows)
table allnotices order by (notice).when desc
);
|
Modified backend/schema/pgsql.sql from [bc736c4c1d] to [daac991db5].
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
create index on parsav_posts (parent); create table parsav_rels ( relator bigint references parsav_actors(id) on delete cascade, -- e.g. follower relatee bigint references parsav_actors(id) on delete cascade, -- e.g. followed kind smallint, -- e.g. follow, block, mute primary key (relator, relatee, kind) ); comment on table parsav_rels is 'all relationships, positive and negative, between local users and other users; kind is a version-specific integer mapping to a type-of-relationship enum in store.t'; create table parsav_acts ( |
| > |
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
create index on parsav_posts (parent); create table parsav_rels ( relator bigint references parsav_actors(id) on delete cascade, -- e.g. follower relatee bigint references parsav_actors(id) on delete cascade, -- e.g. followed kind smallint not null, -- e.g. follow, block, mute since bigint not null, primary key (relator, relatee, kind) ); comment on table parsav_rels is 'all relationships, positive and negative, between local users and other users; kind is a version-specific integer mapping to a type-of-relationship enum in store.t'; create table parsav_acts ( |
Modified config.lua from [6cff716428] to [a1f76576fd].
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
{'heart.webp', 'image/webp'};
{'retweet.webp', 'image/webp'};
{'padlock.svg', 'image/svg+xml'};
{'warn.svg', 'image/svg+xml'};
{'query.webp', 'image/webp'};
{'reply.webp', 'image/webp'};
{'file.webp', 'image/webp'};
-- keep in mind before you add anything to this list: these are not
-- just files parsav can access, they are files that are *kept in
-- memory* for fast access the entire time parsav is running, and
-- which need to be loaded into memory before the program can even
-- start. it's imperative to keep these as small and few in number
-- as is realistically possible.
};
|
> |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
{'heart.webp', 'image/webp'};
{'retweet.webp', 'image/webp'};
{'padlock.svg', 'image/svg+xml'};
{'warn.svg', 'image/svg+xml'};
{'query.webp', 'image/webp'};
{'reply.webp', 'image/webp'};
{'file.webp', 'image/webp'};
{'follow.webp', 'image/webp'};
-- keep in mind before you add anything to this list: these are not
-- just files parsav can access, they are files that are *kept in
-- memory* for fast access the entire time parsav is running, and
-- which need to be loaded into memory before the program can even
-- start. it's imperative to keep these as small and few in number
-- as is realistically possible.
};
|
Modified http.t from [4c9f723184] to [5f40c98144].
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
end
m.codestr = terra(code: uint16)
var [resptext] var [resplen]
switch code do [respbranches] end
return resptext, resplen
end
terra m.hier(uri: lib.mem.ptr(int8)): lib.mem.ptr(lib.mem.ref(int8))
if uri.ct == 0 then return [lib.mem.ptr(lib.mem.ref(int8))] { ptr = nil, ct = 0 } end
var sz = 1
var start = 0 if uri.ptr[0] == @'/' then start = 1 end
for i = start, uri.ct do if uri.ptr[i] == @'/' then sz = sz + 1 end end
var lst = lib.mem.heapa([lib.mem.ref(int8)], sz)
if sz == 0 then
lst.ptr[0].ptr = uri.ptr
lst.ptr[0].ct = uri.ct
return lst
end
var idx: intptr = 0
|
| | |
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
end m.codestr = terra(code: uint16) var [resptext] var [resplen] switch code do [respbranches] end return resptext, resplen end terra m.hier(pool: &lib.mem.pool, uri: lib.mem.ptr(int8)): lib.mem.ptr(lib.mem.ref(int8)) if uri.ct == 0 then return [lib.mem.ptr(lib.mem.ref(int8))] { ptr = nil, ct = 0 } end var sz = 1 var start = 0 if uri.ptr[0] == @'/' then start = 1 end for i = start, uri.ct do if uri.ptr[i] == @'/' then sz = sz + 1 end end var lst = pool:alloc([lib.mem.ref(int8)], sz) if sz == 0 then lst.ptr[0].ptr = uri.ptr lst.ptr[0].ct = uri.ct return lst end var idx: intptr = 0 |
Modified makefile from [8559ac7b2c] to [d43e9d6c44].
1 2 3 4 5 6 7 8 9 10 11 |
dl = git dbg-flags = $(if $(dbg),-g) images = static/default-avatar.webp static/query.webp static/heart.webp static/retweet.webp static/reply.webp static/file.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) env parsav_link=no terra $(dbg-flags) $< |
| |
1 2 3 4 5 6 7 8 9 10 11 |
dl = git
dbg-flags = $(if $(dbg),-g)
images = static/default-avatar.webp static/query.webp static/heart.webp static/retweet.webp static/reply.webp static/file.webp static/follow.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)
env parsav_link=no terra $(dbg-flags) $<
|
Modified mem.t from [7e2b478eaf] to [05a21ff4d9].
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
self.sz = sz
self.debris = [&m.pool](b)
self.debris.storage = nil
return self
end
terra m.pool:free(): {}
lib.io.fmt('DRAINING POOL %p\n',self.storage)
if self.storage == nil then return end
if self.debris.storage ~= nil then self.debris:free() end
m.heapf(self.debris) -- storage + debris field allocated in one block
self.storage = nil
self.cursor = nil
self.sz = 0
self.debris = nil
................................................................................
terra m.pool:clear()
if self.debris.storage ~= nil then self.debris:free() end
self.cursor = self.storage
return self
end
terra m.pool:alloc_bytes(sz: intptr): &opaque
var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
lib.io.fmt('%p / %p @ allocating %llu bytes in %llu of space\n',self.storage,self.cursor,sz,space)
if space < sz then
lib.dbg('reserving more space')
self:cue(space + sz + 256) end
var ptr = self.cursor
self.cursor = [&opaque]([&uint8](self.cursor) + sz)
return ptr
end
terra m.pool:realloc_bytes(oldptr: &opaque, oldsz: intptr, newsz: intptr): &opaque
var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
var cur = [&uint8](self.cursor)
if cur - [&uint8](oldptr) == oldsz and newsz - oldsz < space then
lib.dbg('moving pool cursor')
cur = cur + (newsz - oldsz)
self.cursor = [&opaque](cur)
return oldptr
else
|
<
|
<
<
|
|
|
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
self.sz = sz
self.debris = [&m.pool](b)
self.debris.storage = nil
return self
end
terra m.pool:free(): {}
if self.storage == nil then return end
if self.debris.storage ~= nil then self.debris:free() end
m.heapf(self.debris) -- storage + debris field allocated in one block
self.storage = nil
self.cursor = nil
self.sz = 0
self.debris = nil
................................................................................
terra m.pool:clear()
if self.debris.storage ~= nil then self.debris:free() end
self.cursor = self.storage
return self
end
terra m.pool:alloc_bytes(sz: intptr): &opaque
var space: intptr = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
if space < sz then
self:cue(self.sz + sz + 256) end
var ptr = self.cursor
self.cursor = [&opaque]([&uint8](self.cursor) + sz)
return ptr
end
terra m.pool:realloc_bytes(oldptr: &opaque, oldsz: intptr, newsz: intptr): &opaque
var space: intptr = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
var cur = [&uint8](self.cursor)
if cur - [&uint8](oldptr) == oldsz and newsz - oldsz < space then
lib.dbg('moving pool cursor')
cur = cur + (newsz - oldsz)
self.cursor = [&opaque](cur)
return oldptr
else
|
Modified parsav.md from [1e18c01a8c] to [af14d66fc5].
135 136 137 138 139 140 141 142 |
* ldap for auth (and maybe actors?) * cdb (for static content, maybe? does this make sense?) * mariadb/mysql * the various nosql horrors, e.g. redis, mongo, and so on parsav urgently needs an internationalization framework as well. right now everything is just hardcoded in english. yuck. parsav could be significantly improved by adjusting its memory management strategy. instead of allocating everything with lib.mem.heapa (which currently maps to malloc on all platforms), we should allocate a static buffer for the server overlord object which can simply be cleared and re-used for each http request, and enlarged with `realloc` when necessary. the entire region could be `mlock`ed for better performance, and it would no longer be necessary to track and free memory, as the entire buffer would simply be discarded after use (similar to PHP's original memory management strategy). this would remove possibly the largest source of latency in the codebase, as `parsav` is regrettably quite heavy on malloc, performing numerous allocations for each page rendered. |
| |
135 136 137 138 139 140 141 142 |
* ldap for auth (and maybe actors?)
* cdb (for static content, maybe? does this make sense?)
* mariadb/mysql
* the various nosql horrors, e.g. redis, mongo, and so on
parsav urgently needs an internationalization framework as well. right now everything is just hardcoded in english. yuck.
parsav could be significantly improved by adjusting its memory management strategy. instead of allocating everything with lib.mem.heapa (which currently maps to malloc on all platforms), we should allocate a static buffer for the server overlord object which can simply be cleared and re-used for each http request, and enlarged with `realloc` when necessary. the entire region could be `mlock`ed for better performance, and it would no longer be necessary to track and free memory, as the entire buffer would simply be discarded after use (similar to PHP's original memory management strategy). this would remove possibly the largest source of latency in the codebase, as `parsav` is regrettably quite heavy on malloc, performing numerous allocations for each page rendered. **update:** this is now in progress
|
Modified render/notices.t from [745afb2f25] to [1e81acf0af].
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
else pflink:lpush('/@') end
pflink:push(who(0).xid,0)
var n = data.view.notice {
avatar = cs(who(0).avatar);
nym = lib.render.nym(who.ptr,0,nil,true);
pflink = pstr{ptr = pflink.buf; ct = pflink.sz};
}
var notweet = true
var what = co.srv:post_fetch(notes(i).what) defer what:free()
switch notes(i).kind do
case lib.store.noticetype.rt then
n.kind = P'rt'
n.act = P'retweeted your post'
end
case lib.store.noticetype.like then
n.kind = P'like'
n.act = P'likes your post'
end
case lib.store.noticetype.reply then
n.kind = P'reply'
n.act = P'replied to your post'
notweet = false
end
else goto skip end
do var idbuf: int8[lib.math.shorthand.maxlen]
var idlen = lib.math.shorthand.gen(notes(i).what, idbuf)
var b = lib.smackdown.html(&co.srv.pool, pstr {ptr=what(0).body,ct=0},true) --defer b:free()
body:lpush(' <a class="quote" href="/post/'):push(&idbuf[0],idlen):lpush('">'):ppush(b):lpush('</a>')
end
if not notweet then
var reply = co.srv:post_fetch(notes(i).reply)
lib.render.tweet(co,reply.ptr,&body)
reply:free()
end
n.ref = pstr {ptr = body.buf, ct = body.sz}
n:append(&pg)
::skip:: n.nym:free()
pflink:reset()
body:reset()
end
--pflink:free()
pg:lpush('<form method="post"><button name="act" value="clear">clear all notices</button></form>')
co:livepage([lib.srv.convo.page] {
|
| < > > > > > < < > > | < > |
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
else pflink:lpush('/@') end
pflink:push(who(0).xid,0)
var n = data.view.notice {
avatar = cs(who(0).avatar);
nym = lib.render.nym(who.ptr,0,nil,true);
pflink = pstr{ptr = pflink.buf; ct = pflink.sz};
}
var notweet, nopost = true, false
switch notes(i).kind do
case lib.store.noticetype.rt then
n.kind = P'rt'
n.act = P'retweeted your post'
end
case lib.store.noticetype.like then
n.kind = P'like'
n.act = P'likes your post'
end
case lib.store.noticetype.reply then
n.kind = P'reply'
n.act = P'replied to your post'
notweet = false
end
case lib.store.noticetype.follow then
n.kind = P'follow'
n.act = P'followed you!'
nopost = true
end
else goto skip end
if not nopost then
var what = co.srv:post_fetch(notes(i).what) defer what:free()
var b = lib.smackdown.html(&co.srv.pool, pstr {ptr=what(0).body,ct=0},true) --defer b:free()
body:lpush(' <a class="quote" href="/post/'):shpush(notes(i).what):lpush('">'):ppush(b):lpush('</a>')
end
if not notweet then
var reply = co.srv:post_fetch(notes(i).reply)
lib.render.tweet(co,reply.ptr,&body)
reply:free()
end
n.ref = pstr {ptr = body.buf, ct = body.sz}
n:append(&pg)
::skip:: n.nym:free()
pflink:reset()
body:reset()
end
--pflink:free()
pg:lpush('<form method="post"><button name="act" value="clear">clear all notices</button></form>')
co:livepage([lib.srv.convo.page] {
|
Modified render/profile.t from [a033243372] to [cdb26ba3d8].
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
end
-- this is really more what epithets are for, i think
if actor.rights.rank > 0 and stafftxt:ref() then
comments:lpush('<li>'):ppush(stafftxt):lpush('</li>')
end
if co.who:outranks(actor) then
comments:lpush('<li style="--co:50">underling</li>')
elseif actor:outranks(co.who) then
comments:lpush('<li style="--co:-50">outranks you</li>')
end
if relationship.recip.follow() then
comments:lpush('<li style="--co:30">follows you</li>')
end
end
|
> | | | | > |
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
end
-- this is really more what epithets are for, i think
if actor.rights.rank > 0 and stafftxt:ref() then
comments:lpush('<li>'):ppush(stafftxt):lpush('</li>')
end
if co.who.rights.rank ~= 0 then
if co.who:outranks(actor) then
comments:lpush('<li style="--co:50">underling</li>')
elseif actor:outranks(co.who) then
comments:lpush('<li style="--co:-50">outranks you</li>')
end
end
if relationship.recip.follow() then
comments:lpush('<li style="--co:30">follows you</li>')
end
end
|
Modified route.t from [a232000d86] to [47b3eeec8d].
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 .. 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ... 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 ... 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 |
terra http.actor_profile(co: &lib.srv.convo, actor: &lib.store.actor, meth: method.t)
var rel: lib.store.relationship
if co.aid ~= 0 then
rel = co.srv:actor_rel_calc(co.who.id, actor.id)
if meth == method.post then
var act = co:ppostv('act')
if act:cmp(lib.str.plit 'follow') and not rel.rel.follow() then
if rel.recip.block() then
co:complain(403,'blocked','you cannot follow a user you are blocked by') return
end
(rel.rel.follow << true)
co.srv:actor_rel_create([lib.store.relation.idvmap.follow], co.who.id, actor.id)
elseif act:cmp(lib.str.plit 'unfollow') and rel.rel.follow() then
(rel.rel.follow << false)
co.srv:actor_rel_destroy([lib.store.relation.idvmap.follow], co.who.id, actor.id)
end
end
else
rel.rel:clear()
rel.recip:clear()
end
................................................................................
if handle.ct == 0 then
handle.ct = uri.ct - 2
uri:advance(uri.ct)
elseif handle.ct + 2 < uri.ct then uri:advance(handle.ct + 2) end
lib.dbg('looking up user by xid "', {handle.ptr,handle.ct} ,'", path: ', {uri.ptr,uri.ct})
var path = lib.http.hier(uri) defer path:free()
for i=0,path.ct do
lib.dbg('got path component ', {path.ptr[i].ptr, path.ptr[i].ct})
end
var actor = co.srv:actor_fetch_xid(handle)
if actor.ptr == nil then
co:complain(404,'no such user','no such user known to this server')
................................................................................
credsec_for_uid(co: &lib.srv.convo, uid: uint64)
var act = co:ppostv('act')
lib.dbg('showing credentials')
if act:cmp(lib.str.plit 'invalidate') then
lib.dbg('setting user\'s cookie validation time to now')
co.who.source:auth_sigtime_user_alter(uid, lib.osclock.time(nil))
-- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again
co:installkey('/conf/sec',co.aid)
return
elseif act:cmp(lib.str.plit 'newcred') then
var cmt = co:ppostv('comment')
var pw = co:ppostv('newpw')
var aid: uint64 = 0
if pw:ref() then
var cpw = co:ppostv('rptpw')
................................................................................
end
elseif uri:cmp(lib.str.plit '/logout') then
if co.aid == 0
then goto notfound
else co:reroute_cookie('/','auth=; Path=/')
end
else -- hierarchical routes
var path = lib.http.hier(uri) defer path:free()
if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
http.actor_profile_uid(co, path, meth)
elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
http.tweet_page(co, path, meth)
elseif path(0):cmp(lib.str.lit('tl')) then
http.timeline(co, path)
elseif path(0):cmp(lib.str.lit('media')) then
|
< | > > > > > > > > > > > > | | | | | > > > > > | | | |
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 .. 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 ... 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 ... 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
terra http.actor_profile(co: &lib.srv.convo, actor: &lib.store.actor, meth: method.t)
var rel: lib.store.relationship
if co.aid ~= 0 then
rel = co.srv:actor_rel_calc(co.who.id, actor.id)
if meth == method.post then
var act = co:ppostv('act')
if rel.recip.block() then
if act:cmp(lib.str.plit 'follow') or act:cmp(lib.str.plit 'subscribe') then
co:complain(403,'blocked','you cannot follow a user you are blocked by') return
end
end
if act:cmp(lib.str.plit 'block') and not rel.rel.block() then
(rel.rel.block << true) ; (rel.recip.follow << false)
co.srv:actor_rel_create([lib.store.relation.idvmap.block], co.who.id, actor.id)
co.srv:actor_rel_destroy([lib.store.relation.idvmap.follow], actor.id, co.who.id)
else
[(function()
local tests = quote co:complain(400,'bad request','the action you have attempted on this user is not meaningful') return end
for i,v in ipairs(lib.store.relation.members) do
tests = quote
if [v ~= 'block'] and act:cmp(lib.str.plit([v])) and not rel.rel.[v]() then -- rely on dead code elimination :/
(rel.rel.[v] << true)
co.srv:actor_rel_create([lib.store.relation.idvmap[v]], co.who.id, actor.id)
elseif act:cmp(lib.str.plit(['un'..v])) and rel.rel.[v]() then
(rel.rel.[v] << false)
co.srv:actor_rel_destroy([lib.store.relation.idvmap[v]], co.who.id, actor.id)
else [tests] end
end
end
return tests
end)()]
end
end
else
rel.rel:clear()
rel.recip:clear()
end
................................................................................
if handle.ct == 0 then
handle.ct = uri.ct - 2
uri:advance(uri.ct)
elseif handle.ct + 2 < uri.ct then uri:advance(handle.ct + 2) end
lib.dbg('looking up user by xid "', {handle.ptr,handle.ct} ,'", path: ', {uri.ptr,uri.ct})
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
for i=0,path.ct do
lib.dbg('got path component ', {path.ptr[i].ptr, path.ptr[i].ct})
end
var actor = co.srv:actor_fetch_xid(handle)
if actor.ptr == nil then
co:complain(404,'no such user','no such user known to this server')
................................................................................
credsec_for_uid(co: &lib.srv.convo, uid: uint64)
var act = co:ppostv('act')
lib.dbg('showing credentials')
if act:cmp(lib.str.plit 'invalidate') then
lib.dbg('setting user\'s cookie validation time to now')
co.who.source:auth_sigtime_user_alter(uid, lib.osclock.time(nil))
-- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again
co:installkey('?',co.aid)
return
elseif act:cmp(lib.str.plit 'newcred') then
var cmt = co:ppostv('comment')
var pw = co:ppostv('newpw')
var aid: uint64 = 0
if pw:ref() then
var cpw = co:ppostv('rptpw')
................................................................................
end
elseif uri:cmp(lib.str.plit '/logout') then
if co.aid == 0
then goto notfound
else co:reroute_cookie('/','auth=; Path=/')
end
else -- hierarchical routes
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
http.actor_profile_uid(co, path, meth)
elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
http.tweet_page(co, path, meth)
elseif path(0):cmp(lib.str.lit('tl')) then
http.timeline(co, path)
elseif path(0):cmp(lib.str.lit('media')) then
|
Added static/follow.svg version [61b9b2bee5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="20" height="20" viewBox="0 0 5.2916664 5.2916665" version="1.1" id="svg8" inkscape:version="0.92.4 (5da689c313, 2019-01-14)" sodipodi:docname="follow.svg"> <defs id="defs2"> <linearGradient inkscape:collect="always" id="linearGradient1054"> <stop style="stop-color:#ff73e0;stop-opacity:1" offset="0" id="stop1050" /> <stop style="stop-color:#ff00cb;stop-opacity:0.98431373" offset="1" id="stop1052" /> </linearGradient> <linearGradient id="linearGradient1034" inkscape:collect="always"> <stop id="stop1030" offset="0" style="stop-color:#ff55dd;stop-opacity:0.50869566" /> <stop id="stop1032" offset="1" style="stop-color:#ff55dd;stop-opacity:0.02173913" /> </linearGradient> <linearGradient id="linearGradient1019" inkscape:collect="always"> <stop id="stop1013" offset="0" style="stop-color:#680054;stop-opacity:0.01304348" /> <stop style="stop-color:#ff40d9;stop-opacity:0.23913044" offset="0.30000001" id="stop1015" /> <stop id="stop1017" offset="1" style="stop-color:#d400aa;stop-opacity:0;" /> </linearGradient> <linearGradient id="linearGradient1005" inkscape:collect="always"> <stop id="stop1001" offset="0" style="stop-color:#fff6fd;stop-opacity:1" /> <stop id="stop1003" offset="1" style="stop-color:#ff3cd7;stop-opacity:0.98260868" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient979"> <stop style="stop-color:#680054;stop-opacity:1" offset="0" id="stop975" /> <stop id="stop983" offset="0.30000001" style="stop-color:#d400aa;stop-opacity:0.77254902;" /> <stop style="stop-color:#d400aa;stop-opacity:0;" offset="1" id="stop977" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient971"> <stop style="stop-color:#ff55dd;stop-opacity:1;" offset="0" id="stop967" /> <stop style="stop-color:#ff55dd;stop-opacity:0.97826087" offset="1" id="stop969" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient963"> <stop style="stop-color:#c839ac;stop-opacity:0.00392157" offset="0" id="stop959" /> <stop style="stop-color:#852572;stop-opacity:1" offset="1" id="stop961" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient943"> <stop style="stop-color:#f4d7ee;stop-opacity:1;" offset="0" id="stop939" /> <stop style="stop-color:#f4d7ee;stop-opacity:0;" offset="1" id="stop941" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient954"> <stop style="stop-color:#ffffff;stop-opacity:1;" offset="0" id="stop950" /> <stop style="stop-color:#ffffff;stop-opacity:0;" offset="1" id="stop952" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient938"> <stop style="stop-color:#d9fff6;stop-opacity:1;" offset="0" id="stop934" /> <stop style="stop-color:#d9fff6;stop-opacity:0;" offset="1" id="stop936" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient1403"> <stop style="stop-color:#ccaaff;stop-opacity:1;" offset="0" id="stop1399" /> <stop style="stop-color:#ccaaff;stop-opacity:0;" offset="1" id="stop1401" /> </linearGradient> <linearGradient id="linearGradient1395" inkscape:collect="always"> <stop id="stop1391" offset="0" style="stop-color:#ff1616;stop-opacity:1" /> <stop id="stop1393" offset="1" style="stop-color:#ff1d1d;stop-opacity:0" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient1383"> <stop style="stop-color:#980000;stop-opacity:1;" offset="0" id="stop1379" /> <stop style="stop-color:#980000;stop-opacity:0;" offset="1" id="stop1381" /> </linearGradient> <linearGradient inkscape:collect="always" id="linearGradient832"> <stop style="stop-color:#ffcfcf;stop-opacity:1;" offset="0" id="stop828" /> <stop style="stop-color:#ffcfcf;stop-opacity:0;" offset="1" id="stop830" /> </linearGradient> <radialGradient inkscape:collect="always" xlink:href="#linearGradient832" id="radialGradient834" cx="3.2286437" cy="286.62921" fx="3.2286437" fy="286.62921" r="1.0866126" gradientTransform="matrix(1.8608797,0.8147617,-0.38242057,0.87343168,106.71446,33.692223)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1383" id="radialGradient1385" cx="4.1787109" cy="286.89261" fx="4.1787109" fy="286.89261" r="1.2260786" gradientTransform="matrix(1.7016464,0,0,1.6348586,-2.9319775,-182.10895)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1395" id="radialGradient1389" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.66230313,-1.6430738,1.0154487,0.40931507,-290.06307,177.39489)" cx="4.02069" cy="287.79269" fx="4.02069" fy="287.79269" r="1.0866126" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient1403" id="linearGradient1405" x1="8.3939333" y1="288.1091" x2="7.0158253" y2="287.32819" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient938" id="linearGradient940" x1="7.609839" y1="288.73215" x2="7.609839" y2="283.78305" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient954" id="linearGradient956" x1="3.0150654" y1="285.94464" x2="3.0150654" y2="282.40109" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient954" id="linearGradient1138" gradientUnits="userSpaceOnUse" x1="3.0150654" y1="285.94464" x2="3.0150654" y2="284.62277" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1005" id="radialGradient945" cx="6.1517248" cy="285.09021" fx="6.1517248" fy="285.09021" r="1.3844374" gradientTransform="matrix(2.4674713,0,0,2.4674669,-5.8821073,-417.49152)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient943" id="radialGradient953" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.4674713,0,0,2.4674669,-9.027479,-418.36044)" cx="6.1517248" cy="285.09021" fx="6.1517248" fy="285.09021" r="1.3844374" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient963" id="radialGradient965" cx="6.1523438" cy="285.08984" fx="6.1523438" fy="285.08984" r="1.6679688" gradientTransform="matrix(1,0,0,0.99999775,0,6.4095141e-4)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient971" id="radialGradient973" cx="4.6300988" cy="285.0715" fx="4.6300988" fy="285.0715" r="0.88396439" gradientTransform="matrix(3.5121044,0,0,4.5073949,-11.771195,-1000.0836)" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient979" id="linearGradient981" x1="6.3269596" y1="286.08289" x2="6.3263793" y2="288.44873" gradientUnits="userSpaceOnUse" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient1019" id="linearGradient1009" gradientUnits="userSpaceOnUse" x1="6.3269596" y1="286.08289" x2="6.3263793" y2="288.44873" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1034" id="radialGradient1028" cx="7.8964839" cy="10.825195" fx="7.8964839" fy="10.825195" r="6.1388507" gradientTransform="matrix(1.5553588,0,0,2.1211746,-4.385382,-12.136934)" gradientUnits="userSpaceOnUse" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1034" id="radialGradient1038" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.5553588,0,0,-1.3840186,20.178349,25.807467)" cx="7.8964839" cy="10.825195" fx="7.8964839" fy="10.825195" r="6.1388507" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1054" id="radialGradient1048" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.4674713,0,0,2.4674669,-5.8821075,-417.49152)" cx="6.1517248" cy="285.09021" fx="6.1517248" fy="285.09021" r="1.3844374" /> <filter inkscape:collect="always" style="color-interpolation-filters:sRGB" id="filter1132" x="-0.27479975" width="1.5495995" y="-0.27480025" height="1.5496005"> <feGaussianBlur inkscape:collect="always" stdDeviation="0.3170359" id="feGaussianBlur1134" /> </filter> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1054" id="radialGradient1140" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.4674713,0,0,2.4674669,-5.8821075,-417.49152)" cx="6.1517248" cy="285.09021" fx="6.1517248" fy="285.09021" r="1.3844374" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1005" id="radialGradient1142" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.4674713,0,0,2.4674669,-5.8821073,-417.49152)" cx="6.1517248" cy="285.09021" fx="6.1517248" fy="285.09021" r="1.3844374" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient1034" id="radialGradient1149" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.5553588,0,0,-1.3840186,20.178349,25.807467)" cx="7.8964839" cy="10.825195" fx="7.8964839" fy="10.825195" r="6.1388507" /> <linearGradient inkscape:collect="always" xlink:href="#linearGradient979" id="linearGradient1151" gradientUnits="userSpaceOnUse" x1="6.3269596" y1="286.08289" x2="6.3263793" y2="288.44873" /> <radialGradient inkscape:collect="always" xlink:href="#linearGradient971" id="radialGradient1153" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.5121044,0,0,4.5073949,-11.771195,-1000.0836)" cx="4.6300988" cy="285.0715" fx="4.6300988" fy="285.0715" r="0.88396439" /> </defs> <sodipodi:namedview id="base" pagecolor="#181818" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:zoom="11.2" inkscape:cx="30.205871" inkscape:cy="-5.2770461" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="false" units="px" inkscape:window-width="1920" inkscape:window-height="1042" inkscape:window-x="0" inkscape:window-y="38" inkscape:window-maximized="0" showguides="true" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" /> <metadata id="metadata5"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-2.6134661,-283.36966)"> <g id="g1147" transform="matrix(0.9120087,0,0,0.9120087,0.33514277,25.128587)" style="stroke-width:1.09648085"> <path transform="matrix(0.26458333,0,0,0.26458333,2.6134661,283.36966)" d="m 7.9257812,0.8359375 a 1.6178892,1.6178892 0 0 0 -0.2207031,0.009766 C 5.1410214,1.1501128 3.6301435,2.94586 3.1875,4.4550781 2.798777,5.7804512 2.9557893,6.822698 3.0019531,7.09375 c 0.045127,0.9218304 0.3822636,1.5885831 0.7910157,2.2910156 0.3127802,0.5375068 0.7335894,1.0229114 1.15625,1.4980464 0.028572,0.111047 0.050755,0.187185 0.082031,0.326172 0.0073,0.03244 0.00535,0.02259 0.011719,0.05664 -0.3761238,0.02572 -0.8216256,0.06774 -1.2910157,0.138672 -0.4857631,0.07341 -0.9830994,0.168253 -1.4765625,0.332031 -0.493463,0.163778 -1.0998654,0.233591 -1.6191406,1.203125 -0.23350107,0.435868 -0.24245693,0.654459 -0.2890625,0.923828 -0.0466056,0.269369 -0.0772406,0.547444 -0.10351562,0.84961 -0.0525501,0.604332 -0.0820372,1.293158 -0.0996094,1.955078 -0.0351443,1.323838 -0.0214844,2.544922 -0.0214844,2.544922 A 1.6178892,1.6178892 0 0 0 1.7597656,20.814453 H 14.033203 a 1.6178892,1.6178892 0 0 0 1.617188,-1.601562 c 0,0 0.01366,-1.221084 -0.02149,-2.544922 -0.01757,-0.661919 -0.04706,-1.350747 -0.09961,-1.955078 -0.02628,-0.302166 -0.05691,-0.580241 -0.103516,-0.84961 -0.04661,-0.269368 -0.05556,-0.487961 -0.289062,-0.923828 C 14.61759,11.970465 14.010855,11.900125 13.517578,11.736328 13.024302,11.572531 12.526554,11.477735 12.041016,11.404297 11.571088,11.33322 11.126348,11.28939 10.75,11.263672 c 0.0028,-0.01394 8.95e-4,-0.0098 0.0039,-0.02344 0.02862,-0.129185 0.05214,-0.210465 0.08008,-0.320312 0.433111,-0.472266 0.867515,-0.9510681 1.1875,-1.498047 0.424707,-0.7259885 0.791976,-1.4348115 0.777344,-2.4375 l -0.02734,0.3183594 c 0,0 0.276624,-1.338406 -0.166015,-2.8476563 C 12.162829,2.9458278 10.651988,1.1499497 8.0878906,0.84570312 A 1.6178892,1.6178892 0 0 0 7.9257812,0.8359375 Z M 10.701172,11.511719 c -0.0029,-0.0036 0.007,0.0064 0.0039,0.002 -0.04632,-0.06737 -0.0293,-0.353973 -0.0293,0.134766 0,0.04526 0.01972,-0.102408 0.02539,-0.136719 z m -5.6093751,0.002 c 0.00534,0.02911 0.025391,0.180144 0.025391,0.134766 0,-0.486237 0.016732,-0.199942 -0.029297,-0.132813 -0.00293,0.0043 0.00675,-0.0055 0.00391,-0.002 z" id="path1021" style="fill:url(#radialGradient1149);fill-opacity:1;stroke:none;stroke-width:1.09648073px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" inkscape:original="M 7.8964844 2.453125 C 3.8572424 2.9326715 4.6113281 7.0078125 4.6113281 7.0078125 C 4.6485531 7.8381593 5.5094605 9.2817797 6.4453125 10.195312 C 6.4986525 10.392157 6.734375 11.271085 6.734375 11.648438 C 6.734375 12.069175 6.1908578 12.91084 5.8691406 12.861328 C 5.5474216 12.811888 2.4532451 13.010035 2.0820312 13.703125 C 1.7108136 14.396064 1.7597656 19.197266 1.7597656 19.197266 L 14.033203 19.197266 C 14.033203 19.197266 14.082152 14.396064 13.710938 13.703125 C 13.339721 13.010224 10.247498 12.811816 9.9257812 12.861328 C 9.6040608 12.910798 9.0585937 12.069174 9.0585938 11.648438 C 9.0585938 11.282797 9.2742792 10.466705 9.3378906 10.230469 C 10.300978 9.3271083 11.194239 7.8711535 11.181641 7.0078125 C 11.181641 7.0078125 11.935727 2.9324069 7.8964844 2.453125 z " inkscape:radius="1.6177274" sodipodi:type="inkscape:offset" /> <path sodipodi:nodetypes="cccsccscccc" inkscape:connector-curvature="0" d="m 3.0792354,288.44873 c 0,0 -0.013096,-1.27028 0.085122,-1.45362 0.098217,-0.18338 0.9166976,-0.23571 1.0018191,-0.22263 0.085121,0.0131 0.2291744,-0.20953 0.2291744,-0.32085 0,-0.11131 -0.085123,-0.41905 -0.085123,-0.41905 h 0.7851589 c 0,0 -0.085122,0.30774 -0.085122,0.41905 0,0.11132 0.1440525,0.33394 0.2291744,0.32085 0.085121,-0.0131 0.9036015,0.0393 1.0018191,0.22263 0.098217,0.18334 0.085121,1.45362 0.085121,1.45362 z" style="fill:url(#linearGradient1151);fill-opacity:1;stroke:none;stroke-width:0.29011053px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" id="path893" /> <path sodipodi:nodetypes="cczcc" inkscape:connector-curvature="0" d="m 4.7028071,284.01884 c -1.0687161,0.12688 -0.8692216,1.20492 -0.8692216,1.20492 0.015116,0.33718 0.5431676,1.06402 0.8692218,1.06402 0.3260542,0 0.8742883,-0.71682 0.8692217,-1.06402 0,0 0.1994946,-1.07811 -0.8692216,-1.20492" style="fill:url(#radialGradient1153);fill-opacity:1;stroke:none;stroke-width:0.18091933;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path888" /> </g> <g id="g1138" transform="matrix(0.83362971,0,0,0.83362961,-1.263316,47.635689)" style="stroke-width:1.1995734"> <path id="path1046" style="fill:url(#radialGradient1140);fill-opacity:1;stroke:none;stroke-width:0.19792962;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter1132)" d="m 9.0817743,287.34356 h 0.43065 v -1.16911 H 10.681534 V 285.7438 H 9.5124243 v -1.16911 h -0.43065 v 1.16911 h -1.169115 v 0.43065 h 1.169115 z" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccccc" /> <path sodipodi:nodetypes="ccccccccccccc" inkscape:connector-curvature="0" d="m 9.0817743,287.34356 h 0.43065 v -1.16911 H 10.681534 V 285.7438 H 9.5124243 v -1.16911 h -0.43065 v 1.16911 h -1.169115 v 0.43065 h 1.169115 z" style="fill:url(#radialGradient1142);fill-opacity:1;stroke:none;stroke-width:0.19792962;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="path932" /> </g> </g> </svg> |
Modified static/style.scss from [ba9256aed1] to [08446e37b3].
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
|
}
&:empty {
transition: 0.3s;
opacity: 0.0001; // qutebrowser won't show hints if opacity=0 :(
&:hover, &:focus { opacity: 0.6 !important; }
}
}
> .like { background-image: url(/s/heart.webp); }
> .rt { background-image: url(/s/retweet.webp); }
}
// used for keyboard navigation
&.live-selected {
//margin-left: 0.4in; margin-right: -0.4in;
box-shadow: 0 0 0 1px tone(15%), 0 0 1in tone(5%, -0.5);
transform: scale(1.05) translateX(0.1in);
................................................................................
body.notices {
form { text-align: center; }
div.notice {
padding: 0.15in;
background: linear-gradient(to bottom, tone(10%, -0.9), transparent);
border: 1px solid tone(-60%);
& + div.notice { border-top: none; }
&.rt, &.like, &.reply { &::before {
display: inline-block;
width: 1em; height: 1em;
margin-right: 1ex;
background-size: contain;
vertical-align: bottom;
content: ""; // 🙄
}}
&.rt::before { background-image: url(/s/retweet.webp); }
&.like::before { background-image: url(/s/heart.webp); }
&.reply::before { background-image: url(/s/reply.webp); }
> .action {
display: inline-block;
color: tone(5%);
> .id {
display: inline-block;
> img {
width: 1em; height: 1em;
|
|
|
|
|
|
|
>
|
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
|
}
&:empty {
transition: 0.3s;
opacity: 0.0001; // qutebrowser won't show hints if opacity=0 :(
&:hover, &:focus { opacity: 0.6 !important; }
}
}
> .like { background-image: url(/s/heart.webp); }
> .rt { background-image: url(/s/retweet.webp); }
}
// used for keyboard navigation
&.live-selected {
//margin-left: 0.4in; margin-right: -0.4in;
box-shadow: 0 0 0 1px tone(15%), 0 0 1in tone(5%, -0.5);
transform: scale(1.05) translateX(0.1in);
................................................................................
body.notices {
form { text-align: center; }
div.notice {
padding: 0.15in;
background: linear-gradient(to bottom, tone(10%, -0.9), transparent);
border: 1px solid tone(-60%);
& + div.notice { border-top: none; }
&.rt, &.like, &.reply, &.follow { &::before {
display: inline-block;
width: 1em; height: 1em;
margin-right: 1ex;
background-size: contain;
vertical-align: bottom;
content: ""; // 🙄
}}
&.rt::before { background-image: url(/s/retweet.webp); }
&.like::before { background-image: url(/s/heart.webp); }
&.reply::before { background-image: url(/s/reply.webp); }
&.follow::before { background-image: url(/s/follow.webp); }
> .action {
display: inline-block;
color: tone(5%);
> .id {
display: inline-block;
> img {
width: 1em; height: 1em;
|
Modified store.t from [adf1545306] to [8b07464dc2].
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
local m = {
timepoint = lib.osclock.time_t;
scope = lib.enum {
'public', 'private', 'local';
'personal', 'direct', 'circle';
};
noticetype = lib.enum {
'none', 'mention', 'reply', 'like', 'rt', 'react'
};
relation = lib.set {
'follow',
'subscribe', -- get a notification for every post
'mute', -- posts will be completely hidden at all times
'block', -- no interactions will be permitted, but posts will remain visible
|
| |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
local m = {
timepoint = lib.osclock.time_t;
scope = lib.enum {
'public', 'private', 'local';
'personal', 'direct', 'circle';
};
noticetype = lib.enum {
'none', 'mention', 'reply', 'like', 'rt', 'react', 'follow'
};
relation = lib.set {
'follow',
'subscribe', -- get a notification for every post
'mute', -- posts will be completely hidden at all times
'block', -- no interactions will be permitted, but posts will remain visible
|