Skip to content

Commit

Permalink
Merge pull request #648 from The-Commit-Company/502-rav-11-add-suppor…
Browse files Browse the repository at this point in the history
…t-for-chat-in-desk-interface

feat: chat dialog in desk interface
  • Loading branch information
nikkothari22 authored Jan 28, 2024
2 parents 89d843f + 6152ab4 commit f4f977f
Show file tree
Hide file tree
Showing 51 changed files with 3,297 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EditorContent, EditorContext, EditorProvider, Extension, ReactRenderer, useEditor } from '@tiptap/react'
import { EditorContent, EditorContext, useEditor } from '@tiptap/react'
import { Message, TextMessage } from '../../../../../../../../types/Messaging/Message'
import { UserFields } from '@/utils/users/UserListProvider'
import { BoxProps } from '@radix-ui/themes/dist/cjs/components/box'
Expand Down
50 changes: 35 additions & 15 deletions raven-app/src/utils/layout/FileExtIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from 'react'
import { IconBaseProps } from 'react-icons'
import { FaRegFilePdf, FaRegFileVideo, FaRegFileWord, FaRegFileExcel, FaRegFileAudio, FaRegFilePowerpoint, FaRegFileImage, FaRegFileAlt } from 'react-icons/fa'

Expand All @@ -17,25 +18,44 @@ export const audioExt = ['mp3', 'wav', 'ogg', 'flac']
interface FileExtensionIconProps extends IconBaseProps {
ext: string
}

const getFileType = (ext: string) => {
switch (ext) {
case 'pdf': return 'pdf'
case 'doc': return 'word'
case 'docx': return 'word'
case 'xls': return 'excel'
case 'xlsx': return 'excel'
case 'ppt': return 'powerpoint'
case 'pptx': return 'powerpoint'
case 'mp3': return 'audio'
case 'wav': return 'audio'
case 'ogg': return 'audio'
case 'flac': return 'audio'
case 'mp4': return 'video'
case 'mkv': return 'video'
case 'webm': return 'video'
case 'avi': return 'video'
case 'mov': return 'video'
case 'jpeg': return 'image'
case 'jpg': return 'image'
case 'png': return 'image'
default: return 'file'
}
}
export const FileExtensionIcon = ({ ext, ...props }: FileExtensionIconProps) => {

const isExcel = excelExt.includes(ext)
const isImage = imageExt.includes(ext)
const isWord = wordExt.includes(ext)
const isPdf = ext === "pdf"
const isVideo = videoExt.includes(ext)
const isAudio = audioExt.includes(ext)
const isPpt = pptExt.includes(ext)
const fileType = useMemo(() => getFileType(ext), [ext])

return <span>
{isExcel && <FaRegFileExcel size='20' {...props} />}
{isImage && <FaRegFileImage size='20' {...props} />}
{isWord && <FaRegFileWord size='20' {...props} />}
{isPdf && <FaRegFilePdf size='20' {...props} />}
{isVideo && <FaRegFileVideo size='20' {...props} />}
{isAudio && <FaRegFileAudio size='20' {...props} />}
{isPpt && <FaRegFilePowerpoint size='20' {...props} />}
{!isExcel && !isImage && !isWord && !isPdf && !isAudio && !isPpt && !isVideo && <FaRegFileAlt width='20' {...props} />}
{fileType === 'excel' && <FaRegFileExcel size='20' {...props} />}
{fileType === 'image' && <FaRegFileImage size='20' {...props} />}
{fileType === 'word' && <FaRegFileWord size='20' {...props} />}
{fileType === 'pdf' && <FaRegFilePdf size='20' {...props} />}
{fileType === 'video' && <FaRegFileVideo size='20' {...props} />}
{fileType === 'audio' && <FaRegFileAudio size='20' {...props} />}
{fileType === 'powerpoint' && <FaRegFilePowerpoint size='20' {...props} />}
{fileType === 'file' && <FaRegFileAlt width='20' {...props} />}
</span>

}
91 changes: 91 additions & 0 deletions raven/api/message_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import frappe


@frappe.whitelist()
def get_messages(channel_id: str, base_message=None, before_message=None, after_message=None):

