Skip to content

Commit

Permalink
Merge pull request #1087 from The-Commit-Company/937-system-messages-…
Browse files Browse the repository at this point in the history
…for-addition-removal-of-users-from-a-channel-when-a-admin-is-changed-when-a-user-joins-leaves-the-channel

feat: show system messages when channel members are changed
  • Loading branch information
nikkothari22 authored Oct 11, 2024
2 parents 7890b25 + 000136b commit b873f3f
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const RemoveChannelMemberModal = ({ onClose, member }: RemoveChannelMembe
<Flex direction={'column'} gap='2'>
<ErrorBanner error={errorFetchingChannelMember} />
<ErrorBanner error={error} />
<Text size='1'>This person will no longer have access to the channel and can only rejoin by invitation.</Text>
<Text size='2'>This person will no longer have access to the channel.</Text>
</Flex>

<Flex gap="3" mt="4" justify="end">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ export const MessageItem = ({ message, setDeleteMessage, isHighlighted, onReplyM
data-[state=open]:shadow-sm
transition-colors
px-1
py-2
sm:p-2
py-1.5
rounded-md`, isHighlighted ? 'bg-yellow-50 hover:bg-yellow-50 dark:bg-yellow-300/20 dark:hover:bg-yellow-300/20' : !isDesktop && isHovered ? 'bg-gray-2 dark:bg-gray-3' : '', isEmojiPickerOpen ? 'bg-gray-2 dark:bg-gray-3' : '')}>
<Flex className='gap-2.5 sm:gap-3 items-start'>
<MessageLeftElement message={message} user={user} isActive={isActive} />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Flex, Text } from '@radix-ui/themes'
import { SystemMessage } from '../../../../../../types/Messaging/Message'
import { DateTooltipShort } from './Renderers/DateTooltip'

const SystemMessageBlock = ({ message }: { message: SystemMessage }) => {
return (
<Flex align='center' gap='2' id={`message-${message.name}`} className='pl-1 py-2.5'>
<DateTooltipShort timestamp={message.creation} />
<Text as='span' color='gray' className='pl-1.5' size='1'>{message.text}</Text>
</Flex>

)
}

export default SystemMessageBlock
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ErrorBanner } from '@/components/layout/AlertBanner'
import { ForwardMessageDialog, useForwardMessage } from '../ChatMessage/MessageActions/ForwardMessage'
import AttachFileToDocumentDialog, { useAttachFileToDocument } from '../ChatMessage/MessageActions/AttachFileToDocument'
import { ReactionAnalyticsDialog, useMessageReactionAnalytics } from '../ChatMessage/MessageActions/MessageReactionAnalytics'
import SystemMessageBlock from '../ChatMessage/SystemMessageBlock'

/**
* Anatomy of a message
Expand Down Expand Up @@ -132,6 +133,8 @@ const ChatStream = ({ channelID, replyToMessage, showThreadButton = true }: Prop
return <DateSeparator key={`date-${message.creation}`} id={`date-${message.creation}`} className='p-2 z-10 relative'>
{message.creation}
</DateSeparator>
} else if (message.message_type === 'System') {
return <SystemMessageBlock key={`${message.name}_${message.modified}`} message={message} />
} else {
return <div key={`${message.name}_${message.modified}`} id={`message-${message.name}`}>
<div className="w-full overflow-x-clip overflow-y-visible text-ellipsis animate-fadein">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,9 @@ const useChatStream = (channelID: string, scrollRef: MutableRefObject<HTMLDivEle
}

const currentMessageSender = message.is_bot_message ? message.bot : message.owner
const nextMessageSender = messages[i + 1].is_bot_message ? messages[i + 1].bot : messages[i + 1].owner

const nextMessage = messages[i + 1]
const nextMessageSender = nextMessage.message_type === "System" ? null : nextMessage.is_bot_message ? nextMessage.bot : nextMessage.owner

if (currentMessageSender !== nextMessageSender) {
messagesWithDateSeparators.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,19 @@ def before_insert(self):
self.allow_notifications = 1

def after_delete(self):

member_name = frappe.get_cached_value("Raven User", self.user_id, "full_name")

current_user_name = frappe.get_cached_value("Raven User", frappe.session.user, "full_name")

# If this was the last member of a private channel, archive the channel
if (
frappe.db.count("Raven Channel Member", {"channel_id": self.channel_id}) == 0
and frappe.db.get_value("Raven Channel", self.channel_id, "type") == "Private"
):
frappe.db.set_value("Raven Channel", self.channel_id, "is_archived", 1)

# If this member was the only admin, then make the next oldest member an admin
if (
self.get_admin_count() == 0
and frappe.db.count("Raven Channel Member", {"channel_id": self.channel_id}) > 0
Expand All @@ -61,6 +69,40 @@ def after_delete(self):
)
frappe.db.set_value("Raven Channel Member", first_member.name, "is_admin", 1)

first_member_name = frappe.get_cached_value("Raven User", first_member.user_id, "full_name")

# Add a system message to the channel mentioning the new admin
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": f"{member_name} was removed by {current_user_name} and {first_member_name} is the new admin of this channel.",
}
).insert()
else:
# If the member who left is the current user, then add a system message to the channel mentioning that the user left
if member_name == current_user_name:
# Add a system message to the channel mentioning the member who left
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": f"{member_name} left.",
}
).insert(ignore_permissions=True)
else:
# Add a system message to the channel mentioning the member who left
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": f"{current_user_name} removed {member_name}.",
}
).insert()

def on_trash(self):
# if the leaving member is admin, then the first member becomes new admin
if (
Expand Down Expand Up @@ -119,6 +161,33 @@ def after_insert(self):
if not is_direct_message and self.allow_notifications:
subscribe_user_to_topic(self.channel_id, self.user_id)

if not is_direct_message:

is_thread = self.is_thread()

# Send a system message to the channel mentioning the member who joined
if not is_thread:
member_name = frappe.get_cached_value("Raven User", self.user_id, "full_name")
if self.user_id == frappe.session.user:
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": f"{member_name} joined.",
}
).insert()
else:
current_user_name = frappe.get_cached_value("Raven User", frappe.session.user, "full_name")
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": f"{current_user_name} added {member_name}.",
}
).insert()

def on_update(self):
"""
Check if the notification preference is changed and update the subscription
Expand All @@ -134,9 +203,27 @@ def on_update(self):
else:
unsubscribe_user_to_topic(self.channel_id, self.user_id)

if self.has_value_changed("is_admin") and not self.flags.in_insert and not self.is_thread():
# Send a system message to the channel mentioning the member who became admin
member_name = frappe.get_cached_value("Raven User", self.user_id, "full_name")
text = (
f"{member_name} is now an admin." if self.is_admin else f"{member_name} is no longer an admin."
)
frappe.get_doc(
{
"doctype": "Raven Message",
"channel_id": self.channel_id,
"message_type": "System",
"text": text,
}
).insert()

def get_admin_count(self):
return frappe.db.count("Raven Channel Member", {"channel_id": self.channel_id, "is_admin": 1})

def is_thread(self):
return frappe.get_cached_value("Raven Channel", self.channel_id, "is_thread")


def on_doctype_update():
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"fieldname": "message_type",
"fieldtype": "Select",
"label": "Message Type",
"options": "Text\nImage\nFile\nPoll"
"options": "Text\nImage\nFile\nPoll\nSystem"
},
{
"fieldname": "message_reactions",
Expand Down Expand Up @@ -191,7 +191,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-08-16 16:09:36.292391",
"modified": "2024-10-11 18:42:44.984706",
"modified_by": "Administrator",
"module": "Raven Messaging",
"name": "Raven Message",
Expand Down
4 changes: 2 additions & 2 deletions raven/raven_messaging/doctype/raven_message/raven_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class RavenMessage(Document):
linked_message: DF.Link | None
mentions: DF.Table[RavenMention]
message_reactions: DF.JSON | None
message_type: DF.Literal["Text", "Image", "File", "Poll"]
message_type: DF.Literal["Text", "Image", "File", "Poll", "System"]
poll_id: DF.Link | None
replied_message_details: DF.JSON | None
text: DF.LongText | None
Expand All @@ -55,7 +55,7 @@ class RavenMessage(Document):

def before_validate(self):
try:
if self.text:
if self.text and not self.message_type == "System":
content = html2text(self.text)
# Remove trailing new line characters and white spaces
self.content = content.rstrip()
Expand Down
9 changes: 7 additions & 2 deletions types/Messaging/Message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type Message = FileMessage | TextMessage | ImageMessage | PollMessage
export type Message = FileMessage | TextMessage | ImageMessage | PollMessage | SystemMessage

export interface BaseMessage {
name: string,
Expand All @@ -7,7 +7,7 @@ export interface BaseMessage {
channel_id: string,
creation: string,
modified: string,
message_type: 'Text' | 'File' | 'Image' | 'Poll',
message_type: 'Text' | 'File' | 'Image' | 'Poll' | 'System',
message_reactions?: string | null,
is_continuation: 1 | 0
is_reply: 1 | 0
Expand Down Expand Up @@ -53,6 +53,11 @@ export interface PollMessage extends BaseMessage {
content?: string
}

export interface SystemMessage extends BaseMessage {
message_type: 'System',
text: string,
}

export type DateBlock = {
block_type: 'date',
data: string
Expand Down

0 comments on commit b873f3f

Please sign in to comment.