Differences From
Artifact [4c6c4c1279]:
1 1 -- vim: ft=terra
2 2 local pstr = lib.mem.ptr(int8)
3 3 local terra cs(s: rawstring)
4 4 return pstr { ptr = s, ct = lib.str.sz(s) }
5 5 end
6 +
7 +local relkinds = {
8 + pos = {
9 + { id = 'follow', start = {
10 + text = 'follow';
11 + desc = "this user's posts will appear in your timeline";
12 + }, stop = {
13 + text = 'unfollow';
14 + desc = "this user's posts will no longer appear in your timeline";
15 + }};
16 +
17 + { id = 'sub', start = {
18 + text = 'subscribe';
19 + desc = "you will get a notification whenever this user posts";
20 + }, stop = {
21 + text = 'unsubscribe';
22 + desc = "you will no longer get notifications when this user posts";
23 + }};
24 + };
25 + neg = {
26 + { id = 'mute', start = {
27 + text = 'mute';
28 + desc = "this user's posts will no longer appear anywhere";
29 + }, stop = {
30 + text = 'unmute';
31 + desc = "this user's posts will once again be visible to you";
32 + }};
33 +
34 + { id = 'exclude', start = {
35 + text = 'exclude';
36 + desc = "this user will not be able to see your posts";
37 + }, stop = {
38 + text = 'reinclude';
39 + desc = "this user will again be able to see your posts";
40 + }};
41 +
42 + { id = 'avoid', start = {
43 + text = 'avoid';
44 + desc = "this user's posts will not appear on your timeline even if you follow them and you will not receive notices from them, but they will still be visible in threads";
45 + }, stop = {
46 + text = 'reconcile';
47 + desc = "this user will once again be able to originate notices to you, and will be shown on your timeline";
48 + }};
49 +
50 + { id = 'collapse', start = {
51 + text = 'collapse';
52 + desc = "this user's posts will still appear but will be collapsed by default, so you only see the text if you choose to expand each post";
53 + }, stop = {
54 + text = 'expand';
55 + desc = "this user's posts will no longer be collapsed";
56 + }};
57 +
58 + { id = 'disemvowel', start = {
59 + text = 'disemvowel'; -- translations should not translate this literally
60 + desc = "this user's posts will be ritually mutilated in a humorous fashion as appropriate to the script in which they are written; e.g. the removal of vowels in roman text and deletion of kana in japanese text";
61 + }, stop = {
62 + text = 're-emvowel';
63 + desc = "this user's posts will once again appear normally";
64 + }};
65 +
66 + { id = 'block', start = {
67 + text = 'block';
68 + desc = "this user will not be able to interact with you in any fashion and they will be forced to unfollow you";
69 + }, stop = {
70 + text = 'unblock';
71 + desc = "this user will once again be able to interact with you";
72 + }};
73 + };
74 +}
75 +
76 +local function
77 +btnhtml(kind)
78 + local function sb(class)
79 + local b = kind[class]
80 + return string.format('<div class="opt%s">' ..
81 + '<button name="act" value="%s">%s</button>' ..
82 + '<p>%s</p>' ..
83 + '</div>',
84 + (class == 'stop' and ' on' or ''),
85 + (class == 'stop' and 'un' or '') .. kind.id,
86 + b.text, b.desc)
87 + end
88 + return sb('start'), sb('stop')
89 +end
6 90
7 91 local terra
8 92 render_profile(
9 93 co: &lib.srv.convo,
10 94 actor: &lib.store.actor,
11 95 relationship: &lib.store.relationship
12 96 ): pstr
13 - var aux: lib.str.acc
97 + var aux = co:stra(128)
14 98 var followed = false -- FIXME
15 99 if co.aid ~= 0 and co.who.id == actor.id then
16 - aux:pcompose(&co.srv.pool,'<a accesskey="a" class="button" href="/conf/profile?go=/@',actor.handle,'">alter</a>')
100 + aux:lpush('<a accesskey="a" class="button" href="/conf/profile?go=/@'):push(actor.handle,0):lpush('">alter</a>')
17 101 elseif co.aid ~= 0 then
18 - if not relationship.rel.follow() then
19 - aux:pcompose(&co.srv.pool,'<button accesskey="f" method="post" class="pos" name="act" value="follow">follow</button>')
20 - elseif relationship.rel.follow() then
21 - aux:pcompose(&co.srv.pool,'<button accesskey="f" method="post" class="neg" name="act" value="unfollow">unfollow</button>')
22 - end
23 - aux:lpush(' <a accesskey="h" class="button" href="/'):push(actor.xid,0):lpush('/chat">chat</a>')
24 102 if co.who.rights.powers:affect_users() and co.who:overpowers(actor) then
25 103 aux:lpush(' <a accesskey="n" class="button" href="/conf/users/'):shpush(actor.id):lpush('">control</a>')
26 104 end
27 105 else
28 - aux:pcompose(&co.srv.pool,' <a accesskey="f" class="button" href="/', actor.xid, '/follow">remote follow</a>')
106 + aux:lpush(' <a accesskey="f" class="button" href="/'):push(actor.xid,0):lpush('/follow">remote follow</a>')
29 107 end
30 108 var auxp = aux:finalize()
31 109 var timestr: int8[26] lib.osclock.ctime_r(&actor.knownsince, ×tr[0])
110 +
111 + var relbtns = co:stra(256)
112 + var sancbtns = co:stra(256)
113 + [(function()
114 + local allkinds = {}
115 + for kind, rels in pairs(relkinds) do
116 + for i,v in ipairs(rels) do
117 + v.kind = kind
118 + allkinds[#allkinds + 1] = v
119 + end
120 + end
121 + local br = {}
122 + for i,v in ipairs(allkinds) do
123 + local off, on = btnhtml(v)
124 + local target = v.kind == 'pos' and relbtns or sancbtns
125 + br[#br+1] = quote
126 + if relationship.rel.[v.id]()
127 + then target:ppush(lib.str.plit([on]))
128 + else target:ppush(lib.str.plit([off]))
129 + end
130 + end
131 + end
132 + return br
133 + end)()]
32 134
33 135 var strfbuf: int8[28*4]
34 136 var stats = co.srv:actor_stats(actor.id)
35 137 var sn_posts = cs(lib.math.decstr_friendly(stats.posts, &strfbuf[ [strfbuf.type.N - 1] ]))
36 138 var sn_follows = cs(lib.math.decstr_friendly(stats.follows, sn_posts.ptr - 1))
37 139 var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1))
38 140 var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1))
................................................................................
97 199 nfollowers = sn_followers, nmutuals = sn_mutuals;
98 200 tweetday = cs(timestr);
99 201 timephrase = lib.trn(actor.origin == 0, pstr 'joined', pstr 'known since');
100 202
101 203 remarks = '';
102 204
103 205 auxbtn = auxp;
206 + relations = relbtns:finalize();
207 + sanctions = sancbtns:finalize();
104 208 }
105 209 if comments.sz > 0 then profile.remarks = comments:finalize() end
106 210
107 211 var ret = profile:poolstr(&co.srv.pool)
108 212 -- auxp:free()
109 213 --if actor.bio ~= nil then bio:free() end
110 214 --if comments.sz > 0 then profile.remarks:free() end
111 215 return ret
112 216 end
113 217
114 218 return render_profile