Compare commits

...

6 Commits

6 changed files with 114 additions and 33 deletions

View File

@ -1,5 +1,9 @@
# Release Notes
## 2.52
Posts that were liked or boosted can now be unliked and unboosted.
## 2.51
Support for custom Emojis has been added; they are no longer hardcoded, but read from the `emojis.json` file at the server base directory. Also, they are no longer limited to string substitutions, but images as external URLs are also supported (see `snac(8)` for more information).

View File

@ -1149,8 +1149,10 @@ xs_dict *msg_admiration(snac *snac, char *object, char *type)
if (valid_status(object_get(object, &a_msg))) {
xs *rcpts = xs_list_new();
xs *o_md5 = xs_md5_hex(object, strlen(object));
xs *id = xs_fmt("%s/%s/%s", snac->actor, *type == 'L' ? "l" : "a", o_md5);
msg = msg_base(snac, type, "@dummy", snac->actor, "@now", object);
msg = msg_base(snac, type, id, snac->actor, "@now", object);
if (is_msg_public(a_msg))
rcpts = xs_list_append(rcpts, public_address);
@ -1166,6 +1168,33 @@ xs_dict *msg_admiration(snac *snac, char *object, char *type)
}
xs_dict *msg_repulsion(snac *user, char *id, char *type)
/* creates an Undo + admiration message */
{
xs *a_msg = NULL;
xs_dict *msg = NULL;
if (valid_status(object_get(id, &a_msg))) {
/* create a clone of the original admiration message */
xs *object = msg_admiration(user, id, type);
/* delete the published date */
object = xs_dict_del(object, "published");
/* create an undo message for this object */
msg = msg_undo(user, object);
/* copy the 'to' field */
msg = xs_dict_set(msg, "to", xs_dict_get(object, "to"));
}
/* now we despise this */
object_unadmire(id, user->actor, *type == 'L' ? 1 : 0);
return msg;
}
xs_dict *msg_actor(snac *snac)
/* create a Person message for this actor */
{

25
html.c
View File

@ -1249,6 +1249,11 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
xs_html_add(form,
html_button("like", L("Like"), L("Say you like this post")));
}
else {
/* not like it anymore */
xs_html_add(form,
html_button("unlike", L("Unlike"), L("Nah don't like it that much")));
}
}
else {
if (is_pinned(snac, id))
@ -1265,6 +1270,11 @@ xs_html *html_entry_controls(snac *snac, char *actor, const xs_dict *msg, const
xs_html_add(form,
html_button("boost", L("Boost"), L("Announce this post to your followers")));
}
else {
/* already boosted; add button to regret */
xs_html_add(form,
html_button("unboost", L("Unboost"), L("I regret I boosted this")));
}
}
if (strcmp(actor, snac->actor) != 0) {
@ -2947,6 +2957,21 @@ int html_post_handler(const xs_dict *req, const char *q_path,
timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, 0);
}
}
if (strcmp(action, L("Unlike")) == 0) { /** **/
xs *msg = msg_repulsion(&snac, id, "Like");
if (msg != NULL) {
enqueue_message(&snac, msg);
}
}
else
if (strcmp(action, L("Unboost")) == 0) { /** **/
xs *msg = msg_repulsion(&snac, id, "Announce");
if (msg != NULL) {
enqueue_message(&snac, msg);
}
}
else
if (strcmp(action, L("MUTE")) == 0) { /** **/
mute(&snac, actor);

65
main.c
View File

@ -18,31 +18,32 @@ int usage(void)
printf("\n");
printf("Commands:\n");
printf("\n");
printf("init [{basedir}] Initializes the data storage\n");
printf("upgrade {basedir} Upgrade to a new version\n");
printf("adduser {basedir} [{uid}] Adds a new user\n");
printf("deluser {basedir} {uid} Deletes a user\n");
printf("httpd {basedir} Starts the HTTPD daemon\n");
printf("purge {basedir} Purges old data\n");
printf("state {basedir} Prints server state\n");
printf("webfinger {basedir} {actor} Queries about an actor (@user@host or actor url)\n");
printf("queue {basedir} {uid} Processes a user queue\n");
printf("follow {basedir} {uid} {actor} Follows an actor\n");
printf("unfollow {basedir} {uid} {actor} Unfollows an actor\n");
printf("request {basedir} {uid} {url} Requests an object\n");
printf("actor {basedir} [{uid}] {url} Requests an actor\n");
printf("init [{basedir}] Initializes the data storage\n");
printf("upgrade {basedir} Upgrade to a new version\n");
printf("adduser {basedir} [{uid}] Adds a new user\n");
printf("deluser {basedir} {uid} Deletes a user\n");
printf("httpd {basedir} Starts the HTTPD daemon\n");
printf("purge {basedir} Purges old data\n");
printf("state {basedir} Prints server state\n");
printf("webfinger {basedir} {actor} Queries about an actor (@user@host or actor url)\n");
printf("queue {basedir} {uid} Processes a user queue\n");
printf("follow {basedir} {uid} {actor} Follows an actor\n");
printf("unfollow {basedir} {uid} {actor} Unfollows an actor\n");
printf("request {basedir} {uid} {url} Requests an object\n");
printf("actor {basedir} [{uid}] {url} Requests an actor\n");
printf("note {basedir} {uid} {text} [files...] Sends a note with optional attachments\n");
printf("announce {basedir} {uid} {url} Announces (boosts) a post\n");
printf("resetpwd {basedir} {uid} Resets the password of a user\n");
printf("ping {basedir} {uid} {actor} Pings an actor\n");
printf("webfinger_s {basedir} {uid} {actor} Queries about an actor (@user@host or actor url)\n");
printf("pin {basedir} {uid} {msg_url} Pins a message\n");
printf("unpin {basedir} {uid} {msg_url} Unpins a message\n");
printf("block {basedir} {instance_url} Blocks a full instance\n");
printf("unblock {basedir} {instance_url} Unblocks a full instance\n");
printf("limit {basedir} {uid} {actor} Limits an actor (drops their announces)\n");
printf("unlimit {basedir} {uid} {actor} Unlimits an actor\n");
printf("verify_links {basedir} {uid} Verifies a user's links (in the metadata)\n");
printf("boost|announce {basedir} {uid} {url} Boosts (announces) a post\n");
printf("unboost {basedir} {uid} {url} Unboosts a post\n");
printf("resetpwd {basedir} {uid} Resets the password of a user\n");
printf("ping {basedir} {uid} {actor} Pings an actor\n");
printf("webfinger_s {basedir} {uid} {actor} Queries about an actor (@user@host or actor url)\n");
printf("pin {basedir} {uid} {msg_url} Pins a message\n");
printf("unpin {basedir} {uid} {msg_url} Unpins a message\n");
printf("block {basedir} {instance_url} Blocks a full instance\n");
printf("unblock {basedir} {instance_url} Unblocks a full instance\n");
printf("limit {basedir} {uid} {actor} Limits an actor (drops their announces)\n");
printf("unlimit {basedir} {uid} {actor} Unlimits an actor\n");
printf("verify_links {basedir} {uid} Verifies a user's links (in the metadata)\n");
return 1;
}
@ -281,7 +282,7 @@ int main(int argc, char *argv[])
return 0;
}
if (strcmp(cmd, "announce") == 0) { /** **/
if (strcmp(cmd, "boost") == 0 || strcmp(cmd, "announce") == 0) { /** **/
xs *msg = msg_admiration(&snac, url, "Announce");
if (msg != NULL) {
@ -295,6 +296,20 @@ int main(int argc, char *argv[])
return 0;
}
if (strcmp(cmd, "unboost") == 0) { /** **/
xs *msg = msg_repulsion(&snac, url, "Announce");
if (msg != NULL) {
enqueue_message(&snac, msg);
if (dbglevel) {
xs_json_dump(msg, 4, stdout);
}
}
return 0;
}
if (strcmp(cmd, "follow") == 0) { /** **/
xs *msg = msg_follow(&snac, url);

View File

@ -2314,11 +2314,13 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
}
else
if (strcmp(op, "unfavourite") == 0) { /** **/
/* partial support: as the original Like message
is not stored anywhere here, it's not possible
to send an Undo + Like; the only thing done here
is to delete the actor from the list of likes */
object_unadmire(id, snac.actor, 1);
xs *n_msg = msg_repulsion(&snac, id, "Like");
if (n_msg != NULL) {
enqueue_message(&snac, n_msg);
out = mastoapi_status(&snac, msg);
}
}
else
if (strcmp(op, "reblog") == 0) { /** **/
@ -2333,8 +2335,13 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
}
else
if (strcmp(op, "unreblog") == 0) { /** **/
/* partial support: see comment in 'unfavourite' */
object_unadmire(id, snac.actor, 0);
xs *n_msg = msg_repulsion(&snac, id, "Announce");
if (n_msg != NULL) {
enqueue_message(&snac, n_msg);
out = mastoapi_status(&snac, msg);
}
}
else
if (strcmp(op, "bookmark") == 0) { /** **/

1
snac.h
View File

@ -264,6 +264,7 @@ char *get_atto(const xs_dict *msg);
xs_list *get_attachments(const xs_dict *msg);
xs_dict *msg_admiration(snac *snac, char *object, char *type);
xs_dict *msg_repulsion(snac *user, char *id, char *type);
xs_dict *msg_create(snac *snac, const xs_dict *object);
xs_dict *msg_follow(snac *snac, const char *actor);