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
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
-- vim: ft=terra
local pstr = lib.mem.ptr(int8)
local terra cs(s: rawstring)
return pstr { ptr = s, ct = lib.str.sz(s) }
end
local terra
render_profile(
co: &lib.srv.convo,
actor: &lib.store.actor,
relationship: &lib.store.relationship
): pstr
var aux: lib.str.acc
var followed = false -- FIXME
if co.aid ~= 0 and co.who.id == actor.id then
aux:pcompose(&co.srv.pool,'<a accesskey="a" class="button" href="/conf/profile?go=/@',actor.handle,'">alter</a>')
elseif co.aid ~= 0 then
if not relationship.rel.follow() then
aux:pcompose(&co.srv.pool,'<button accesskey="f" method="post" class="pos" name="act" value="follow">follow</button>')
elseif relationship.rel.follow() then
aux:pcompose(&co.srv.pool,'<button accesskey="f" method="post" class="neg" name="act" value="unfollow">unfollow</button>')
end
aux:lpush(' <a accesskey="h" class="button" href="/'):push(actor.xid,0):lpush('/chat">chat</a>')
if co.who.rights.powers:affect_users() and co.who:overpowers(actor) then
aux:lpush(' <a accesskey="n" class="button" href="/conf/users/'):shpush(actor.id):lpush('">control</a>')
end
else
aux:pcompose(&co.srv.pool,' <a accesskey="f" class="button" href="/', actor.xid, '/follow">remote follow</a>')
end
var auxp = aux:finalize()
var timestr: int8[26] lib.osclock.ctime_r(&actor.knownsince, ×tr[0])
var strfbuf: int8[28*4]
var stats = co.srv:actor_stats(actor.id)
var sn_posts = cs(lib.math.decstr_friendly(stats.posts, &strfbuf[ [strfbuf.type.N - 1] ]))
var sn_follows = cs(lib.math.decstr_friendly(stats.follows, sn_posts.ptr - 1))
var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1))
var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1))
................................................................................
nfollowers = sn_followers, nmutuals = sn_mutuals;
tweetday = cs(timestr);
timephrase = lib.trn(actor.origin == 0, pstr 'joined', pstr 'known since');
remarks = '';
auxbtn = auxp;
}
if comments.sz > 0 then profile.remarks = comments:finalize() end
var ret = profile:poolstr(&co.srv.pool)
-- auxp:free()
--if actor.bio ~= nil then bio:free() end
--if comments.sz > 0 then profile.remarks:free() end
return ret
end
return render_profile
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
<
>
|
<
<
<
<
<
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
-- vim: ft=terra
local pstr = lib.mem.ptr(int8)
local terra cs(s: rawstring)
return pstr { ptr = s, ct = lib.str.sz(s) }
end
local relkinds = {
pos = {
{ id = 'follow', start = {
text = 'follow';
desc = "this user's posts will appear in your timeline";
}, stop = {
text = 'unfollow';
desc = "this user's posts will no longer appear in your timeline";
}};
{ id = 'sub', start = {
text = 'subscribe';
desc = "you will get a notification whenever this user posts";
}, stop = {
text = 'unsubscribe';
desc = "you will no longer get notifications when this user posts";
}};
};
neg = {
{ id = 'mute', start = {
text = 'mute';
desc = "this user's posts will no longer appear anywhere";
}, stop = {
text = 'unmute';
desc = "this user's posts will once again be visible to you";
}};
{ id = 'exclude', start = {
text = 'exclude';
desc = "this user will not be able to see your posts";
}, stop = {
text = 'reinclude';
desc = "this user will again be able to see your posts";
}};
{ id = 'avoid', start = {
text = 'avoid';
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";
}, stop = {
text = 'reconcile';
desc = "this user will once again be able to originate notices to you, and will be shown on your timeline";
}};
{ id = 'collapse', start = {
text = 'collapse';
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";
}, stop = {
text = 'expand';
desc = "this user's posts will no longer be collapsed";
}};
{ id = 'disemvowel', start = {
text = 'disemvowel'; -- translations should not translate this literally
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";
}, stop = {
text = 're-emvowel';
desc = "this user's posts will once again appear normally";
}};
{ id = 'block', start = {
text = 'block';
desc = "this user will not be able to interact with you in any fashion and they will be forced to unfollow you";
}, stop = {
text = 'unblock';
desc = "this user will once again be able to interact with you";
}};
};
}
local function
btnhtml(kind)
local function sb(class)
local b = kind[class]
return string.format('<div class="opt%s">' ..
'<button name="act" value="%s">%s</button>' ..
'<p>%s</p>' ..
'</div>',
(class == 'stop' and ' on' or ''),
(class == 'stop' and 'un' or '') .. kind.id,
b.text, b.desc)
end
return sb('start'), sb('stop')
end
local terra
render_profile(
co: &lib.srv.convo,
actor: &lib.store.actor,
relationship: &lib.store.relationship
): pstr
var aux = co:stra(128)
var followed = false -- FIXME
if co.aid ~= 0 and co.who.id == actor.id then
aux:lpush('<a accesskey="a" class="button" href="/conf/profile?go=/@'):push(actor.handle,0):lpush('">alter</a>')
elseif co.aid ~= 0 then
if co.who.rights.powers:affect_users() and co.who:overpowers(actor) then
aux:lpush(' <a accesskey="n" class="button" href="/conf/users/'):shpush(actor.id):lpush('">control</a>')
end
else
aux:lpush(' <a accesskey="f" class="button" href="/'):push(actor.xid,0):lpush('/follow">remote follow</a>')
end
var auxp = aux:finalize()
var timestr: int8[26] lib.osclock.ctime_r(&actor.knownsince, ×tr[0])
var relbtns = co:stra(256)
var sancbtns = co:stra(256)
[(function()
local allkinds = {}
for kind, rels in pairs(relkinds) do
for i,v in ipairs(rels) do
v.kind = kind
allkinds[#allkinds + 1] = v
end
end
local br = {}
for i,v in ipairs(allkinds) do
local off, on = btnhtml(v)
local target = v.kind == 'pos' and relbtns or sancbtns
br[#br+1] = quote
if relationship.rel.[v.id]()
then target:ppush(lib.str.plit([on]))
else target:ppush(lib.str.plit([off]))
end
end
end
return br
end)()]
var strfbuf: int8[28*4]
var stats = co.srv:actor_stats(actor.id)
var sn_posts = cs(lib.math.decstr_friendly(stats.posts, &strfbuf[ [strfbuf.type.N - 1] ]))
var sn_follows = cs(lib.math.decstr_friendly(stats.follows, sn_posts.ptr - 1))
var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1))
var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1))
................................................................................
nfollowers = sn_followers, nmutuals = sn_mutuals;
tweetday = cs(timestr);
timephrase = lib.trn(actor.origin == 0, pstr 'joined', pstr 'known since');
remarks = '';
auxbtn = auxp;
relations = relbtns:finalize();
sanctions = sancbtns:finalize();
}
if comments.sz > 0 then profile.remarks = comments:finalize() end
var ret = profile:poolstr(&co.srv.pool)
-- auxp:free()
--if actor.bio ~= nil then bio:free() end
--if comments.sz > 0 then profile.remarks:free() end
return ret
end
return render_profile
|