Merge branch 'feature/implement-inline-replies' into 'master'

Implement inline replies

Closes #131

See merge request litecord/litecord!79
This commit is contained in:
luna 2021-09-05 03:23:00 +00:00
commit 4860ae369d
10 changed files with 55 additions and 11 deletions

1
.gitignore vendored
View File

@ -109,3 +109,4 @@ attachments/*
.DS_Store .DS_Store
.vscode .vscode
.idea

View File

@ -41,6 +41,7 @@ from litecord.common.messages import (
msg_create_check_content, msg_create_check_content,
msg_add_attachment, msg_add_attachment,
msg_guild_text_mentions, msg_guild_text_mentions,
message_view,
) )
from litecord.pubsub.user import dispatch_user from litecord.pubsub.user import dispatch_user
@ -129,7 +130,7 @@ async def get_messages(channel_id):
if msg is None: if msg is None:
continue continue
result.append(msg) result.append(message_view(msg))
log.info("Fetched {} messages", len(result)) log.info("Fetched {} messages", len(result))
return jsonify(result) return jsonify(result)
@ -146,7 +147,7 @@ async def get_single_message(channel_id, message_id):
if not message: if not message:
raise MessageNotFound() raise MessageNotFound()
return jsonify(message) return jsonify(message_view(message))
async def _dm_pre_dispatch(channel_id, peer_id): async def _dm_pre_dispatch(channel_id, peer_id):
@ -196,8 +197,8 @@ async def create_message(
""" """
INSERT INTO messages (id, channel_id, guild_id, author_id, INSERT INTO messages (id, channel_id, guild_id, author_id,
content, tts, mention_everyone, nonce, message_type, content, tts, mention_everyone, nonce, message_type,
embeds) embeds, message_reference, allowed_mentions)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
""", """,
message_id, message_id,
channel_id, channel_id,
@ -209,6 +210,8 @@ async def create_message(
data["nonce"], data["nonce"],
MessageType.DEFAULT.value, MessageType.DEFAULT.value,
data.get("embeds") or [], data.get("embeds") or [],
data.get("message_reference") or None,
data.get("allowed_mentions") or None,
) )
return message_id return message_id
@ -266,6 +269,8 @@ async def _create_message(channel_id):
"embeds": ( "embeds": (
[await fill_embed(j["embed"])] if j.get("embed") is not None else [] [await fill_embed(j["embed"])] if j.get("embed") is not None else []
), ),
"message_reference": j.get("message_reference"),
"allowed_mentions": j.get("allowed_mentions"),
}, },
) )
@ -304,7 +309,7 @@ async def _create_message(channel_id):
payload, guild_id, mentions_everyone, mentions_here payload, guild_id, mentions_everyone, mentions_here
) )
return jsonify(payload) return jsonify(message_view(payload))
@bp.route("/<int:channel_id>/messages/<int:message_id>", methods=["PATCH"]) @bp.route("/<int:channel_id>/messages/<int:message_id>", methods=["PATCH"])
@ -390,7 +395,7 @@ async def edit_message(channel_id, message_id):
if updated: if updated:
await app.dispatcher.channel.dispatch(channel_id, ("MESSAGE_UPDATE", message)) await app.dispatcher.channel.dispatch(channel_id, ("MESSAGE_UPDATE", message))
return jsonify(message) return jsonify(message_view(message))
async def _del_msg_fkeys(message_id: int): async def _del_msg_fkeys(message_id: int):

View File

@ -26,6 +26,7 @@ from litecord.types import timestamp_
from litecord.system_messages import send_sys_message from litecord.system_messages import send_sys_message
from litecord.enums import MessageType, SYS_MESSAGES from litecord.enums import MessageType, SYS_MESSAGES
from litecord.errors import BadRequest from litecord.errors import BadRequest
from litecord.common.messages import message_view
bp = Blueprint("channel_pins", __name__) bp = Blueprint("channel_pins", __name__)
@ -58,7 +59,7 @@ async def get_pins(channel_id):
for message_id in ids: for message_id in ids:
message = await app.storage.get_message(message_id) message = await app.storage.get_message(message_id)
if message is not None: if message is not None:
res.append(message) res.append(message_view(message))
return jsonify(res) return jsonify(res)

View File

@ -36,6 +36,7 @@ from litecord.permissions import base_permissions
from litecord.blueprints.auth import check_password from litecord.blueprints.auth import check_password
from litecord.utils import to_update from litecord.utils import to_update
from litecord.common.messages import message_view
from litecord.common.users import ( from litecord.common.users import (
mass_user_update, mass_user_update,
delete_user, delete_user,
@ -470,7 +471,7 @@ async def _get_mentions():
if gid not in guild_ids: if gid not in guild_ids:
continue continue
res.append(message) res.append(message_view(message))
return jsonify(res) return jsonify(res)

View File

@ -192,3 +192,10 @@ async def msg_guild_text_mentions(
user_id, user_id,
channel_id, channel_id,
) )
def message_view(message_data: dict) -> dict:
# Change message type to 19 if this is a reply to another message
if message_data["message_reference"] and request.discord_api_version > 7:
return {**message_data, **{"type": 19}}
return message_data

View File

@ -128,6 +128,12 @@ class GatewayState:
try: try:
if self.ws: if self.ws:
if (
event_type.startswith("MESSAGE_")
and payload["d"]["message_reference"] is not None
and self.ws.ws_properties.version > 7
):
payload["d"]["type"] = 19
await self.ws.send(payload) await self.ws.send(payload)
except websockets.exceptions.ConnectionClosed as exc: except websockets.exceptions.ConnectionClosed as exc:
log.warning( log.warning(

View File

@ -435,6 +435,25 @@ MESSAGE_CREATE = {
"required": False, "required": False,
"nullable": True, "nullable": True,
}, },
"message_reference": {
"type": "dict",
"required": False,
"nullable": True,
"schema": {
"guild_id": {"type": "string", "required": False},
"channel_id": {"type": "string", "required": True},
"message_id": {"type": "string", "required": True},
},
},
"allowed_mentions": {
"type": "dict",
"required": False,
"nullable": True,
"schema": {
"parse": {"type": "list", "required": True},
"replied_user": {"type": "boolean", "required": True},
},
},
} }

View File

@ -35,7 +35,6 @@ from litecord.blueprints.user.billing import PLAN_ID_TO_TYPE
from litecord.types import timestamp_ from litecord.types import timestamp_
from litecord.utils import pg_set_json from litecord.utils import pg_set_json
log = Logger(__name__) log = Logger(__name__)
@ -1019,7 +1018,7 @@ class Storage:
""" """
SELECT id::text, channel_id::text, author_id, content, SELECT id::text, channel_id::text, author_id, content,
created_at AS timestamp, edited_at AS edited_timestamp, created_at AS timestamp, edited_at AS edited_timestamp,
tts, mention_everyone, nonce, message_type, embeds, flags tts, mention_everyone, nonce, message_type, embeds, flags, message_reference
FROM messages FROM messages
WHERE id = $1 WHERE id = $1
""", """,

View File

@ -28,6 +28,8 @@ from logbook import Logger
from quart.json import JSONEncoder from quart.json import JSONEncoder
from quart import current_app as app from quart import current_app as app
from litecord.common.messages import message_view
from .errors import BadRequest from .errors import BadRequest
log = Logger(__name__) log = Logger(__name__)
@ -226,7 +228,7 @@ async def search_result_from_list(rows: List) -> Dict[str, Any]:
msg = await app.storage.get_message(row["current_id"]) msg = await app.storage.get_message(row["current_id"])
msg["hit"] = True msg["hit"] = True
res.append(before + [msg] + after) res.append(before + [message_view(msg)] + after)
return {"total_results": results, "messages": res, "analytics_id": ""} return {"total_results": results, "messages": res, "analytics_id": ""}

View File

@ -0,0 +1,3 @@
ALTER TABLE messages
ADD COLUMN message_reference jsonb DEFAULT null,
ADD COLUMN allowed_mentions jsonb DEFAULT null;