From f811d3ccd9d782470fba7745740c50230d663c46 Mon Sep 17 00:00:00 2001 From: Nikhil Kothari Date: Fri, 12 Apr 2024 17:39:31 +0530 Subject: [PATCH] feat: add option to hide link preview --- .../src/types/RavenMessaging/RavenMessage.ts | 6 +- .../feature/chat/ChatMessage/MessageItem.tsx | 2 +- .../Renderers/TiptapRenderer/Link.tsx | 82 ++-- .../TiptapRenderer/TiptapRenderer.tsx | 4 +- .../src/types/RavenMessaging/RavenMessage.ts | 6 +- raven/api/chat_stream.py | 3 + raven/api/preview_links.py | 11 + .../doctype/raven_message/raven_message.json | 429 +++++++++--------- .../doctype/raven_message/raven_message.py | 3 + types/Messaging/Message.ts | 3 +- 10 files changed, 303 insertions(+), 246 deletions(-) diff --git a/mobile/src/types/RavenMessaging/RavenMessage.ts b/mobile/src/types/RavenMessaging/RavenMessage.ts index a0f2c7e3c..1fc4cbdde 100644 --- a/mobile/src/types/RavenMessaging/RavenMessage.ts +++ b/mobile/src/types/RavenMessaging/RavenMessage.ts @@ -26,7 +26,7 @@ export interface RavenMessage{ /** Replied Message Details : JSON */ replied_message_details?: any /** Message Type : Select */ - message_type?: "Text" | "Image" | "File" + message_type?: "Text" | "Image" | "File" | "Poll" /** Content : Long Text */ content?: string /** File : Attach */ @@ -49,8 +49,12 @@ export interface RavenMessage{ is_edited?: 0 | 1 /** Mentions : Table - Raven Mention */ mentions?: RavenMention[] + /** Poll ID : Link - Raven Poll */ + poll_id?: string /** Is Bot Message : Check */ is_bot_message?: 0 | 1 /** Bot : Link - Raven User */ bot?: string + /** Hide link preview : Check */ + hide_link_preview?: 0 | 1 } \ No newline at end of file diff --git a/raven-app/src/components/feature/chat/ChatMessage/MessageItem.tsx b/raven-app/src/components/feature/chat/ChatMessage/MessageItem.tsx index cabef7d28..890f3aace 100644 --- a/raven-app/src/components/feature/chat/ChatMessage/MessageItem.tsx +++ b/raven-app/src/components/feature/chat/ChatMessage/MessageItem.tsx @@ -242,7 +242,7 @@ export const MessageContent = ({ message, user, ...props }: MessageContentProps) {message.text ? : null} + }} user={user} showLinkPreview={message.hide_link_preview ? false : true} /> : null} {message.message_type === 'Image' && } {message.message_type === 'File' && } {message.message_type === 'Poll' && } diff --git a/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/Link.tsx b/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/Link.tsx index e6bcb483c..35c3379fa 100644 --- a/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/Link.tsx +++ b/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/Link.tsx @@ -1,9 +1,9 @@ -import { Skeleton } from '@/components/common/Skeleton'; -import { Box, Flex, Text } from '@radix-ui/themes'; +import { Box, Flex, IconButton, Text, Tooltip } from '@radix-ui/themes'; import TiptapLink from '@tiptap/extension-link' import { mergeAttributes, useCurrentEditor } from "@tiptap/react"; -import { useFrappeGetCall } from 'frappe-react-sdk'; +import { useFrappeGetCall, useFrappePostCall } from 'frappe-react-sdk'; import { memo, useMemo } from 'react'; +import { BiX } from 'react-icons/bi'; export const CustomLink = TiptapLink.extend({ renderHTML({ HTMLAttributes }) { @@ -19,7 +19,6 @@ export const CustomLink = TiptapLink.extend({ protocols: ['mailto', 'https', 'http'], openOnClick: false, }) - export type LinkPreviewDetails = { title: string, description: string, @@ -29,7 +28,7 @@ export type LinkPreviewDetails = { site_name: string } -export const LinkPreview = memo(({ isScrolling }: { isScrolling?: boolean }) => { +export const LinkPreview = memo(({ messageID }: { messageID: string }) => { const { editor } = useCurrentEditor() @@ -78,50 +77,75 @@ export const LinkPreview = memo(({ isScrolling }: { isScrolling?: boolean }) => // const href = editor?.getAttributes('link').href - const { data, isLoading } = useFrappeGetCall<{ message: LinkPreviewDetails[] }>('raven.api.preview_links.get_preview_link', { + const { data } = useFrappeGetCall<{ message: LinkPreviewDetails[] }>('raven.api.preview_links.get_preview_link', { urls: JSON.stringify([href]) - }, href ? undefined : null, { + }, href ? `link_preview_${href}` : null, { revalidateIfStale: false, revalidateOnFocus: false, revalidateOnReconnect: false, shouldRetryOnError: false, }) + const { call } = useFrappePostCall('raven.api.preview_links.hide_link_preview') + + const hidePreviewLink = () => { + call({ + message_id: messageID + }) + } + if (!href) return null const linkPreview = data?.message?.[0] - return - - {linkPreview ? linkPreview.site_name && linkPreview.description ? - {(linkPreview.absolute_image || linkPreview.image) && - + return + {linkPreview ? linkPreview.site_name && linkPreview.description ? + {(linkPreview.absolute_image || linkPreview.image) && + + {/* Absolute positioned skeleton loader */} - - + + - {linkPreview.title} - - } - - - {linkPreview.title} - {linkPreview.site_name} + + } + + + + + + {linkPreview.title} + {linkPreview.site_name} + + {linkPreview.description} - {linkPreview.description} - - : null : - - null} - - + +
+ + + + + +
+ + : null : + + null + } + }) \ No newline at end of file diff --git a/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/TiptapRenderer.tsx b/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/TiptapRenderer.tsx index c2bfe467a..6f6ff3de8 100644 --- a/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/TiptapRenderer.tsx +++ b/raven-app/src/components/feature/chat/ChatMessage/Renderers/TiptapRenderer/TiptapRenderer.tsx @@ -44,7 +44,7 @@ export const TiptapRenderer = ({ message, user, isScrolling = false, isTruncated editable: false, editorProps: { attributes: { - class: isTruncated ? 'tiptap-renderer line-clamp-3' : 'tiptap-renderer' + class: isTruncated ? 'tiptap-renderer line-clamp-3' : 'tiptap-renderer' } }, enableCoreExtensions: true, @@ -97,7 +97,7 @@ export const TiptapRenderer = ({ message, user, isScrolling = false, isTruncated contentEditable={false} editor={editor} readOnly /> - {showLinkPreview && } + {showLinkPreview && } ) diff --git a/raven-app/src/types/RavenMessaging/RavenMessage.ts b/raven-app/src/types/RavenMessaging/RavenMessage.ts index a0f2c7e3c..1fc4cbdde 100644 --- a/raven-app/src/types/RavenMessaging/RavenMessage.ts +++ b/raven-app/src/types/RavenMessaging/RavenMessage.ts @@ -26,7 +26,7 @@ export interface RavenMessage{ /** Replied Message Details : JSON */ replied_message_details?: any /** Message Type : Select */ - message_type?: "Text" | "Image" | "File" + message_type?: "Text" | "Image" | "File" | "Poll" /** Content : Long Text */ content?: string /** File : Attach */ @@ -49,8 +49,12 @@ export interface RavenMessage{ is_edited?: 0 | 1 /** Mentions : Table - Raven Mention */ mentions?: RavenMention[] + /** Poll ID : Link - Raven Poll */ + poll_id?: string /** Is Bot Message : Check */ is_bot_message?: 0 | 1 /** Bot : Link - Raven User */ bot?: string + /** Hide link preview : Check */ + hide_link_preview?: 0 | 1 } \ No newline at end of file diff --git a/raven/api/chat_stream.py b/raven/api/chat_stream.py index ecf37e363..7399af92c 100644 --- a/raven/api/chat_stream.py +++ b/raven/api/chat_stream.py @@ -51,6 +51,7 @@ def get_messages(channel_id: str, limit: int = 20, base_message: str | None = No message.poll_id, message.is_bot_message, message.bot, + message.hide_link_preview, ) .where(message.channel_id == channel_id) .orderby(message.creation, order=Order.desc) @@ -155,6 +156,7 @@ def fetch_older_messages( message.poll_id, message.is_bot_message, message.bot, + message.hide_link_preview, ) .where(message.channel_id == channel_id) .where( @@ -263,6 +265,7 @@ def fetch_newer_messages( message.poll_id, message.is_bot_message, message.bot, + message.hide_link_preview, ) .where(message.channel_id == channel_id) .where(condition) diff --git a/raven/api/preview_links.py b/raven/api/preview_links.py index 984f7d91b..531833525 100644 --- a/raven/api/preview_links.py +++ b/raven/api/preview_links.py @@ -58,3 +58,14 @@ def get_preview_link(urls): message_links.append(data) return message_links + + +@frappe.whitelist(methods=["POST"]) +def hide_link_preview(message_id: str): + """ + Remove the preview from the message + """ + message = frappe.get_doc("Raven Message", message_id) + message.flags.ignore_permissions = True + message.hide_link_preview = 1 + message.save() diff --git a/raven/raven_messaging/doctype/raven_message/raven_message.json b/raven/raven_messaging/doctype/raven_message/raven_message.json index 7d3fb1b74..8f066b294 100644 --- a/raven/raven_messaging/doctype/raven_message/raven_message.json +++ b/raven/raven_messaging/doctype/raven_message/raven_message.json @@ -1,213 +1,220 @@ { - "actions": [], - "allow_rename": 1, - "autoname": "hash", - "creation": "2023-02-12 17:29:25.498988", - "default_view": "List", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "channel_id", - "text", - "json", - "message_reactions", - "is_reply", - "linked_message", - "replied_message_details", - "column_break_wvje", - "message_type", - "content", - "file", - "image_width", - "image_height", - "file_thumbnail", - "thumbnail_width", - "thumbnail_height", - "link_doctype", - "link_document", - "is_edited", - "mentions", - "poll_id", - "is_bot_message", - "bot" - ], - "fields": [ - { - "fieldname": "channel_id", - "fieldtype": "Link", - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Channel ID", - "options": "Raven Channel", - "reqd": 1, - "search_index": 1 - }, - { - "fieldname": "text", - "fieldtype": "Long Text", - "label": "Text" - }, - { - "fieldname": "json", - "fieldtype": "JSON", - "label": "JSON" - }, - { - "fieldname": "file", - "fieldtype": "Attach", - "label": "File" - }, - { - "fieldname": "message_type", - "fieldtype": "Select", - "label": "Message Type", - "options": "Text\nImage\nFile\nPoll" - }, - { - "fieldname": "message_reactions", - "fieldtype": "JSON", - "label": "Message Reactions" - }, - { - "default": "0", - "fieldname": "is_reply", - "fieldtype": "Check", - "label": "Is Reply" - }, - { - "fieldname": "linked_message", - "fieldtype": "Link", - "label": "Replied Message ID", - "options": "Raven Message" - }, - { - "fieldname": "file_thumbnail", - "fieldtype": "Attach", - "label": "File Thumbnail" - }, - { - "fieldname": "image_width", - "fieldtype": "Data", - "label": "Image Width" - }, - { - "fieldname": "image_height", - "fieldtype": "Data", - "label": "Image Height" - }, - { - "fieldname": "thumbnail_width", - "fieldtype": "Data", - "label": "Thumbnail Width" - }, - { - "fieldname": "thumbnail_height", - "fieldtype": "Data", - "label": "Thumbnail Height" - }, - { - "fieldname": "link_doctype", - "fieldtype": "Link", - "label": "Link Doctype", - "options": "DocType" - }, - { - "fieldname": "link_document", - "fieldtype": "Dynamic Link", - "label": "Link Document", - "options": "link_doctype" - }, - { - "default": "0", - "fieldname": "is_bot_message", - "fieldtype": "Check", - "label": "Is Bot Message" - }, - { - "depends_on": "eval: doc.is_bot_message == 1", - "fieldname": "bot", - "fieldtype": "Link", - "label": "Bot", - "mandatory_depends_on": "eval: doc.is_bot_message == 1", - "options": "Raven User" - }, - { - "fieldname": "content", - "fieldtype": "Long Text", - "label": "Content", - "read_only": 1 - }, - { - "default": "0", - "fieldname": "is_edited", - "fieldtype": "Check", - "label": "Is Edited" - }, - { - "fieldname": "column_break_wvje", - "fieldtype": "Column Break" - }, - { - "fieldname": "replied_message_details", - "fieldtype": "JSON", - "label": "Replied Message Details" - }, - { - "fieldname": "mentions", - "fieldtype": "Table", - "label": "Mentions", - "options": "Raven Mention" - }, - { - "fieldname": "poll_id", - "fieldtype": "Link", - "label": "Poll ID", - "options": "Raven Poll", - "unique": 1 - } - ], - "index_web_pages_for_search": 1, - "links": [], - "modified": "2024-03-30 15:32:15.182210", - "modified_by": "Administrator", - "module": "Raven Messaging", - "name": "Raven Message", - "naming_rule": "Random", - "owner": "Administrator", - "permissions": [ - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "select": 1, - "share": 1, - "write": 1 - }, - { - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 1, - "print": 1, - "report": 1, - "role": "Raven User", - "share": 1, - "write": 1 - }, - { - "read": 1, - "role": "Raven User" - } - ], - "search_fields": "text", - "sort_field": "modified", - "sort_order": "DESC", - "states": [] + "actions": [], + "allow_rename": 1, + "autoname": "hash", + "creation": "2023-02-12 17:29:25.498988", + "default_view": "List", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "channel_id", + "text", + "json", + "message_reactions", + "is_reply", + "linked_message", + "replied_message_details", + "column_break_wvje", + "message_type", + "content", + "file", + "image_width", + "image_height", + "file_thumbnail", + "thumbnail_width", + "thumbnail_height", + "link_doctype", + "link_document", + "is_edited", + "mentions", + "poll_id", + "is_bot_message", + "bot", + "hide_link_preview" + ], + "fields": [ + { + "fieldname": "channel_id", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Channel ID", + "options": "Raven Channel", + "reqd": 1, + "search_index": 1 + }, + { + "fieldname": "text", + "fieldtype": "Long Text", + "label": "Text" + }, + { + "fieldname": "json", + "fieldtype": "JSON", + "label": "JSON" + }, + { + "fieldname": "file", + "fieldtype": "Attach", + "label": "File" + }, + { + "fieldname": "message_type", + "fieldtype": "Select", + "label": "Message Type", + "options": "Text\nImage\nFile\nPoll" + }, + { + "fieldname": "message_reactions", + "fieldtype": "JSON", + "label": "Message Reactions" + }, + { + "default": "0", + "fieldname": "is_reply", + "fieldtype": "Check", + "label": "Is Reply" + }, + { + "fieldname": "linked_message", + "fieldtype": "Link", + "label": "Replied Message ID", + "options": "Raven Message" + }, + { + "fieldname": "file_thumbnail", + "fieldtype": "Attach", + "label": "File Thumbnail" + }, + { + "fieldname": "image_width", + "fieldtype": "Data", + "label": "Image Width" + }, + { + "fieldname": "image_height", + "fieldtype": "Data", + "label": "Image Height" + }, + { + "fieldname": "thumbnail_width", + "fieldtype": "Data", + "label": "Thumbnail Width" + }, + { + "fieldname": "thumbnail_height", + "fieldtype": "Data", + "label": "Thumbnail Height" + }, + { + "fieldname": "link_doctype", + "fieldtype": "Link", + "label": "Link Doctype", + "options": "DocType" + }, + { + "fieldname": "link_document", + "fieldtype": "Dynamic Link", + "label": "Link Document", + "options": "link_doctype" + }, + { + "default": "0", + "fieldname": "is_bot_message", + "fieldtype": "Check", + "label": "Is Bot Message" + }, + { + "depends_on": "eval: doc.is_bot_message == 1", + "fieldname": "bot", + "fieldtype": "Link", + "label": "Bot", + "mandatory_depends_on": "eval: doc.is_bot_message == 1", + "options": "Raven User" + }, + { + "fieldname": "content", + "fieldtype": "Long Text", + "label": "Content", + "read_only": 1 + }, + { + "default": "0", + "fieldname": "is_edited", + "fieldtype": "Check", + "label": "Is Edited" + }, + { + "fieldname": "column_break_wvje", + "fieldtype": "Column Break" + }, + { + "fieldname": "replied_message_details", + "fieldtype": "JSON", + "label": "Replied Message Details" + }, + { + "fieldname": "mentions", + "fieldtype": "Table", + "label": "Mentions", + "options": "Raven Mention" + }, + { + "fieldname": "poll_id", + "fieldtype": "Link", + "label": "Poll ID", + "options": "Raven Poll", + "unique": 1 + }, + { + "default": "0", + "fieldname": "hide_link_preview", + "fieldtype": "Check", + "label": "Hide link preview" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-04-12 16:30:21.689774", + "modified_by": "Administrator", + "module": "Raven Messaging", + "name": "Raven Message", + "naming_rule": "Random", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "select": 1, + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 1, + "print": 1, + "report": 1, + "role": "Raven User", + "share": 1, + "write": 1 + }, + { + "read": 1, + "role": "Raven User" + } + ], + "search_fields": "text", + "sort_field": "modified", + "sort_order": "DESC", + "states": [] } \ No newline at end of file diff --git a/raven/raven_messaging/doctype/raven_message/raven_message.py b/raven/raven_messaging/doctype/raven_message/raven_message.py index 6bf8ef405..aa175f1fd 100644 --- a/raven/raven_messaging/doctype/raven_message/raven_message.py +++ b/raven/raven_messaging/doctype/raven_message/raven_message.py @@ -29,6 +29,7 @@ class RavenMessage(Document): content: DF.LongText | None file: DF.Attach | None file_thumbnail: DF.Attach | None + hide_link_preview: DF.Check image_height: DF.Data | None image_width: DF.Data | None is_bot_message: DF.Check @@ -370,6 +371,7 @@ def on_update(self): "message_reactions": self.message_reactions, "is_bot_message": self.is_bot_message, "bot": self.bot, + "hide_link_preview": self.hide_link_preview, }, }, doctype="Raven Channel", @@ -419,6 +421,7 @@ def on_update(self): "name": self.name, "is_bot_message": self.is_bot_message, "bot": self.bot, + "hide_link_preview": self.hide_link_preview, }, }, doctype="Raven Channel", diff --git a/types/Messaging/Message.ts b/types/Messaging/Message.ts index 9c844df1f..b76ff7960 100644 --- a/types/Messaging/Message.ts +++ b/types/Messaging/Message.ts @@ -19,7 +19,8 @@ export interface BaseMessage { replied_message_details?: string, poll_id?: string is_bot_message?: 1 | 0, - bot?: string + bot?: string, + hide_link_preview?: 1 | 0, } export interface FileMessage extends BaseMessage {