# Check if the user has permission to view the channel
check_permission(channel_id)

messages = get_message_list(channel_id, base_message=base_message, before_message=before_message, after_message=after_message)

# Track the visit of the user to the channel if the messages fetched are latest
if not base_message:
track_visit(channel_id, True)

#TODO: Also send a pagination cursor to the client - base64 encoded message_id + timestamp


return messages

def get_message_list(channel_id: str, base_message=None, before_message=None, after_message=None):
'''
Get a list of messages in the channel.
If no base_message is provided, get the latest messages
If base_message is provided, get the 10 messages before the base_message and 10 messages after the base_message
'''
# TODO: Change to 50
limit = 20
if base_message:
# TODO:
return []
else:
filters = {'channel_id': channel_id}
if before_message:
filters['name'] = ['<', before_message]
elif after_message:
filters['name'] = ['>', after_message]
messages = frappe.db.get_all('Raven Message',
filters=filters,
fields=['name', 'owner', 'creation', 'text',
'file', 'message_type', 'message_reactions', 'is_reply', 'linked_message', '_liked_by', 'channel_id', 'thumbnail_width', 'thumbnail_height', 'file_thumbnail'],
order_by='creation desc, name asc',
page_length=limit,
)

has_old_messages = len(messages) == limit

return {
'messages': messages,
'has_old_messages': has_old_messages
}

def check_permission(channel_id):
'''
Check if the user has permission to view the messages in the channel
'''
if frappe.db.get_value('Raven Channel', channel_id, 'type') == 'Private':
if frappe.db.exists("Raven Channel Member", {"channel_id": channel_id, "user_id": frappe.session.user}):
pass
elif frappe.session.user == "Administrator":
pass
else:
frappe.throw(
"You don't have permission to view this channel", frappe.PermissionError)


def track_visit(channel_id: str, commit=False):
'''
Track the last visit of the user to the channel.
If the user is not a member of the channel, create a new member record
'''
doc = frappe.db.get_value("Raven Channel Member", {
"channel_id": channel_id, "user_id": frappe.session.user}, "name")
if doc:
frappe.db.set_value("Raven Channel Member", doc,
"last_visit", frappe.utils.now())
elif frappe.db.get_value('Raven Channel', channel_id, 'type') == 'Open':
frappe.get_doc({
"doctype": "Raven Channel Member",
"channel_id": channel_id,
"user_id": frappe.session.user,
"last_visit": frappe.utils.now()
}).insert()
frappe.publish_realtime(
'raven:unread_channel_count_updated', {
'channel_id': channel_id,
'play_sound': False
}, user=frappe.session.user, after_commit=True)
# Need to commit the changes to the database if the request is a GET request
if commit:
frappe.db.commit()
3 changes: 2 additions & 1 deletion raven/api/raven_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def track_visit(channel_id, commit=False):
frappe.publish_realtime(
'raven:unread_channel_count_updated', {
'channel_id': channel_id,
}, after_commit=True)
'play_sound': False
}, user=frappe.session.user, after_commit=True)
# Need to commit the changes to the database if the request is a GET request
if commit:
frappe.db.commit()
Expand Down
4 changes: 4 additions & 0 deletions raven/boot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import frappe

def boot_session(bootinfo):
bootinfo.show_raven_chat_on_desk = frappe.db.get_single_value("Raven Settings", "show_raven_on_desk")
7 changes: 7 additions & 0 deletions raven/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@
# ------------------

# include js, css files in header of desk.html
app_include_css = "raven.bundle.css"
# app_include_css = "/assets/raven/css/raven.css"
# app_include_js = "/assets/raven/js/raven.js" ]
app_include_js = "raven.bundle.js"


sounds = [
{"name": "raven_notification", "src": "/assets/raven/sounds/raven_notification.mp3", "volume": 0.2},
]

extend_bootinfo = "raven.boot.boot_session"
# include js, css files in header of web template
# web_include_css = "/assets/raven/css/raven.css"
# web_include_js = "/assets/raven/js/raven.js"
Expand Down
Loading

0 comments on commit f4f977f

Please sign in to comment.