Skip to content

Commit 10406b2

Browse files
committed
Sending Message
Storing Messages Scrolling functionality Added Favicon
1 parent 5b0808b commit 10406b2

File tree

9 files changed

+160
-29
lines changed

9 files changed

+160
-29
lines changed

core/static/images/favicon.ico

66.1 KB
Binary file not shown.

core/templates/core/base.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{% load static %}
12
<!DOCTYPE html>
23
<html lang="en">
34
<head>
@@ -6,6 +7,13 @@
67
<meta name="viewport" content="width=device-width, initial-scale=1.0">
78
<title>{% block title %}{% endblock %}DjangoChat</title>
89
<script src="https://cdn.tailwindcss.com"></script>
10+
<link rel="shortcut icon" href="{% static 'images/favicon.ico' %}">
11+
<style>
12+
.chat-messages{
13+
height: 400px;
14+
overflow-y: auto;
15+
}
16+
</style>
917
</head>
1018
<body class="bg-teal-600">
1119
<nav class="flex items-center justify-between px-4 py-6 bg-teal-800">

djangochat/settings.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
1-
"""
2-
Django settings for djangochat project.
3-
4-
Generated by 'django-admin startproject' using Django 4.0.
5-
6-
For more information on this file, see
7-
https://docs.djangoproject.com/en/4.0/topics/settings/
8-
9-
For the full list of settings and their values, see
10-
https://docs.djangoproject.com/en/4.0/ref/settings/
11-
"""
12-
1+
import os
132
from pathlib import Path
143

154
# Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -118,6 +107,7 @@
118107

119108
# Static files (CSS, JavaScript, Images)
120109
# https://docs.djangoproject.com/en/4.0/howto/static-files/
110+
STATICFILES_DIRS = [os.path.join(BASE_DIR,'core/static'),]
121111

122112
STATIC_URL = 'static/'
123113
LOGOUT_REDIRECT_URL = '/'

room/consumers.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
22
from channels.generic.websocket import AsyncWebsocketConsumer
33
from asgiref.sync import sync_to_async
4+
from django.contrib.auth.models import User
5+
from .models import Message, Room
46

57
class ChatConsumer(AsyncWebsocketConsumer):
68
async def connect(self):
@@ -18,4 +20,39 @@ async def disconnect(self, close_code):
1820
await self.channel_layer.group_discard(
1921
self.room_group_name,
2022
self.channel_name
21-
)
23+
)
24+
25+
async def receive(self, text_data):
26+
data = json.loads(text_data)
27+
message = data['message']
28+
username = data['username']
29+
room = data['room']
30+
31+
await self.save_message(username, room, message)
32+
33+
await self.channel_layer.group_send(
34+
self.room_group_name,
35+
{
36+
'type': 'chat_message',
37+
'message': message,
38+
'username': username,
39+
'room': room,
40+
}
41+
)
42+
43+
async def chat_message(self, event):
44+
messages = event['message']
45+
username = event['username']
46+
room = event['room']
47+
48+
await self.send(text_data = json.dumps({
49+
'message': messages,
50+
'username': username,
51+
'room': room,
52+
}))
53+
54+
@sync_to_async
55+
def save_message(self, username, room, message):
56+
user = User.objects.get(username=username)
57+
room = Room.objects.get(slug=room)
58+
Message.objects.create(user=user, room=room, content=message)

room/migrations/0002_message.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 4.0.2 on 2022-02-18 07:32
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12+
('room', '0001_initial'),
13+
]
14+
15+
operations = [
16+
migrations.CreateModel(
17+
name='Message',
18+
fields=[
19+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20+
('content', models.TextField()),
21+
('date_added', models.DateTimeField(auto_now_add=True)),
22+
('room', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='room.room')),
23+
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
24+
],
25+
options={
26+
'ordering': ['date_added'],
27+
},
28+
),
29+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 4.0.2 on 2022-02-18 07:51
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12+
('room', '0002_message'),
13+
]
14+
15+
operations = [
16+
migrations.AlterModelOptions(
17+
name='message',
18+
options={'ordering': ('date_added',)},
19+
),
20+
migrations.AlterField(
21+
model_name='message',
22+
name='user',
23+
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to=settings.AUTH_USER_MODEL),
24+
),
25+
]

room/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
from django.contrib.auth.models import User
12
from django.db import models
23

