├── README.md ├── db.sqlite3 ├── manage.py ├── mychat ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── settings.cpython-39.pyc │ ├── urls.cpython-39.pyc │ └── wsgi.cpython-39.pyc ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── mychatapp ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── admin.cpython-39.pyc │ ├── apps.cpython-39.pyc │ ├── forms.cpython-39.pyc │ ├── models.cpython-39.pyc │ ├── urls.cpython-39.pyc │ └── views.cpython-39.pyc ├── admin.py ├── apps.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_friend_profile_friends.py │ ├── 0003_chatmessage.py │ ├── __init__.py │ └── __pycache__ │ │ ├── 0001_initial.cpython-39.pyc │ │ ├── 0002_friend_profile_friends.cpython-39.pyc │ │ ├── 0003_chatmessage.cpython-39.pyc │ │ └── __init__.cpython-39.pyc ├── models.py ├── static │ └── css │ │ └── style.css ├── templates │ └── mychatapp │ │ ├── base.html │ │ ├── detail.html │ │ └── index.html ├── tests.py ├── urls.py └── views.py └── static └── img ├── b1.jpg ├── b1_GnbrNBB.jpg ├── b2.jpg ├── b3.jpg ├── pic_1.png ├── pic_1_O4zdvrg.png ├── pic_2.png ├── screenshot_1.png ├── screenshot_2.png └── screenshot_3.png /README.md: -------------------------------------------------------------------------------- 1 | # Real Time Chat App with Django. 2 | 3 | 4 |
5 | 6 | Checkout how the Real Time Chat App works - [view demo](https://www.youtube.com/watch?v=JWasK72rXsY) 7 | 8 | 9 | 10 | ## Overview of the Chat App 11 | 12 | The main focus of this chat application is to enable users chat with one another, therefore I didn't add an authentication system, users are created and logged-in from the Django admin.

Before you access the index page of this application, a user must be logged-in, else there will be an AnonymousUserError from Django.

Remember creating of users, profiles and friends all done in the Django admin. 13 | 14 | 15 | 16 | 17 | ## Screenshots 18 | 19 | Index Page: 20 | 21 | ![alt text](https://github.com/ClintonCode20/chatapp/blob/main/static/img/screenshot_1.png) 22 | 23 | 24 | 25 | Detail Page: 26 | 27 | ![alt text](https://github.com/ClintonCode20/chatapp/blob/main/static/img/screenshot_3.png) 28 | 29 | 30 | 31 | 32 | Detail Page: 33 | 34 | ![alt text](https://github.com/ClintonCode20/chatapp/blob/main/static/img/screenshot_2.png) 35 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/db.sqlite3 -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mychat.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /mychat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychat/__init__.py -------------------------------------------------------------------------------- /mychat/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychat/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /mychat/__pycache__/settings.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychat/__pycache__/settings.cpython-39.pyc -------------------------------------------------------------------------------- /mychat/__pycache__/urls.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychat/__pycache__/urls.cpython-39.pyc -------------------------------------------------------------------------------- /mychat/__pycache__/wsgi.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychat/__pycache__/wsgi.cpython-39.pyc -------------------------------------------------------------------------------- /mychat/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for mychat project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mychat.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /mychat/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for mychat project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.0.4. 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 | 13 | from pathlib import Path 14 | 15 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 16 | BASE_DIR = Path(__file__).resolve().parent.parent 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'django-insecure-lcv2ee6#vr@@kquoa4_z!v5me=t1vre(@f@zhohbyj=b&8$d18' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'mychatapp' 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'mychat.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'mychat.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/4.0/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': BASE_DIR / 'db.sqlite3', 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/4.0/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_TZ = True 114 | 115 | 116 | # Static files (CSS, JavaScript, Images) 117 | # https://docs.djangoproject.com/en/4.0/howto/static-files/ 118 | 119 | STATIC_URL = 'static/' 120 | STATICFILES_DIRS = [BASE_DIR/'static'] 121 | 122 | MEDIA_URL = 'media/' 123 | 124 | MEDIA_ROOT = BASE_DIR/'static' 125 | 126 | # Default primary key field type 127 | # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field 128 | 129 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 130 | -------------------------------------------------------------------------------- /mychat/urls.py: -------------------------------------------------------------------------------- 1 | """mychat URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | from django.conf import settings 19 | from django.conf.urls.static import static 20 | 21 | urlpatterns = [ 22 | path('admin/', admin.site.urls), 23 | path('chats/', include("mychatapp.urls")) 24 | ] 25 | 26 | 27 | urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) -------------------------------------------------------------------------------- /mychat/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mychat project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mychat.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /mychatapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__init__.py -------------------------------------------------------------------------------- /mychatapp/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/admin.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/admin.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/apps.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/apps.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/forms.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/forms.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/models.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/models.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/urls.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/urls.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/__pycache__/views.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/__pycache__/views.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Profile, Friend, ChatMessage 3 | 4 | # Register your models here. 5 | admin.site.register([Profile, Friend, ChatMessage]) -------------------------------------------------------------------------------- /mychatapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class MychatappConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'mychatapp' 7 | -------------------------------------------------------------------------------- /mychatapp/forms.py: -------------------------------------------------------------------------------- 1 | from socket import fromshare 2 | from django import forms 3 | from django.forms import ModelForm 4 | from .models import ChatMessage 5 | 6 | 7 | class ChatMessageForm(ModelForm): 8 | body = forms.CharField(widget=forms.Textarea(attrs={"class":"forms", "rows":3, "placeholder": "Type message here"})) 9 | class Meta: 10 | model = ChatMessage 11 | fields = ["body",] -------------------------------------------------------------------------------- /mychatapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.4 on 2022-05-30 02:36 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 | initial = True 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Profile', 19 | fields=[ 20 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('name', models.CharField(max_length=100)), 22 | ('pic', models.ImageField(blank=True, null=True, upload_to='img')), 23 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 24 | ], 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /mychatapp/migrations/0002_friend_profile_friends.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.4 on 2022-05-30 02:59 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('mychatapp', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Friend', 16 | fields=[ 17 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('profile', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='mychatapp.profile')), 19 | ], 20 | ), 21 | migrations.AddField( 22 | model_name='profile', 23 | name='friends', 24 | field=models.ManyToManyField(related_name='my_friends', to='mychatapp.friend'), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /mychatapp/migrations/0003_chatmessage.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.4 on 2022-05-30 04:18 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('mychatapp', '0002_friend_profile_friends'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='ChatMessage', 16 | fields=[ 17 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('body', models.TextField()), 19 | ('seen', models.BooleanField(default=False)), 20 | ('msg_receiver', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='msg_receiver', to='mychatapp.profile')), 21 | ('msg_sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='msg_sender', to='mychatapp.profile')), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /mychatapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/migrations/__init__.py -------------------------------------------------------------------------------- /mychatapp/migrations/__pycache__/0001_initial.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/migrations/__pycache__/0001_initial.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/migrations/__pycache__/0002_friend_profile_friends.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/migrations/__pycache__/0002_friend_profile_friends.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/migrations/__pycache__/0003_chatmessage.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/migrations/__pycache__/0003_chatmessage.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/migrations/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/mychatapp/migrations/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /mychatapp/models.py: -------------------------------------------------------------------------------- 1 | import profile 2 | from xmlrpc.client import Boolean 3 | from django.db import models 4 | from django.contrib.auth.models import User 5 | 6 | # Create your models here. 7 | 8 | class Profile(models.Model): 9 | user = models.OneToOneField(User, on_delete=models.CASCADE) 10 | name = models.CharField(max_length=100) 11 | pic = models.ImageField(upload_to="img", blank=True, null=True) 12 | friends = models.ManyToManyField('Friend', related_name = "my_friends") 13 | 14 | def __str__(self): 15 | return self.name 16 | 17 | 18 | class Friend(models.Model): 19 | profile = models.OneToOneField(Profile, on_delete=models.CASCADE) 20 | 21 | def __str__(self): 22 | return self.profile.name 23 | 24 | class ChatMessage(models.Model): 25 | body = models.TextField() 26 | msg_sender = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="msg_sender") 27 | msg_receiver = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="msg_receiver") 28 | seen = models.BooleanField(default=False) 29 | 30 | def __str__(self): 31 | return self.body 32 | 33 | -------------------------------------------------------------------------------- /mychatapp/static/css/style.css: -------------------------------------------------------------------------------- 1 | *{ 2 | padding: 0px; 3 | margin: 0px; 4 | box-sizing: border-box; 5 | font-family: Poppins; 6 | } 7 | 8 | body{ 9 | width: 100%; 10 | height: 100vh; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | background-color: slateblue; 15 | font-family: Poppins; 16 | } 17 | .logo{ 18 | width: 100px; 19 | /* border: 2px solid black; */ 20 | height: 100px; 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | font-size: 20px; 25 | font-weight: bold; 26 | color: slateblue; 27 | line-height: 20px; 28 | } 29 | 30 | .main{ 31 | width: 100%; 32 | height: auto; 33 | /* border: 2px solid black; */ 34 | display: flex; 35 | align-items: center; 36 | justify-content: space-between; 37 | 38 | } 39 | 40 | img{ 41 | object-fit: cover; 42 | height: 100%; 43 | width: 100%; 44 | border-radius: 50%; 45 | } 46 | 47 | .chat-container, .chat-container2{ 48 | width: 350px; 49 | height: 580px; 50 | /* border: 2px solid black; */ 51 | background-color: white; 52 | border-radius: 30px; 53 | padding: 10px 10px 54 | } 55 | .sub-main{ 56 | /* border: 2px solid green; */ 57 | width: 200px; 58 | display: flex; 59 | align-items: flex-end; 60 | justify-content: center; 61 | flex-direction: column; 62 | } 63 | .sub-main p{ 64 | font-size: 18px; 65 | } 66 | .main-user{ 67 | width: 60px; 68 | height: 60px; 69 | /* border: 2px solid black; */ 70 | float: right; 71 | border-radius: 50%; 72 | } 73 | 74 | .header{ 75 | width: 100%; 76 | height: auto; 77 | /* border: 2px solid red; */ 78 | display: flex; 79 | align-items: center; 80 | justify-content: center; 81 | font-size: 20px; 82 | font-weight: bold; 83 | } 84 | 85 | .friends-container{ 86 | width: 100%; 87 | height: 380px; 88 | /* border: 2px solid black; */ 89 | overflow: auto; 90 | } 91 | 92 | .friends{ 93 | width: 100%; 94 | height: 80px; 95 | box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px; 96 | border-radius: 20px; 97 | display: flex; 98 | align-items: center; 99 | justify-content: space-between; 100 | margin-top: 10px; 101 | padding: 0px 10px; 102 | 103 | } 104 | 105 | .pic, .pro-pic{ 106 | width: 50px; 107 | height: 50px; 108 | /* border: 1px solid black; */ 109 | border-radius: 50%; 110 | } 111 | .name{ 112 | flex-grow: 2; 113 | /* border: 2px solid black; */ 114 | display: flex; 115 | align-items: center; 116 | justify-content: center; 117 | flex-direction: column; 118 | } 119 | 120 | .name p{ 121 | font-size: 14px; 122 | } 123 | 124 | .time_new_msg{ 125 | width: auto; 126 | height: 50px; 127 | /* border: 2px solid black; */ 128 | display: flex; 129 | align-items: center; 130 | justify-content: center; 131 | flex-direction: column; 132 | } 133 | 134 | .time_new_msg p{ 135 | font-size: 14px; 136 | } 137 | 138 | .msg{ 139 | width: 40px; 140 | height: 40px; 141 | background-color: slateblue; 142 | border-radius: 50%; 143 | text-align: center; 144 | color: white; 145 | display: flex; 146 | align-items: center; 147 | justify-content: center; 148 | font-size: 18px; 149 | 150 | } 151 | 152 | .footer{ 153 | width: 100%; 154 | height: 40px; 155 | /* border: 1px solid black; */ 156 | display: flex; 157 | align-items: center; 158 | justify-content: space-around; 159 | } 160 | 161 | svg{ 162 | cursor: pointer; 163 | } 164 | 165 | 166 | .identity{ 167 | width: 100%; 168 | height: 80px; 169 | display: flex; 170 | align-items: center; 171 | justify-content: space-around; 172 | /* border: 2px solid black; */ 173 | 174 | } 175 | 176 | 177 | .sub-container{ 178 | 179 | height: 100%; 180 | width: 100%; 181 | /* border: 2px solid blue; */ 182 | padding: 10px; 183 | display: flex; 184 | align-items: center; 185 | justify-content: space-between; 186 | flex-direction: column; 187 | 188 | } 189 | 190 | 191 | .chat-body{ 192 | width: 100%; 193 | height: 280px; 194 | /* border: 2px solid slateblue; */ 195 | overflow: auto; 196 | /* display: flex; 197 | align-items: flex-start; 198 | justify-content: center; */ 199 | } 200 | 201 | #myform{ 202 | width: 100%; 203 | height: auto; 204 | /* border: 2px solid black; */ 205 | /* display: flex; 206 | justify-content: space-between; 207 | align-items: center; */ 208 | flex-grow: 2; 209 | 210 | } 211 | 212 | #input{ 213 | flex-grow: 2; 214 | height: 30px; 215 | /* border: 2px solid slateblue; */ 216 | border-radius: 10px; 217 | padding: 0px 10px; 218 | font-size: 16px; 219 | font-family: sans-serif !important; 220 | } 221 | 222 | .chat-container2{ 223 | display: flex; 224 | align-items: center; 225 | justify-content: space-between; 226 | flex-direction: column; 227 | } 228 | button{ 229 | background: slateblue; 230 | color: white; 231 | width: 100px; 232 | height: 40px; 233 | border: none; 234 | cursor: pointer; 235 | border-radius: 10px; 236 | font-size: 14px; 237 | margin-top: 10px; 238 | 239 | } 240 | 241 | .chat-box-received, .chat-box-sent{ 242 | width: 200px; 243 | height: auto; 244 | font-size: 14px; 245 | background-color: slateblue; 246 | color: white; 247 | margin-left: auto; 248 | margin-bottom: 10px; 249 | display: flex; 250 | align-items: center; 251 | padding:10px 10px; 252 | border-radius: 10px; 253 | } 254 | 255 | .chat-box-sent{ 256 | background-color: rebeccapurple; 257 | color: white; 258 | float: left; 259 | 260 | } -------------------------------------------------------------------------------- /mychatapp/templates/mychatapp/base.html: -------------------------------------------------------------------------------- 1 | 2 | {% load static %} 3 | 4 | 5 | 6 | 7 | 8 | Chatty 9 | 10 | 11 | 12 | 13 | 14 | {% block content %} 15 |

Hello world

16 | {% endblock %} 17 | 18 | 19 | -------------------------------------------------------------------------------- /mychatapp/templates/mychatapp/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "mychatapp/base.html" %} 2 | 3 | {% block content %} 4 | 5 | 15 | 16 |
17 |
18 |
19 | 20 | 28 | 32 | 36 | 37 | 38 |
39 | 40 |

