# retoor <retoor@molodetz.nl>
from .._shared import BOOKMARK_TARGETS, REACTION_TARGETS, VOTE_TARGETS, endpoint, field
from devplacepy.constants import REACTION_EMOJI
GROUP = {
"slug": "social-actions",
"title": "Votes, Reactions, Bookmarks & Polls",
"intro": """
# Votes, Reactions, Bookmarks & Polls
Lightweight engagement actions. The POST endpoints here are **toggles** - sending the same
action again removes it. They return JSON when called with `X-Requested-With: fetch` (sent
automatically by the panels below); the [Conventions & Errors](/docs/conventions.html) page
explains that header rule and the response envelope.
Every endpoint follows the shared [Conventions & Errors](/docs/conventions.html) (auth, content
negotiation, pagination, status codes); see [Authentication](/docs/authentication.html) for the
four ways to sign requests.
""",
"endpoints": [
endpoint(
id="votes-cast",
method="POST",
path="/votes/{target_type}/{target_uid}",
title="Cast or toggle a vote",
summary="Upvote or downvote a target. Re-sending the same value removes the vote.",
auth="user",
ajax=True,
encoding="form",
params=[
field(
"target_type",
"path",
"enum",
True,
"post",
"Type of content being voted on.",
VOTE_TARGETS,
),
field(
"target_uid",
"path",
"string",
True,
"POST_UID",
"UID of the target.",
),
field(
"value",
"form",
"enum",
True,
"1",
"1 to upvote, -1 to downvote.",
["1", "-1"],
),
],
sample_response={"net": 3, "up": 4, "down": 1, "value": 1},
),
endpoint(
id="reactions-toggle",
method="POST",
path="/reactions/{target_type}/{target_uid}",
title="Toggle an emoji reaction",
summary="Add or remove an emoji reaction on a target.",
auth="user",
ajax=True,
encoding="form",
params=[
field(
"target_type",
"path",
"enum",
True,
"post",
"Type of content being reacted to.",
REACTION_TARGETS,
),
field(
"target_uid",
"path",
"string",
True,
"POST_UID",
"UID of the target.",
),
field(
"emoji",
"form",
"enum",
True,
REACTION_EMOJI[0],
"One of the allowed reaction emoji.",
REACTION_EMOJI,
),
],
sample_response={
"counts": {REACTION_EMOJI[0]: 2},
"mine": [REACTION_EMOJI[0]],
},
),
endpoint(
id="bookmarks-toggle",
method="POST",
path="/bookmarks/{target_type}/{target_uid}",
title="Toggle a bookmark",
summary="Save or unsave a target to your bookmarks.",
auth="user",
ajax=True,
encoding="none",
params=[
field(
"target_type",
"path",
"enum",
True,
"post",
"Type of content to bookmark.",
BOOKMARK_TARGETS,
),
field(
"target_uid",
"path",
"string",
True,
"POST_UID",
"UID of the target.",
),
],
sample_response={"saved": True},
),
endpoint(
id="bookmarks-saved",
method="GET",
path="/bookmarks/saved",
title="View saved bookmarks",
summary="Render your saved content. Returns an HTML page.",
auth="user",
interactive=True,
params=[
field(
"before",
"query",
"string",
False,
"",
"Pagination cursor (created_at of the last item).",
)
],
notes=[
"Bookmarks target posts, projects, gists, and news; see [Posts, Comments, Projects, Gists & News](/docs/content.html)."
],
),
endpoint(
id="polls-vote",
method="POST",
path="/polls/{poll_uid}/vote",
title="Vote in a poll",
summary="Cast, change, or clear your vote on a poll option.",
auth="user",
ajax=True,
encoding="form",
params=[
field(
"poll_uid",
"path",
"string",
True,
"POLL_UID",
"UID of the poll.",
),
field(
"option_uid",
"form",
"string",
True,
"OPTION_UID",
"UID of the chosen option.",
),
],
notes=[
"You hold at most one vote per poll, and only your latest vote counts. "
"Voting a different option replaces your previous choice; voting your current "
"option again removes the vote.",
],
sample_response={
"question": "Best editor?",
"options": [{"uid": "OPTION_UID", "label": "Vim", "votes": 5}],
"total": 5,
"voted": "OPTION_UID",
},
),
],
}