34
class Room(models.Model):
45
name = models.CharField(max_length=255)
56
slug = models.SlugField(unique=True)
7+
8+
class Message(models.Model):
9+
room = models.ForeignKey(Room, related_name='messages', on_delete=models.CASCADE)
10+
user = models.ForeignKey(User, related_name='messages', on_delete=models.CASCADE)
11+
content = models.TextField()
12+
date_added = models.DateTimeField(auto_now_add=True)
13+
14+
class Meta:
15+
ordering = ('date_added',)

room/templates/room/room.html

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,12 @@ <h1 class="text-3xl lg:text-6xl text-white">{{ room.name }}</h1>
99

1010
<div class="lg:w-2/4 mx-4 lg:mx-auto p-4 bg-white rounded-xl">
1111
<div class="chat-messages space-y-3" id="chat-messages">
12-
<div class="p-4 bg-gray-200 rounded-xl">
13-
<p class="font-semibold">Username</p>
14-
<p>This message is a temp message</p>
15-
</div>
16-
17-
<div class="p-4 bg-gray-200 rounded-xl">
18-
<p class="font-semibold">Username</p>
19-
<p>This message is a temp message</p>
20-
</div>
21-
22-
<div class="p-4 bg-gray-200 rounded-xl">
23-
<p class="font-semibold">Username</p>
24-
<p>This message is a temp message</p>
25-
</div>
12+
{% for message in messages %}
13+
<div class="p-4 bg-gray-200 rounded-xl">
14+
<p class="font-semibold">{{ message.user.username }}</p>
15+
<p>{{ message.content }}</p>
16+
</div>
17+
{% endfor %}
2618
</div>
2719
</div>
2820

@@ -38,9 +30,12 @@ <h1 class="text-3xl lg:text-6xl text-white">{{ room.name }}</h1>
3830

3931
{% block scripts %}
4032
{{ room.slug|json_script:"json-roomname"}}
33+
{{ request.user.username|json_script:"json-username"}}
4134

4235
<script>
4336
const roomName = JSON.parse(document.getElementById('json-roomname').textContent);
37+
const userName = JSON.parse(document.getElementById('json-username').textContent);
38+
4439
const chatSocket = new WebSocket(
4540
'ws://'
4641
+ window.location.host
@@ -51,11 +46,47 @@ <h1 class="text-3xl lg:text-6xl text-white">{{ room.name }}</h1>
5146

5247
chatSocket.onmessage = function(e){
5348
console.log('onmessage')
49+
50+
const data = JSON.parse(e.data);
51+
const message = data.message;
52+
53+
if(message){
54+
let html = '<div class="p-4 bg-gray-200 rounded-xl">';
55+
html += '<p class="font-semibold">' + data.username + '</p>';
56+
html += '<p>' + message + '</p></div>';
57+
58+
document.querySelector('#chat-messages').innerHTML += html;
59+
60+
scrollToBottom();
61+
} else{
62+
alert('The message was empty');
63+
}
5464
}
5565

5666
chatSocket.onclose = function(e){
5767
console.log('onclose')
5868
}
69+
70+
document.querySelector('#chat-message-submit').onclick = function(e){
71+
e.preventDefault();
72+
const message = document.querySelector('#chat-message-input').value;
73+
const messageObject = {
74+
'message': message,
75+
'username': userName,
76+
'room': roomName
77+
};
78+
chatSocket.send(JSON.stringify(messageObject));
79+
document.querySelector('#chat-message-input').value = '';
80+
81+
return false;
82+
}
83+
84+
function scrollToBottom(){
85+
const messages = document.querySelector('#chat-messages');
86+
messages.scrollTop = messages.scrollHeight;
87+
}
88+
89+
scrollToBottom();
5990
</script>
6091
{% endblock %}
6192

room/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.contrib.auth.decorators import login_required
22
from django.shortcuts import render
3-
from .models import Room
3+
from .models import Room,Message
44

55
@login_required
66
def rooms(request):
@@ -10,5 +10,6 @@ def rooms(request):
1010
@login_required
1111
def room(request, slug):
1212
room = Room.objects.get(slug=slug)
13-
return render(request, 'room/room.html', {'room': room})
13+
messages = Message.objects.filter(room=room)[0:25]
14+
return render(request, 'room/room.html', {'room': room, 'messages': messages})
1415

0 commit comments

Comments
 (0)