{{friend.profile.name}}

41 | 42 |
43 | profile-picture 44 |
45 | 46 | 47 |
48 | 49 |
50 | 51 | 52 |
53 | 54 | 55 | {% for chat in chats %} 56 | {% if chat.msg_sender == user and chat.msg_receiver == profile %} 57 | 58 |
59 | {{chat}} 60 |
61 | 62 | {% elif chat.msg_sender == profile and chat.msg_receiver == user %} 63 | 64 |
65 | {{chat}} 66 |
67 | 68 | {% endif %} 69 | 70 | 71 | 72 | 73 | 74 | {% endfor %} 75 | 76 | 77 | 78 | 79 | 82 | 83 | 84 |
85 | 86 |
87 | {% csrf_token %} 88 | 89 | {{form.body}} 90 | 91 | 92 |
93 | 94 | 95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 | 232 | 233 | 234 | {% endblock %} 235 | 236 | -------------------------------------------------------------------------------- /mychatapp/templates/mychatapp/index.html: -------------------------------------------------------------------------------- 1 | {% extends "mychatapp/base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 | 10 | 11 |
12 |
13 | profile picture 14 |
15 |

@{{request.user.username}}

16 |
17 |
18 | 19 |
Messages
20 | 21 |
22 | 23 | {% for friend in friends %} 24 | 25 | 26 |
27 |
28 | 29 |
30 |
31 |
{{friend.profile.name}}
32 |

How are you doing today

33 |
34 |
35 | {% comment %}

7:30am

{% endcomment %} 36 | 37 |
0
38 | 39 | 40 |
41 |
42 |
43 | 44 | {% endfor %} 45 | 46 | 47 | 48 |
49 | 50 | 108 |
109 | 110 | 130 | 131 | 132 | 133 | 134 | {% endblock %} 135 | 136 | -------------------------------------------------------------------------------- /mychatapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /mychatapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | urlpatterns = [ 5 | path('', views.index, name= "index"), 6 | path('friend/', views.detail, name="detail"), 7 | path('sent_msg/', views.sentMessages, name = "sent_msg"), 8 | path('rec_msg/', views.receivedMessages, name = "rec_msg"), 9 | path('notification', views.chatNotification, name = "notification"), 10 | 11 | ] 12 | -------------------------------------------------------------------------------- /mychatapp/views.py: -------------------------------------------------------------------------------- 1 | from cgi import print_arguments 2 | from django.shortcuts import render, redirect 3 | from .models import ChatMessage, Profile, Friend 4 | from .forms import ChatMessageForm 5 | from django.http import JsonResponse 6 | import json 7 | 8 | # Create your views here. 9 | def index(request): 10 | user = request.user.profile 11 | friends = user.friends.all() 12 | context = {"user": user, "friends": friends} 13 | return render(request, "mychatapp/index.html", context) 14 | 15 | 16 | def detail(request,pk): 17 | friend = Friend.objects.get(profile_id=pk) 18 | user = request.user.profile 19 | profile = Profile.objects.get(id=friend.profile.id) 20 | chats = ChatMessage.objects.all() 21 | rec_chats = ChatMessage.objects.filter(msg_sender=profile, msg_receiver=user, seen=False) 22 | rec_chats.update(seen=True) 23 | form = ChatMessageForm() 24 | if request.method == "POST": 25 | form = ChatMessageForm(request.POST) 26 | if form.is_valid(): 27 | chat_message = form.save(commit=False) 28 | chat_message.msg_sender = user 29 | chat_message.msg_receiver = profile 30 | chat_message.save() 31 | return redirect("detail", pk=friend.profile.id) 32 | context = {"friend": friend, "form": form, "user":user, 33 | "profile":profile, "chats": chats, "num": rec_chats.count()} 34 | return render(request, "mychatapp/detail.html", context) 35 | 36 | def sentMessages(request, pk): 37 | user = request.user.profile 38 | friend = Friend.objects.get(profile_id=pk) 39 | profile = Profile.objects.get(id=friend.profile.id) 40 | data = json.loads(request.body) 41 | new_chat = data["msg"] 42 | new_chat_message = ChatMessage.objects.create(body=new_chat, msg_sender=user, msg_receiver=profile, seen=False ) 43 | print(new_chat) 44 | return JsonResponse(new_chat_message.body, safe=False) 45 | 46 | def receivedMessages(request, pk): 47 | user = request.user.profile 48 | friend = Friend.objects.get(profile_id=pk) 49 | profile = Profile.objects.get(id=friend.profile.id) 50 | arr = [] 51 | chats = ChatMessage.objects.filter(msg_sender=profile, msg_receiver=user) 52 | for chat in chats: 53 | arr.append(chat.body) 54 | return JsonResponse(arr, safe=False) 55 | 56 | 57 | def chatNotification(request): 58 | user = request.user.profile 59 | friends = user.friends.all() 60 | arr = [] 61 | for friend in friends: 62 | chats = ChatMessage.objects.filter(msg_sender__id=friend.profile.id, msg_receiver=user, seen=False) 63 | arr.append(chats.count()) 64 | return JsonResponse(arr, safe=False) 65 | -------------------------------------------------------------------------------- /static/img/b1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/b1.jpg -------------------------------------------------------------------------------- /static/img/b1_GnbrNBB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/b1_GnbrNBB.jpg -------------------------------------------------------------------------------- /static/img/b2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/b2.jpg -------------------------------------------------------------------------------- /static/img/b3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/b3.jpg -------------------------------------------------------------------------------- /static/img/pic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/pic_1.png -------------------------------------------------------------------------------- /static/img/pic_1_O4zdvrg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/pic_1_O4zdvrg.png -------------------------------------------------------------------------------- /static/img/pic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/pic_2.png -------------------------------------------------------------------------------- /static/img/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/screenshot_1.png -------------------------------------------------------------------------------- /static/img/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/screenshot_2.png -------------------------------------------------------------------------------- /static/img/screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/chatapp/9793ec9a23dfa708defa57d7b76727ea48bd67ad/static/img/screenshot_3.png --------------------------------------------------------------------------------