Skip to content

Commit

Permalink
Minor features, UI improvements
Browse files Browse the repository at this point in the history
1. On click, messages now show when they were sent last, in the django app's set timezone. Closes #27
2. UI improvements like shaping the message bubbles better and adding a circle to indicate a username's first letter (design inspirations from Google's Messaging web app)
3. ChatConsumer is now an AsyncJsonWebSocketConsumer; it serves and receives JSON data by default
4. Refactored websocket code into its own file
  • Loading branch information
ishtiaque06 committed May 24, 2019
1 parent 7163692 commit 31e9bfa
Show file tree
Hide file tree
Showing 12 changed files with 508 additions and 271 deletions.
2 changes: 1 addition & 1 deletion chatter/settings.py
Expand Up @@ -159,7 +159,7 @@

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
TIME_ZONE = "America/New_York"

USE_I18N = True

Expand Down
113 changes: 55 additions & 58 deletions django_chatter/consumers.py
Expand Up @@ -3,13 +3,14 @@
--------------------------------------------------------------------------AI'''
from django.contrib.auth import get_user_model
from django.db import connection
from django.utils.timezone import now
from django.utils.timezone import now, get_default_timezone_name
from django.utils import dateformat


'''AI--------------------------------------------------------------------------
Third-party Imports
--------------------------------------------------------------------------AI'''
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from channels.db import database_sync_to_async
import bleach

Expand All @@ -25,6 +26,7 @@
--------------------------------------------------------------------------AI'''
import json
from uuid import UUID
import pytz


'''
Expand Down Expand Up @@ -72,16 +74,18 @@ def save_message(room, sender, text, multitenant=False, schema_name=None):
new_message.save()
room.date_modified = new_message.date_modified
room.save()
return new_message.date_created
else:
new_message = Message(room=room, sender=sender, text=text)
new_message.save()
new_message.recipients.add(sender)
new_message.save()
room.date_modified = new_message.date_modified
room.save()
return new_message.date_created


class ChatConsumer(AsyncWebsocketConsumer):
class ChatConsumer(AsyncJsonWebsocketConsumer):

'''
AI-------------------------------------------------------------------
Expand Down Expand Up @@ -134,64 +138,57 @@ async def disconnect(self, close_code):
self.channel_name
)

async def receive(self, text_data):
async def receive_json(self, data):
username = self.user.username

text_data_json = json.loads(text_data)
message = text_data_json['message']
room_id = text_data_json['room_id']
message_type = data['type']
if message_type == "text":
message = data['message']
room_id = data['room_id']

# Clean code off message if message contains code
self.message_safe = bleach.clean(message)
message_harmful = (self.message_safe != message)
# Clean code off message if message contains code
self.message_safe = bleach.clean(message)
message_harmful = (self.message_safe != message)

try:
# room = await self.get_room(room_id)
room_group_name = 'chat_%s' % room_id
except Exception as ex:
raise ex
await self.disconnect(500)

await save_message(self.room,
self.user,
self.message_safe,
self.multitenant,
self.schema_name
)

if message_harmful:
warning = "Your message has been escaped due to security reasons.\
For more information, see \
https://en.wikipedia.org/wiki/Cross-site_scripting"
else:
warning = ''

await self.channel_layer.group_send(
room_group_name,
{
'type': 'send_to_websocket',
'message': self.message_safe,
'warning': warning,
'sender': username,
'room_id': room_id,
}
)
try:
# room = await self.get_room(room_id)
room_group_name = 'chat_%s' % room_id
except Exception as ex:
raise ex
await self.disconnect(500)

time = await save_message(self.room,
self.user,
self.message_safe,
self.multitenant,
self.schema_name
)

zone = pytz.timezone(get_default_timezone_name())
time = time.astimezone(tz=zone)
formatted = dateformat.DateFormat(time)
time = formatted.format('M d, Y h:i a')


if message_harmful:
warning = "Your message has been escaped due to security reasons.\
For more information, see \
https://en.wikipedia.org/wiki/Cross-site_scripting"
else:
warning = ''

await self.channel_layer.group_send(
room_group_name,
{
'type': 'send_to_websocket',
'message_type': 'text',
'message': self.message_safe,
'date_created': time,
'warning': warning,
'sender': username,
'room_id': room_id,
}
)

async def send_to_websocket(self, event):
message = event['message']
warning = event['warning']
sender = event['sender']
room_id = event['room_id']
if warning == '':
await self.send(text_data=(json.dumps({
'message': message,
'sender': sender,
'room_id': room_id,
})))
else:
await self.send(text_data=(json.dumps({
'message': message,
'sender': sender,
'warning': warning,
'room_id': room_id
})))
await self.send_json(event)
3 changes: 3 additions & 0 deletions django_chatter/models.py
Expand Up @@ -9,6 +9,7 @@ class UserProfile(models.Model):
on_delete=models.CASCADE, related_name='profile')
last_visit = models.DateTimeField()


# This model is used to give date and time when a message was created/modified.
class DateTimeModel(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
Expand All @@ -17,6 +18,7 @@ class DateTimeModel(models.Model):
class Meta:
abstract = True


class Room(DateTimeModel):
id = models.UUIDField(primary_key=True,
default=uuid.uuid4,
Expand All @@ -31,6 +33,7 @@ def __str__(self):

return ", ".join(members_list)


class Message(DateTimeModel):
sender = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name='sender')
Expand Down

0 comments on commit 31e9bfa

Please sign in to comment.